Skip to content

Commit

Permalink
Fixed issues found using PHPStan
Browse files Browse the repository at this point in the history
  • Loading branch information
juniwalk committed May 2, 2024
1 parent b1bfd84 commit 1422df0
Show file tree
Hide file tree
Showing 12 changed files with 137 additions and 43 deletions.
2 changes: 2 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
},

"require-dev": {
"nette/application": "^3.2",
"nette/security": "^3.2",
"nette/tester": "^2.5",
"phpstan/extension-installer": "^1.0",
"phpstan/phpstan": "^1.0",
Expand Down
24 changes: 16 additions & 8 deletions src/Chronicler.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,15 @@
namespace JuniWalk\Nestor;

use DateTime;
use Doctrine\DBAL\DBALException;
use Doctrine\ORM\EntityManagerInterface as EntityManager;
use Doctrine\ORM\ORMException;
use JuniWalk\Nestor\Entity\Record;
use JuniWalk\Nestor\Entity\RecordRepository;
use JuniWalk\Nestor\Enums\Type;
use JuniWalk\Nestor\Exceptions\RecordExistsException;
use JuniWalk\Nestor\Exceptions\RecordFailedException;
use JuniWalk\Nestor\Exceptions\RecordNotValidException;
use JuniWalk\Utils\Strings;
use Throwable;

final class Chronicler
{
Expand All @@ -41,7 +40,10 @@ public function getEntityName(): string
}


public function log(string $event, string $message, iterable $params = []): void
/**
* @param array<string, mixed> $params
*/
public function log(string $event, string $message, array $params = []): void
{
$record = $this->createRecord($event, $message, $params)
->withType(Type::Log);
Expand All @@ -50,7 +52,10 @@ public function log(string $event, string $message, iterable $params = []): void
}


public function todo(string $event, string $message, iterable $params = []): void
/**
* @param array<string, mixed> $params
*/
public function todo(string $event, string $message, array $params = []): void
{
$record = $this->createRecord($event, $message, $params)
->withType(Type::Todo);
Expand All @@ -63,7 +68,7 @@ public function todo(string $event, string $message, iterable $params = []): voi
* @throws RecordExistsException
* @throws RecordFailedException
*/
public function record(RecordBuilder|Record $record, string $period = null): void
public function record(Record|RecordBuilder $record, ?string $period = null): void
{
if ($record instanceof RecordBuilder) {
$record = $record->create();
Expand All @@ -75,15 +80,15 @@ public function record(RecordBuilder|Record $record, string $period = null): voi

try {
$this->entityManager->persist($record);
$this->entityManager->flush($record);
$this->entityManager->flush($record); // @phpstan-ignore-line

} catch (DBALException|ORMException $e) {
} catch (Throwable $e) {
throw RecordFailedException::fromRecord($record, $e);
}
}


public function isRecorded(Record $record, string $period = null): bool
public function isRecorded(Record $record, ?string $period = null): bool
{
$result = $this->recordRepository->findOneBy(function($qb) use ($record, $period) {
$qb->andWhere('e.hash = :hash')->setParameter('hash', $record->getHash());
Expand All @@ -104,6 +109,9 @@ public function isRecorded(Record $record, string $period = null): bool
}


/**
* @param array<string, mixed> $params
*/
public function createRecord(string $event, string $message, array $params = []): RecordBuilder
{
return (new RecordBuilder($this))
Expand Down
15 changes: 15 additions & 0 deletions src/DI/Config.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php declare(strict_types=1);

/**
* @copyright Martin Procházka (c) 2024
* @license MIT License
*/

namespace JuniWalk\Nestor\DI;

class Config
{
/** @var class-string */
public string $entityName;
public bool $watchActivity = false;
}
12 changes: 8 additions & 4 deletions src/DI/NestorExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

use JuniWalk\Nestor\Chronicler;
use JuniWalk\Nestor\Entity\Subscribers\ActivitySubscriber;
use JuniWalk\Nestor\Exceptions\ConfigNotValidException;
use JuniWalk\Nestor\Exceptions\RecordNotValidException;
use Nette\DI\CompilerExtension;
use Nette\Schema\Expect;
use Nette\Schema\Schema;
Expand All @@ -17,21 +19,23 @@ final class NestorExtension extends CompilerExtension
{
public function getConfigSchema(): Schema
{
return Expect::structure([
'entityName' => Expect::string()->required(),
'watchActivity' => Expect::bool(false),
]);
return Expect::from(new Config);
}


/**
* @throws ConfigNotValidException
* @throws RecordNotValidException
*/
public function loadConfiguration()
{
$builder = $this->getContainerBuilder();
$config = $this->getConfig();

if (!$config instanceof Config) {
throw new ConfigNotValidException('Config must be instance of '.Config::class);
}

$builder->addDefinition($this->prefix('chronicler'))
->setFactory(Chronicler::class, [$config->entityName]);

Expand Down
4 changes: 4 additions & 0 deletions src/Entity/Attributes/ActivityOverride.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ public function __construct(
}


/**
* @param array<string, mixed> $changes
* @return array<string, mixed>
*/
public function process(array $changes, string $fieldName): array
{
switch ($this->strategy) {
Expand Down
27 changes: 22 additions & 5 deletions src/Entity/Record.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
use JuniWalk\Utils\Json;
use Nette\Application\UI\Control;
use Nette\Localization\Translator;
use Stringable;

#[ORM\MappedSuperclass]
abstract class Record
Expand All @@ -41,6 +42,9 @@ abstract class Record
#[ORM\Column(type: 'string')]
protected string $message;

/**
* @var class-string|null $target
*/
#[ORM\Column(type: 'string', nullable: true, options: ['default' => null])]
protected ?string $target = null;

Expand Down Expand Up @@ -123,7 +127,7 @@ public function getMessageFormatted(): string
}


public function getMessageTranslated(Translator $translator): string
public function getMessageTranslated(Translator $translator): Stringable|string
{
return $translator->translate($this->message, Arrays::flatten($this->params));
}
Expand All @@ -143,8 +147,8 @@ public function setTarget(object $target, ?int $targetId = null): void
// $this->params = $target->getRecordParams();
// }

if ($target instanceof Proxy) {
$this->target = get_parent_class($target);
if ($target instanceof Proxy && $targetParent = get_parent_class($target)) {
$this->target = $targetParent;
}
}

Expand All @@ -161,8 +165,12 @@ public function getTargetId(): ?int
}


public function createTarget(EntityManager $entityManager): object
public function createTarget(EntityManager $entityManager): ?object
{
if (!$this->target) {
return null;
}

return $entityManager->getReference($this->target, $this->targetId);
}

Expand Down Expand Up @@ -197,23 +205,32 @@ public function isFinishable(): bool
}


/**
* @param array<string, mixed> $params
*/
public function setParams(array $params): void
{
$this->params = [];
$this->addParams($params);
}


/**
* @param array<string, mixed> $params
*/
public function addParams(array $params): void
{
$params = Arrays::map($params, fn($v) => Format::scalarize($v));
$params = array_filter($params, fn($v) => !is_null($v));
$params = array_filter((array) $params, fn($v) => !is_null($v));
$params = array_merge($params, $this->params ?? []);

$this->params = $params;
}


/**
* @return array<string, mixed>
*/
public function getParamsUnified(): array
{
return Arrays::flatten($this->getParams());
Expand Down
50 changes: 32 additions & 18 deletions src/Entity/Subscribers/ActivitySubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@
namespace JuniWalk\Nestor\Entity\Subscribers;

use Closure;
use Doctrine\Common\Collections\Collection;
use Doctrine\Common\EventArgs;
use Doctrine\Common\EventSubscriber;
use Doctrine\ORM\EntityManagerInterface as EntityManager;
use Doctrine\ORM\Events;
use Doctrine\ORM\PersistentCollection;
use Doctrine\ORM\Proxy\Proxy;
use JuniWalk\Nestor\Chronicler;
use JuniWalk\Nestor\Entity\Attributes\ActivityOverride;
Expand All @@ -21,17 +21,20 @@
use JuniWalk\Nestor\Enums\Action;
use JuniWalk\Nestor\Interfaces\ParamsProvider;
use JuniWalk\Nestor\Interfaces\TargetProvider;
use JuniWalk\ORM\Entity\Interfaces\Identified;
use JuniWalk\Utils\Format;
use Nette\Security\IIdentity as Identity;
use Nette\Security\User as LoggedInUser;
use ReflectionClass;

class ActivitySubscriber implements EventSubscriber
{
/** @var array<string, bool> */
private static array $ignored = [];

private bool $isFlushing = false;
/** @var array<string, array{object, Action, array<string, mixed>, int|null}> */
private array $items = [];
private bool $isFlushing = false;
private ?Identity $user;

final public function __construct(
Expand Down Expand Up @@ -113,8 +116,8 @@ public function postFlush(EventArgs $event): void
$record->setParams($params);
$record->setFinished(true);

if ($target instanceof TargetProvider) {
$record->setTarget($target->getRecordTarget());
if ($target instanceof TargetProvider && $target = $target->getRecordTarget()) {
$record->setTarget($target);
}

$this->entityManager->persist($record);
Expand All @@ -131,13 +134,13 @@ private function process(Action $action, object $target): void
$changes = $this->findChanges($action, $target);
$hash = spl_object_hash($target);

if ($target instanceof Collection) {
$target = $target->getOwner();
if ($target instanceof PersistentCollection) {
$target = $target->getOwner() ?? $target;
}

$reflection = new ReflectionClass($target);
$class = new ReflectionClass($target);

if ($reflection->getAttributes(TargetIgnore::class)) {
if ($class->getAttributes(TargetIgnore::class)) {
return;
}

Expand All @@ -149,24 +152,32 @@ private function process(Action $action, object $target): void
$target,
$action,
$changes,
$target->getId(),
null,
];

// TODO: Use new Identified interface from juniwalk/orm:^0.10
if (method_exists($target, 'getId')/* || $target instanceof Identified */) {
$this->items[$hash][3] = $target->getId();
}
}


/**
* @return array<string, mixed>
*/
private function findChanges(Action $action, object $target): array
{
$uow = $this->entityManager->getUnitOfWork();
$changes = [];

if ($target instanceof Collection) {
if ($target instanceof PersistentCollection) {
$fieldName = $target->getMapping()['fieldName'];
$changes[$fieldName] = [
$target->getSnapshot(),
$target->getValues(),
];

$target = $target->getOwner();
$target = $target->getOwner() ?? $target;
}

$changes = array_merge($changes, $uow->getEntityChangeSet($target));
Expand Down Expand Up @@ -198,21 +209,24 @@ private function findChanges(Action $action, object $target): array
}


/**
* @return array<string, ActivityOverride>
*/
private function findOverrides(object $target): array
{
$reflection = new ReflectionClass($target);
$overrides = [];
$class = new ReflectionClass($target);
$result = [];

if ($target instanceof Proxy) {
$reflection = $reflection->getParentClass();
if ($target instanceof Proxy && $classParent = $class->getParentClass()) {
$class = $classParent;
}

foreach ($reflection->getProperties() as $property) {
foreach ($class->getProperties() as $property) {
foreach ($property->getAttributes(ActivityOverride::class) as $attribute) {
$overrides[$property->getName()] = $attribute->newInstance();
$result[$property->getName()] = $attribute->newInstance();
}
}

return $overrides;
return $result;
}
}
5 changes: 3 additions & 2 deletions src/Enums/Action.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@
use JuniWalk\Utils\Enums\LabeledEnum;
use JuniWalk\Utils\Enums\Traits\Labeled;

enum Action: string
enum Action: string implements LabeledEnum
{
use Labeled;

case Create = 'create';
case Update = 'update';
case Delete = 'delete';
Expand All @@ -34,7 +36,6 @@ public function color(): Color
self::Create => Color::Success,
self::Update => Color::Primary,
self::Delete => Color::Danger,
default => Color::Secondary,
};
}
}
Loading

0 comments on commit 1422df0

Please sign in to comment.