From 0825ee724b4d48830286042f65d7f02b5cc49e64 Mon Sep 17 00:00:00 2001 From: Regis Grison Date: Mon, 4 Nov 2024 18:42:34 +0100 Subject: [PATCH 01/18] update composer.json for symfony 7 --- composer.json | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/composer.json b/composer.json index 98497c4..e5da50e 100644 --- a/composer.json +++ b/composer.json @@ -28,22 +28,22 @@ "php": "^8.0", "doctrine/doctrine-bundle": "^2.0", "doctrine/persistence": "^1.3 || ^2.1", - "knplabs/knp-paginator-bundle": "^4.4 || ^5.1", - "symfony/asset": "^4.4 || ^5.1 || ^6.0", - "symfony/config": "^4.4 || ^5.1 || ^6.0", - "symfony/console": "^4.4 || ^5.1 || ^6.0", - "symfony/dependency-injection": "^4.1 || ^5.0 || ^6.0", - "symfony/event-dispatcher": "^4.4 || ^5.1 || ^6.0", - "symfony/form": "^4.4 || ^5.1 || ^6.0", - "symfony/framework-bundle": "^4.4 || ^5.1 || ^6.0", - "symfony/http-foundation": "^4.4 || ^5.1 || ^6.0", - "symfony/http-kernel": "^4.4 || ^5.1 || ^6.0", - "symfony/options-resolver": "^4.4 || ^5.1 || ^6.0", - "symfony/security-bundle": "^4.4 || ^5.1 || ^6.0", - "symfony/translation": "^4.4 || ^5.1 || ^6.0", - "symfony/twig-bundle": "^4.4 || ^5.1 || ^6.0", - "symfony/validator": "^4.4 || ^5.1 || ^6.0", - "symfony/yaml": "^4.4 || ^5.1 || ^6.0", + "knplabs/knp-paginator-bundle": "^6.6", + "symfony/asset": "^7.0", + "symfony/config": "^7.0", + "symfony/console": "^7.0", + "symfony/dependency-injection": "^7.0", + "symfony/event-dispatcher": "^7.0", + "symfony/form": "^7.0", + "symfony/framework-bundle": "^7.0", + "symfony/http-foundation": "^7.0", + "symfony/http-kernel": "^7.0", + "symfony/options-resolver": "^7.0", + "symfony/security-bundle": "^7.0", + "symfony/translation": "^7.0", + "symfony/twig-bundle": "^7.0", + "symfony/validator": "^7.0", + "symfony/yaml": "^7.0", "twig/twig": "^2.9 || ^3.0" }, "require-dev": { @@ -51,7 +51,7 @@ "friendsofphp/php-cs-fixer": "^3.0", "phpstan/phpstan": "^1.3", "phpunit/phpunit": "^9.5", - "symfony/phpunit-bridge": "^4.4 || ^5.1 || ^6.0", + "symfony/phpunit-bridge": "^7.0", "symfony/test-pack": "^1.0" }, "suggest": { @@ -81,7 +81,7 @@ }, "extra": { "branch-alias": { - "dev-master": "4.x-dev" + "dev-master": "5.x-dev" } } } From 1934d94e95685e30ad461a7e94d355fac0cea371 Mon Sep 17 00:00:00 2001 From: Regis Grison Date: Mon, 4 Nov 2024 18:46:17 +0100 Subject: [PATCH 02/18] update doctrine-bundle --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index e5da50e..baab513 100644 --- a/composer.json +++ b/composer.json @@ -26,7 +26,7 @@ ], "require": { "php": "^8.0", - "doctrine/doctrine-bundle": "^2.0", + "doctrine/doctrine-bundle": ">=2.11", "doctrine/persistence": "^1.3 || ^2.1", "knplabs/knp-paginator-bundle": "^6.6", "symfony/asset": "^7.0", From edd1c82316efdea3f0cb485b54e0e22e2b7d1b4c Mon Sep 17 00:00:00 2001 From: Regis Grison Date: Tue, 5 Nov 2024 07:08:08 +0100 Subject: [PATCH 03/18] run rector once --- Command/AutoClosingCommand.php | 17 +-- Command/TicketManagerCommand.php | 15 +- Controller/TicketAttachmentController.php | 20 +-- Controller/TicketController.php | 27 +--- Event/TicketEvent.php | 5 +- Form/DataTransformer/StatusTransformer.php | 5 +- Form/Type/TicketMessageType.php | 11 +- Form/Type/TicketType.php | 5 +- Maker/AbstractMaker.php | 11 +- Maker/Util/ClassSourceManipulator.php | 158 ++++++--------------- Manager/TicketManager.php | 32 ++--- Manager/UserManager.php | 19 +-- Resources/config/controllers.php | 2 +- TwigExtension/TicketFeatureExtension.php | 7 +- TwigExtension/TicketGlobalExtension.php | 5 +- composer.json | 6 +- 16 files changed, 81 insertions(+), 264 deletions(-) diff --git a/Command/AutoClosingCommand.php b/Command/AutoClosingCommand.php index 3134e76..4780f30 100644 --- a/Command/AutoClosingCommand.php +++ b/Command/AutoClosingCommand.php @@ -29,16 +29,6 @@ final class AutoClosingCommand extends Command { protected static $defaultName = 'ticket:autoclosing'; - /** - * @var TicketManagerInterface - */ - private $ticketManager; - - /** - * @var UserManagerInterface - */ - private $userManager; - /** * @var string */ @@ -54,15 +44,12 @@ final class AutoClosingCommand extends Command */ private $translator; - public function __construct(TicketManagerInterface $ticketManager, UserManagerInterface $userManager, LocaleAwareInterface $translator, ParameterBagInterface $parameterBag) + public function __construct(private readonly TicketManagerInterface $ticketManager, private readonly UserManagerInterface $userManager, LocaleAwareInterface $translator, ParameterBagInterface $parameterBag) { parent::__construct(); - $this->ticketManager = $ticketManager; - $this->userManager = $userManager; - if (!is_a($translator, TranslatorInterface::class)) { - throw new \InvalidArgumentException(\get_class($translator).' Must implement TranslatorInterface and LocaleAwareInterface'); + throw new \InvalidArgumentException($translator::class.' Must implement TranslatorInterface and LocaleAwareInterface'); } $this->translator = $translator; diff --git a/Command/TicketManagerCommand.php b/Command/TicketManagerCommand.php index 8004907..76ce3ca 100644 --- a/Command/TicketManagerCommand.php +++ b/Command/TicketManagerCommand.php @@ -26,22 +26,9 @@ final class TicketManagerCommand extends Command { protected static $defaultName = 'ticket:create'; - /** - * @var TicketManagerInterface - */ - private $ticketManager; - - /** - * @var UserManagerInterface - */ - private $userManager; - - public function __construct(TicketManagerInterface $ticketManager, UserManagerInterface $userManager) + public function __construct(private readonly TicketManagerInterface $ticketManager, private readonly UserManagerInterface $userManager) { parent::__construct(); - - $this->ticketManager = $ticketManager; - $this->userManager = $userManager; } /** diff --git a/Controller/TicketAttachmentController.php b/Controller/TicketAttachmentController.php index 39eda55..a03eece 100644 --- a/Controller/TicketAttachmentController.php +++ b/Controller/TicketAttachmentController.php @@ -29,24 +29,8 @@ */ final class TicketAttachmentController extends AbstractController { - private DownloadHandler $downloadHandler; - - private TicketManager $ticketManager; - - private TranslatorInterface $translator; - - private UserManagerInterface $userManager; - - public function __construct( - DownloadHandler $downloadHandler, - TicketManager $ticketManager, - TranslatorInterface $translator, - UserManagerInterface $userManager - ) { - $this->downloadHandler = $downloadHandler; - $this->ticketManager = $ticketManager; - $this->translator = $translator; - $this->userManager = $userManager; + public function __construct(private readonly DownloadHandler $downloadHandler, private readonly TicketManager $ticketManager, private readonly TranslatorInterface $translator, private readonly UserManagerInterface $userManager) + { } /** diff --git a/Controller/TicketController.php b/Controller/TicketController.php index 69aade7..282e1d7 100644 --- a/Controller/TicketController.php +++ b/Controller/TicketController.php @@ -37,31 +37,16 @@ */ final class TicketController extends AbstractController { - private EventDispatcherInterface $dispatcher; - - private PaginatorInterface $pagination; - - private TicketManager $ticketManager; - - private TranslatorInterface $translator; - - private UserManagerInterface $userManager; - private array $templates = []; public function __construct( - EventDispatcherInterface $dispatcher, - PaginatorInterface $pagination, + private readonly EventDispatcherInterface $dispatcher, + private readonly PaginatorInterface $pagination, ParameterBagInterface $bag, - TicketManager $ticketManager, - TranslatorInterface $translator, - UserManagerInterface $userManager + private readonly TicketManager $ticketManager, + private readonly TranslatorInterface $translator, + private readonly UserManagerInterface $userManager ) { - $this->dispatcher = $dispatcher; - $this->pagination = $pagination; - $this->ticketManager = $ticketManager; - $this->translator = $translator; - $this->userManager = $userManager; $this->templates = $bag->get('hackzilla_ticket.templates'); } @@ -285,7 +270,7 @@ private function dispatchTicketEvent(string $ticketEvent, TicketInterface $ticke * * @param mixed $id The entity id */ - private function createDeleteForm($id): FormInterface + private function createDeleteForm(mixed $id): FormInterface { return $this->createFormBuilder(['id' => $id]) ->add('id', HiddenType::class) diff --git a/Event/TicketEvent.php b/Event/TicketEvent.php index 5ef1848..0edaf47 100644 --- a/Event/TicketEvent.php +++ b/Event/TicketEvent.php @@ -18,11 +18,8 @@ final class TicketEvent extends Event { - protected $ticket; - - public function __construct(TicketInterface $ticket) + public function __construct(protected TicketInterface $ticket) { - $this->ticket = $ticket; } public function getTicket(): TicketInterface diff --git a/Form/DataTransformer/StatusTransformer.php b/Form/DataTransformer/StatusTransformer.php index 66d80ea..1022cea 100644 --- a/Form/DataTransformer/StatusTransformer.php +++ b/Form/DataTransformer/StatusTransformer.php @@ -19,11 +19,8 @@ final class StatusTransformer implements DataTransformerInterface { - private TicketInterface $ticket; - - public function __construct(TicketInterface $ticket) + public function __construct(private readonly TicketInterface $ticket) { - $this->ticket = $ticket; } /** diff --git a/Form/Type/TicketMessageType.php b/Form/Type/TicketMessageType.php index ed16e3b..df24dc6 100644 --- a/Form/Type/TicketMessageType.php +++ b/Form/Type/TicketMessageType.php @@ -27,17 +27,8 @@ final class TicketMessageType extends AbstractType { - protected $userManager; - - protected $features; - - protected $messageClass; - - public function __construct(UserManagerInterface $userManager, TicketFeatures $features, string $messageClass) + public function __construct(protected UserManagerInterface $userManager, protected TicketFeatures $features, protected string $messageClass) { - $this->userManager = $userManager; - $this->features = $features; - $this->messageClass = $messageClass; } public function buildForm(FormBuilderInterface $builder, array $options) diff --git a/Form/Type/TicketType.php b/Form/Type/TicketType.php index 7a977b9..d8fd6f7 100644 --- a/Form/Type/TicketType.php +++ b/Form/Type/TicketType.php @@ -21,11 +21,8 @@ final class TicketType extends AbstractType { - protected $ticketClass; - - public function __construct(string $ticketClass) + public function __construct(protected string $ticketClass) { - $this->ticketClass = $ticketClass; } public function buildForm(FormBuilderInterface $builder, array $options) diff --git a/Maker/AbstractMaker.php b/Maker/AbstractMaker.php index b7e8354..27b991f 100644 --- a/Maker/AbstractMaker.php +++ b/Maker/AbstractMaker.php @@ -37,17 +37,12 @@ */ abstract class AbstractMaker extends \Symfony\Bundle\MakerBundle\Maker\AbstractMaker { - private $fileManager; - private $doctrineHelper; private $userClass; private $ticketClass; private $messageClass; - public function __construct(FileManager $fileManager, DoctrineHelper $doctrineHelper, ParameterBagInterface $bag) + public function __construct(private readonly FileManager $fileManager, private readonly DoctrineHelper $doctrineHelper, ParameterBagInterface $bag) { - $this->fileManager = $fileManager; - $this->doctrineHelper = $doctrineHelper; - $this->userClass = $bag->get('hackzilla_ticket.model.user.class'); $this->ticketClass = $bag->get('hackzilla_ticket.model.ticket.class'); $this->messageClass = $bag->get('hackzilla_ticket.model.message.class'); @@ -264,9 +259,7 @@ private function getPropertyNames(string $class): array $reflClass = new \ReflectionClass($class); - return array_map(static function (\ReflectionProperty $prop) { - return $prop->getName(); - }, $reflClass->getProperties()); + return array_map(static fn(\ReflectionProperty $prop) => $prop->getName(), $reflClass->getProperties()); } private function doesEntityUseAnnotationMapping(string $className): bool diff --git a/Maker/Util/ClassSourceManipulator.php b/Maker/Util/ClassSourceManipulator.php index 455a6ae..23cca04 100644 --- a/Maker/Util/ClassSourceManipulator.php +++ b/Maker/Util/ClassSourceManipulator.php @@ -48,10 +48,6 @@ final class ClassSourceManipulator private const CONTEXT_OUTSIDE_CLASS = 'outside_class'; private const CONTEXT_CLASS = 'class'; private const CONTEXT_CLASS_METHOD = 'class_method'; - - private $overwrite; - private $useAnnotations; - private $useAttributesForDoctrineMapping; private $parser; private $lexer; private $printer; @@ -65,11 +61,8 @@ final class ClassSourceManipulator private $pendingComments = []; - public function __construct(string $sourceCode, bool $overwrite = false, bool $useAnnotations = true, bool $useAttributesForDoctrineMapping = false) + public function __construct(string $sourceCode, private readonly bool $overwrite = false, private readonly bool $useAnnotations = true, private readonly bool $useAttributesForDoctrineMapping = false) { - $this->overwrite = $overwrite; - $this->useAnnotations = $useAnnotations; - $this->useAttributesForDoctrineMapping = $useAttributesForDoctrineMapping; $this->lexer = new Lexer\Emulative([ 'usedAttributes' => [ 'comments', @@ -101,7 +94,7 @@ public function addCreatedToContructor() // look for "$this->propertyName = " $constructorString = $this->printer->prettyPrint([$this->getConstructorNode()]); - if (false !== strpos($constructorString, sprintf('$this->%s = ', 'createdAt'))) { + if (str_contains($constructorString, sprintf('$this->%s = ', 'createdAt'))) { $addCreatedAt = false; } } @@ -179,9 +172,7 @@ public function addTrait(string $trait): void $importedClassName = $this->addUseStatementIfNecessary($trait); /** @var Node\Stmt\TraitUse[] $traitNodes */ - $traitNodes = $this->findAllNodes(static function ($node) { - return $node instanceof Node\Stmt\TraitUse; - }); + $traitNodes = $this->findAllNodes(static fn($node) => $node instanceof Node\Stmt\TraitUse); foreach ($traitNodes as $node) { if ($node->traits[0]->toString() === $importedClassName) { @@ -429,14 +420,10 @@ private function buildAnnotationLine(string $annotationClass, array $options): s $formattedOptions = array_map(function ($option, $value) { if (\is_array($value)) { if (!isset($value[0])) { - return sprintf('%s={%s}', $option, implode(', ', array_map(function ($val, $key) { - return sprintf('"%s" = %s', $key, $this->quoteAnnotationValue($val)); - }, $value, array_keys($value)))); + return sprintf('%s={%s}', $option, implode(', ', array_map(fn($val, $key) => sprintf('"%s" = %s', $key, $this->quoteAnnotationValue($val)), $value, array_keys($value)))); } - return sprintf('%s={%s}', $option, implode(', ', array_map(function ($val) { - return $this->quoteAnnotationValue($val); - }, $value))); + return sprintf('%s={%s}', $option, implode(', ', array_map(fn($val) => $this->quoteAnnotationValue($val), $value))); } return sprintf('%s=%s', $option, $this->quoteAnnotationValue($value)); @@ -565,7 +552,7 @@ private function addCollectionRelation(BaseCollectionRelation $relation): void // look for "$this->propertyName = " $constructorString = $this->printer->prettyPrint([$this->getConstructorNode()]); - if (false !== strpos($constructorString, sprintf('$this->%s = ', $relation->getPropertyName()))) { + if (str_contains($constructorString, sprintf('$this->%s = ', $relation->getPropertyName()))) { $addArrayCollection = false; } } @@ -596,7 +583,7 @@ private function addStatementToConstructor(Node\Stmt $stmt): void new Node\Expr\StaticCall(new Node\Name('parent'), new Node\Identifier('__construct')) ); } - } catch (\ReflectionException $e) { + } catch (\ReflectionException) { } $this->addNodeAfterProperties($constructorNode); @@ -631,14 +618,14 @@ private function updateSourceCodeFromNewStmts(): void // replace the 3 "fake" items that may be in the code (allowing for different indentation) $newCode = preg_replace('/(\ |\t)*private\ \$__EXTRA__LINE;/', '', $newCode); - $newCode = preg_replace('/use __EXTRA__LINE;/', '', $newCode); - $newCode = preg_replace('/(\ |\t)*\$__EXTRA__LINE;/', '', $newCode); + $newCode = preg_replace('/use __EXTRA__LINE;/', '', (string) $newCode); + $newCode = preg_replace('/(\ |\t)*\$__EXTRA__LINE;/', '', (string) $newCode); // process comment lines foreach ($this->pendingComments as $i => $comment) { // sanity check $placeholder = sprintf('$__COMMENT__VAR_%d;', $i); - if (false === strpos($newCode, $placeholder)) { + if (!str_contains((string) $newCode, $placeholder)) { // this can happen if a comment is createSingleLineCommentNode() // is called, but then that generated code is ultimately not added continue; @@ -667,9 +654,7 @@ private function setSourceCode(string $sourceCode): void private function getClassNode(): Node\Stmt\Class_ { - $node = $this->findFirstNode(static function ($node) { - return $node instanceof Node\Stmt\Class_; - }); + $node = $this->findFirstNode(static fn($node) => $node instanceof Node\Stmt\Class_); if (!$node) { throw new \Exception('Could not find class node'); @@ -681,9 +666,7 @@ private function getClassNode(): Node\Stmt\Class_ private function getNamespaceNode(): Node\Stmt\Namespace_ { - $node = $this->findFirstNode(static function ($node) { - return $node instanceof Node\Stmt\Namespace_; - }); + $node = $this->findFirstNode(static fn($node) => $node instanceof Node\Stmt\Namespace_); if (!$node) { throw new \Exception('Could not find namespace node'); @@ -731,21 +714,15 @@ private function findAllNodes(callable $filterCallback): array private function createBlankLineNode(string $context) { - switch ($context) { - case self::CONTEXT_OUTSIDE_CLASS: - return (new Builder\Use_('__EXTRA__LINE', Node\Stmt\Use_::TYPE_NORMAL)) - ->getNode() - ; - case self::CONTEXT_CLASS: - return (new Builder\Property('__EXTRA__LINE')) - ->makePrivate() - ->getNode() - ; - case self::CONTEXT_CLASS_METHOD: - return new Node\Expr\Variable('__EXTRA__LINE'); - default: - throw new \Exception('Unknown context: '.$context); - } + return match ($context) { + self::CONTEXT_OUTSIDE_CLASS => (new Builder\Use_('__EXTRA__LINE', Node\Stmt\Use_::TYPE_NORMAL)) + ->getNode(), + self::CONTEXT_CLASS => (new Builder\Property('__EXTRA__LINE')) + ->makePrivate() + ->getNode(), + self::CONTEXT_CLASS_METHOD => new Node\Expr\Variable('__EXTRA__LINE'), + default => throw new \Exception('Unknown context: '.$context), + }; } private function createSingleLineCommentNode(string $comment, string $context): Node\Stmt @@ -828,56 +805,22 @@ private function addMethod(Node\Stmt\ClassMethod $methodNode): void private function getEntityTypeHint($doctrineType): ?string { - switch ($doctrineType) { - case 'string': - case 'text': - case 'guid': - case 'bigint': - case 'decimal': - return 'string'; - - case 'array': - case 'simple_array': - case 'json': - case 'json_array': - return 'array'; - - case 'boolean': - return 'bool'; - - case 'integer': - case 'smallint': - return 'int'; - - case 'float': - return 'float'; - - case 'datetime': - case 'datetimetz': - case 'date': - case 'time': - return '\\'.\DateTimeInterface::class; - - case 'datetime_immutable': - case 'datetimetz_immutable': - case 'date_immutable': - case 'time_immutable': - return '\\'.\DateTimeImmutable::class; - - case 'dateinterval': - return '\\'.\DateInterval::class; - - case 'object': - case 'binary': - case 'blob': - default: - return null; - } + return match ($doctrineType) { + 'string', 'text', 'guid', 'bigint', 'decimal' => 'string', + 'array', 'simple_array', 'json', 'json_array' => 'array', + 'boolean' => 'bool', + 'integer', 'smallint' => 'int', + 'float' => 'float', + 'datetime', 'datetimetz', 'date', 'time' => '\\'.\DateTimeInterface::class, + 'datetime_immutable', 'datetimetz_immutable', 'date_immutable', 'time_immutable' => '\\'.\DateTimeImmutable::class, + 'dateinterval' => '\\'.\DateInterval::class, + default => null, + }; } private function isInSameNamespace($class): bool { - $namespace = substr($class, 0, strrpos($class, '\\')); + $namespace = substr((string) $class, 0, strrpos((string) $class, '\\')); return $this->getNamespaceNode()->name->toCodeString() === $namespace; } @@ -897,22 +840,16 @@ private function addNodeAfterProperties(Node $newNode): void $classNode = $this->getClassNode(); // try to add after last property - $targetNode = $this->findLastNode(static function ($node) { - return $node instanceof Node\Stmt\Property; - }, [$classNode]); + $targetNode = $this->findLastNode(static fn($node) => $node instanceof Node\Stmt\Property, [$classNode]); // otherwise, try to add after the last constant if (!$targetNode) { - $targetNode = $this->findLastNode(static function ($node) { - return $node instanceof Node\Stmt\ClassConst; - }, [$classNode]); + $targetNode = $this->findLastNode(static fn($node) => $node instanceof Node\Stmt\ClassConst, [$classNode]); } // otherwise, try to add after the last trait if (!$targetNode) { - $targetNode = $this->findLastNode(static function ($node) { - return $node instanceof Node\Stmt\TraitUse; - }, [$classNode]); + $targetNode = $this->findLastNode(static fn($node) => $node instanceof Node\Stmt\TraitUse, [$classNode]); } // add the new property after this node @@ -985,11 +922,10 @@ private function addMethodParams(Builder\Method $methodBuilder, array $params): * builds a PHPParser Expr Node based on the value given in $value * throws an Exception when the given $value is not resolvable by this method. * - * @param mixed $value * * @throws \Exception */ - private function buildNodeExprByValue($value): Node\Expr + private function buildNodeExprByValue(mixed $value): Node\Expr { switch (\gettype($value)) { case 'string': @@ -1006,12 +942,10 @@ private function buildNodeExprByValue($value): Node\Expr break; case 'array': $context = $this; - $arrayItems = array_map(static function ($key, $value) use ($context) { - return new Node\Expr\ArrayItem( - $context->buildNodeExprByValue($value), - !\is_int($key) ? $context->buildNodeExprByValue($key) : null - ); - }, array_keys($value), array_values($value)); + $arrayItems = array_map(static fn($key, $value) => new Node\Expr\ArrayItem( + $context->buildNodeExprByValue($value), + !\is_int($key) ? $context->buildNodeExprByValue($key) : null + ), array_keys($value), array_values($value)); $nodeValue = new Node\Expr\Array_($arrayItems, ['kind' => Node\Expr\Array_::KIND_SHORT]); break; default: @@ -1044,9 +978,7 @@ private function buildAttributeNode(string $attributeClass, array $options): Nod $options = $this->sortOptionsByClassConstructorParameters($options, $attributeClass); $context = $this; - $nodeArguments = array_map(static function ($option, $value) use ($context) { - return new Node\Arg($context->buildNodeExprByValue($value), false, false, [], new Node\Identifier($option)); - }, array_keys($options), array_values($options)); + $nodeArguments = array_map(static fn($option, $value) => new Node\Arg($context->buildNodeExprByValue($value), false, false, [], new Node\Identifier($option)), array_keys($options), array_values($options)); return new Node\Attribute( new Node\Name($attributeClass), @@ -1062,13 +994,11 @@ private function buildAttributeNode(string $attributeClass, array $options): Nod */ private function sortOptionsByClassConstructorParameters(array $options, string $classString): array { - if ('ORM\\' === substr($classString, 0, 4)) { + if (str_starts_with($classString, 'ORM\\')) { $classString = sprintf('Doctrine\\ORM\\Mapping\\%s', substr($classString, 4)); } - $constructorParameterNames = array_map(static function (\ReflectionParameter $reflectionParameter) { - return $reflectionParameter->getName(); - }, (new \ReflectionClass($classString))->getConstructor()->getParameters()); + $constructorParameterNames = array_map(static fn(\ReflectionParameter $reflectionParameter) => $reflectionParameter->getName(), (new \ReflectionClass($classString))->getConstructor()->getParameters()); $sorted = []; foreach ($constructorParameterNames as $name) { diff --git a/Manager/TicketManager.php b/Manager/TicketManager.php index 895f339..774d9c7 100644 --- a/Manager/TicketManager.php +++ b/Manager/TicketManager.php @@ -35,17 +35,11 @@ final class TicketManager implements TicketManagerInterface private $messageRepository; - private $ticketClass; - - private $ticketMessageClass; - /** * TicketManager constructor. */ - public function __construct(string $ticketClass, string $ticketMessageClass) + public function __construct(private string $ticketClass, private string $ticketMessageClass) { - $this->ticketClass = $ticketClass; - $this->ticketMessageClass = $ticketMessageClass; } public function setLogger(LoggerInterface $logger): self @@ -202,22 +196,14 @@ public function getTicketListQuery($ticketStatus, $ticketPriority = null): Query ->orderBy('t.lastMessage', 'DESC') ; - switch ($ticketStatus) { - case TicketMessageInterface::STATUS_CLOSED: - $query - ->andWhere('t.status = :status') - ->setParameter('status', TicketMessageInterface::STATUS_CLOSED) - ; - - break; - - case TicketMessageInterface::STATUS_OPEN: - default: - $query - ->andWhere('t.status != :status') - ->setParameter('status', TicketMessageInterface::STATUS_CLOSED) - ; - } + match ($ticketStatus) { + TicketMessageInterface::STATUS_CLOSED => $query + ->andWhere('t.status = :status') + ->setParameter('status', TicketMessageInterface::STATUS_CLOSED), + default => $query + ->andWhere('t.status != :status') + ->setParameter('status', TicketMessageInterface::STATUS_CLOSED), + }; if ($ticketPriority) { $query diff --git a/Manager/UserManager.php b/Manager/UserManager.php index e76f88f..64381f5 100644 --- a/Manager/UserManager.php +++ b/Manager/UserManager.php @@ -23,34 +23,21 @@ final class UserManager implements UserManagerInterface { use PermissionManagerTrait; - /** - * @var TokenStorageInterface - */ - private $tokenStorage; - - /** - * @var AuthorizationCheckerInterface - */ - private $authorizationChecker; - /** * @var ObjectRepository */ private $userRepository; public function __construct( - TokenStorageInterface $tokenStorage, + private TokenStorageInterface $tokenStorage, ObjectRepository $userRepository, - AuthorizationCheckerInterface $authorizationChecker, + private AuthorizationCheckerInterface $authorizationChecker, ) { - $this->tokenStorage = $tokenStorage; - if (!is_subclass_of($userRepository->getClassName(), UserInterface::class)) { throw new \InvalidArgumentException(sprintf('Argument 2 passed to "%s()" MUST be an object repository for a class implementing "%s".', __METHOD__, UserInterface::class)); } $this->userRepository = $userRepository; - $this->authorizationChecker = $authorizationChecker; } public function getCurrentUser(): ?UserInterface @@ -95,7 +82,7 @@ public function hasPermission(?UserInterface $user, TicketInterface $ticket): bo { try { $this->getPermissionManager()->hasPermission($user, $ticket); - } catch (\Exception $exception) { + } catch (\Exception) { return false; } diff --git a/Resources/config/controllers.php b/Resources/config/controllers.php index 771fdd2..b42bbf0 100644 --- a/Resources/config/controllers.php +++ b/Resources/config/controllers.php @@ -22,7 +22,7 @@ // Use "service" function for creating references to services when dropping support for Symfony 4.4 // Use "param" function for creating references to parameters when dropping support for Symfony 5.1 - if (class_exists('\\Vich\\UploaderBundle\\Handler\\DownloadHandler')) { + if (class_exists(\Vich\UploaderBundle\Handler\DownloadHandler::class)) { $container->services() ->set(TicketAttachmentController::class) ->args([ diff --git a/TwigExtension/TicketFeatureExtension.php b/TwigExtension/TicketFeatureExtension.php index b78475a..a8574fc 100644 --- a/TwigExtension/TicketFeatureExtension.php +++ b/TwigExtension/TicketFeatureExtension.php @@ -19,17 +19,14 @@ final class TicketFeatureExtension extends AbstractExtension { - private $ticketFeatures; - - public function __construct(TicketFeatures $ticketFeatures) + public function __construct(private readonly TicketFeatures $ticketFeatures) { - $this->ticketFeatures = $ticketFeatures; } public function getFunctions(): array { return [ - new TwigFunction('hasTicketFeature', [$this, 'hasFeature']), + new TwigFunction('hasTicketFeature', $this->hasFeature(...)), ]; } diff --git a/TwigExtension/TicketGlobalExtension.php b/TwigExtension/TicketGlobalExtension.php index b8b5a37..9ca5e7d 100644 --- a/TwigExtension/TicketGlobalExtension.php +++ b/TwigExtension/TicketGlobalExtension.php @@ -18,11 +18,8 @@ final class TicketGlobalExtension extends AbstractExtension implements GlobalsInterface { - protected $templates = []; - - public function __construct(array $templates) + public function __construct(protected array $templates) { - $this->templates = $templates; } public function getGlobals(): array diff --git a/composer.json b/composer.json index baab513..1abaa7d 100644 --- a/composer.json +++ b/composer.json @@ -25,9 +25,10 @@ } ], "require": { - "php": "^8.0", + "php": "^8.1", "doctrine/doctrine-bundle": ">=2.11", - "doctrine/persistence": "^1.3 || ^2.1", + "doctrine/orm": "^3.3", + "doctrine/persistence": "^3.1", "knplabs/knp-paginator-bundle": "^6.6", "symfony/asset": "^7.0", "symfony/config": "^7.0", @@ -51,6 +52,7 @@ "friendsofphp/php-cs-fixer": "^3.0", "phpstan/phpstan": "^1.3", "phpunit/phpunit": "^9.5", + "symfony/maker-bundle": "^1.61", "symfony/phpunit-bridge": "^7.0", "symfony/test-pack": "^1.0" }, From fdf40ebfa85aacc9043136f769efc48550a46575 Mon Sep 17 00:00:00 2001 From: Regis Grison Date: Tue, 5 Nov 2024 07:41:34 +0100 Subject: [PATCH 04/18] re-run rector after configuration --- Command/AutoClosingCommand.php | 20 +- Command/TicketManagerCommand.php | 2 +- Component/TicketFeatures.php | 2 +- Controller/TicketAttachmentController.php | 2 +- Controller/TicketController.php | 46 ++- .../HackzillaTicketExtension.php | 9 +- Form/DataTransformer/StatusTransformer.php | 4 +- Form/Type/PriorityType.php | 2 +- Form/Type/StatusType.php | 2 +- Form/Type/TicketMessageType.php | 4 +- Form/Type/TicketType.php | 4 +- Maker/AbstractMaker.php | 26 +- Maker/MessageMaker.php | 4 +- Maker/Util/ClassSourceManipulator.php | 277 ++++++++++-------- Manager/PermissionManager.php | 4 +- Manager/PermissionManagerInterface.php | 2 - Manager/TicketManager.php | 28 +- Manager/UserManager.php | 22 +- Model/MessageAttachmentInterface.php | 3 +- Model/TicketInterface.php | 13 +- Model/TicketMessageInterface.php | 7 +- Model/TicketMessageTrait.php | 12 +- Model/TicketTrait.php | 15 +- Model/UserInterface.php | 3 +- Resources/config/commands.php | 6 - Resources/config/controllers.php | 4 +- Resources/config/event_listener.php | 1 - Resources/config/maker.php | 7 +- Resources/config/twig.php | 2 - Tests/Component/TicketFeaturesTest.php | 25 +- .../DependencyInjection/ConfigurationTest.php | 4 +- .../HackzillaTicketExtensionTest.php | 2 +- Tests/Fixtures/Entity/Ticket.php | 39 ++- Tests/Fixtures/Entity/TicketMessage.php | 29 +- .../Entity/TicketMessageWithAttachment.php | 41 +-- Tests/Fixtures/Entity/User.php | 17 +- .../DataTransformer/StatusTransformerTest.php | 2 +- Tests/Form/Type/PriorityTypeTest.php | 2 +- Tests/Form/Type/StatusTypeTest.php | 2 +- Tests/Form/Type/TicketMessageTypeTest.php | 7 +- Tests/Form/Type/TicketTypeTest.php | 5 +- Tests/Functional/Command/ApplicationTest.php | 14 +- Tests/Functional/FunctionalTest.php | 34 +-- Tests/Functional/TestKernel.php | 28 +- Tests/Functional/WebTestCase.php | 5 +- Tests/Manager/UserManagerTest.php | 11 +- Tests/TwigExtension/TicketFeaturesTest.php | 2 +- Tests/bootstrap.php | 2 +- TwigExtension/TicketFeatureExtension.php | 2 +- TwigExtension/TicketGlobalExtension.php | 5 +- composer.json | 1 + rector.php | 27 ++ 52 files changed, 430 insertions(+), 409 deletions(-) create mode 100644 rector.php diff --git a/Command/AutoClosingCommand.php b/Command/AutoClosingCommand.php index 4780f30..eeb6a61 100644 --- a/Command/AutoClosingCommand.php +++ b/Command/AutoClosingCommand.php @@ -13,6 +13,8 @@ namespace Hackzilla\Bundle\TicketBundle\Command; +use UnitEnum; +use InvalidArgumentException; use Hackzilla\Bundle\TicketBundle\Manager\TicketManagerInterface; use Hackzilla\Bundle\TicketBundle\Manager\UserManagerInterface; use Hackzilla\Bundle\TicketBundle\Model\TicketMessageInterface; @@ -29,27 +31,21 @@ final class AutoClosingCommand extends Command { protected static $defaultName = 'ticket:autoclosing'; - /** - * @var string - */ - private $locale = 'en'; + private bool|string|int|float|UnitEnum|array|null $locale = 'en'; - /** - * @var string - */ - private $translationDomain = 'HackzillaTicketBundle'; + private string $translationDomain = 'HackzillaTicketBundle'; /** * @var TranslatorInterface */ - private $translator; + private readonly LocaleAwareInterface $translator; public function __construct(private readonly TicketManagerInterface $ticketManager, private readonly UserManagerInterface $userManager, LocaleAwareInterface $translator, ParameterBagInterface $parameterBag) { parent::__construct(); - if (!is_a($translator, TranslatorInterface::class)) { - throw new \InvalidArgumentException($translator::class.' Must implement TranslatorInterface and LocaleAwareInterface'); + if (!$translator instanceof TranslatorInterface) { + throw new InvalidArgumentException($translator::class.' Must implement TranslatorInterface and LocaleAwareInterface'); } $this->translator = $translator; @@ -63,7 +59,7 @@ public function __construct(private readonly TicketManagerInterface $ticketManag /** * {@inheritdoc} */ - protected function configure() + protected function configure(): void { $this ->setDescription('Automatically close resolved tickets still opened') diff --git a/Command/TicketManagerCommand.php b/Command/TicketManagerCommand.php index 76ce3ca..e68327c 100644 --- a/Command/TicketManagerCommand.php +++ b/Command/TicketManagerCommand.php @@ -34,7 +34,7 @@ public function __construct(private readonly TicketManagerInterface $ticketManag /** * {@inheritdoc} */ - protected function configure() + protected function configure(): void { $this ->setDescription('Create a new Ticket') diff --git a/Component/TicketFeatures.php b/Component/TicketFeatures.php index 4981731..ed61873 100644 --- a/Component/TicketFeatures.php +++ b/Component/TicketFeatures.php @@ -21,7 +21,7 @@ final class TicketFeatures * @param array $features * @param string $messageClass TicketMessage class */ - private $features = []; + private array $features; /** * @param string $messageClass TicketMessage class diff --git a/Controller/TicketAttachmentController.php b/Controller/TicketAttachmentController.php index a03eece..6ceb5c1 100644 --- a/Controller/TicketAttachmentController.php +++ b/Controller/TicketAttachmentController.php @@ -36,7 +36,7 @@ public function __construct(private readonly DownloadHandler $downloadHandler, p /** * Download attachment on message. */ - public function downloadAction(int $ticketMessageId): Response + public function download(int $ticketMessageId): Response { $ticketMessage = $this->ticketManager->getMessageById($ticketMessageId); diff --git a/Controller/TicketController.php b/Controller/TicketController.php index 282e1d7..9dc5c50 100644 --- a/Controller/TicketController.php +++ b/Controller/TicketController.php @@ -13,6 +13,9 @@ namespace Hackzilla\Bundle\TicketBundle\Controller; +use Symfony\Component\HttpKernel\Exception\HttpException; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpFoundation\RedirectResponse; use Hackzilla\Bundle\TicketBundle\Event\TicketEvent; use Hackzilla\Bundle\TicketBundle\Form\Type\TicketMessageType; use Hackzilla\Bundle\TicketBundle\Form\Type\TicketType; @@ -52,12 +55,9 @@ public function __construct( /** * Lists all Ticket entities. - * - * @return \Symfony\Component\HttpFoundation\Response */ - public function indexAction(Request $request) + public function index(Request $request): Response { - $userManager = $this->userManager; $ticketManager = $this->ticketManager; $ticketState = $request->get('state', $this->translator->trans('STATUS_OPEN', [], 'HackzillaTicketBundle')); @@ -87,10 +87,8 @@ public function indexAction(Request $request) /** * Creates a new Ticket entity. - * - * @return \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response */ - public function createAction(Request $request) + public function create(Request $request): RedirectResponse|Response { $ticketManager = $this->ticketManager; @@ -108,7 +106,7 @@ public function createAction(Request $request) $ticketManager->updateTicket($ticket, $message); $this->dispatchTicketEvent(TicketEvents::TICKET_CREATE, $ticket); - return $this->redirect($this->generateUrl('hackzilla_ticket_show', ['ticketId' => $ticket->getId()])); + return $this->redirectToRoute('hackzilla_ticket_show', ['ticketId' => $ticket->getId()]); } return $this->render( @@ -124,7 +122,7 @@ public function createAction(Request $request) /** * Displays a form to create a new Ticket entity. */ - public function newAction() + public function new(): Response { $ticketManager = $this->ticketManager; $entity = $ticketManager->createTicket(); @@ -145,16 +143,14 @@ public function newAction() * Finds and displays a TicketInterface entity. * * @param int $ticketId - * - * @return \Symfony\Component\HttpFoundation\Response */ - public function showAction($ticketId) + public function show($ticketId): RedirectResponse|Response { $ticketManager = $this->ticketManager; $ticket = $ticketManager->getTicketById($ticketId); - if (!$ticket) { - return $this->redirect($this->generateUrl('hackzilla_ticket')); + if (!$ticket instanceof TicketInterface) { + return $this->redirectToRoute('hackzilla_ticket'); } $currentUser = $this->userManager->getCurrentUser(); @@ -182,15 +178,13 @@ public function showAction($ticketId) * Finds and displays a TicketInterface entity. * * @param int $ticketId - * - * @return \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response */ - public function replyAction(Request $request, $ticketId) + public function reply(Request $request, $ticketId): RedirectResponse|Response { $ticketManager = $this->ticketManager; $ticket = $ticketManager->getTicketById($ticketId); - if (!$ticket) { + if (!$ticket instanceof TicketInterface) { throw $this->createNotFoundException($this->translator->trans('ERROR_FIND_TICKET_ENTITY', [], 'HackzillaTicketBundle')); } @@ -210,7 +204,7 @@ public function replyAction(Request $request, $ticketId) $ticketManager->updateTicket($ticket, $message); $this->dispatchTicketEvent(TicketEvents::TICKET_UPDATE, $ticket); - return $this->redirect($this->generateUrl('hackzilla_ticket_show', ['ticketId' => $ticket->getId()])); + return $this->redirectToRoute('hackzilla_ticket_show', ['ticketId' => $ticket->getId()]); } $data = ['ticket' => $ticket, 'form' => $form->createView(), 'translationDomain' => 'HackzillaTicketBundle']; @@ -226,16 +220,14 @@ public function replyAction(Request $request, $ticketId) * Deletes a Ticket entity. * * @param int $ticketId - * - * @return \Symfony\Component\HttpFoundation\RedirectResponse */ - public function deleteAction(Request $request, $ticketId) + public function delete(Request $request, $ticketId): RedirectResponse { $userManager = $this->userManager; $user = $userManager->getCurrentUser(); if (!\is_object($user) || !$userManager->hasRole($user, TicketRole::ADMIN)) { - throw new \Symfony\Component\HttpKernel\Exception\HttpException(403); + throw new HttpException(403); } $form = $this->createDeleteForm($ticketId); @@ -247,7 +239,7 @@ public function deleteAction(Request $request, $ticketId) $ticketManager = $this->ticketManager; $ticket = $ticketManager->getTicketById($ticketId); - if (!$ticket) { + if (!$ticket instanceof TicketInterface) { throw $this->createNotFoundException($this->translator->trans('ERROR_FIND_TICKET_ENTITY', [], 'HackzillaTicketBundle')); } @@ -256,7 +248,7 @@ public function deleteAction(Request $request, $ticketId) } } - return $this->redirect($this->generateUrl('hackzilla_ticket')); + return $this->redirectToRoute('hackzilla_ticket'); } private function dispatchTicketEvent(string $ticketEvent, TicketInterface $ticket): void @@ -280,14 +272,12 @@ private function createDeleteForm(mixed $id): FormInterface private function createMessageForm(TicketMessageInterface $message): FormInterface { - $form = $this->createForm( + return $this->createForm( TicketMessageType::class, $message, [ 'ticket' => $message->getTicket(), ] ); - - return $form; } } diff --git a/DependencyInjection/HackzillaTicketExtension.php b/DependencyInjection/HackzillaTicketExtension.php index 74798a6..d05fb0e 100644 --- a/DependencyInjection/HackzillaTicketExtension.php +++ b/DependencyInjection/HackzillaTicketExtension.php @@ -13,10 +13,11 @@ namespace Hackzilla\Bundle\TicketBundle\DependencyInjection; +use Symfony\Component\DependencyInjection\Loader\PhpFileLoader; +use Exception; use Hackzilla\Bundle\TicketBundle\Manager\PermissionManager; use Symfony\Component\Config\FileLocator; use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\DependencyInjection\Loader; use Symfony\Component\HttpKernel\DependencyInjection\Extension; /** @@ -29,12 +30,12 @@ final class HackzillaTicketExtension extends Extension /** * {@inheritdoc} */ - public function load(array $configs, ContainerBuilder $container) + public function load(array $configs, ContainerBuilder $container): void { $configuration = new Configuration(); $config = $this->processConfiguration($configuration, $configs); - $loader = new Loader\PhpFileLoader($container, new FileLocator(self::bundleDirectory().'/Resources/config')); + $loader = new PhpFileLoader($container, new FileLocator(self::bundleDirectory().'/Resources/config')); $loader->load('manager.php'); $loader->load('maker.php'); $loader->load('form_types.php'); @@ -51,7 +52,7 @@ public function load(array $configs, ContainerBuilder $container) $permissionClass = $config['permission_class'] ?? PermissionManager::class; if (!class_exists($permissionClass)) { - throw new \Exception(sprintf('Permission manager does not exist: %s', $permissionClass)); + throw new Exception(sprintf('Permission manager does not exist: %s', $permissionClass)); } $container->setParameter('hackzilla_ticket.manager.permission.class', $permissionClass); diff --git a/Form/DataTransformer/StatusTransformer.php b/Form/DataTransformer/StatusTransformer.php index 1022cea..6619e6e 100644 --- a/Form/DataTransformer/StatusTransformer.php +++ b/Form/DataTransformer/StatusTransformer.php @@ -30,7 +30,7 @@ public function __construct(private readonly TicketInterface $ticket) * * @return true|null */ - public function transform($number) + public function transform($number): mixed { if (TicketMessageInterface::STATUS_CLOSED === $number) { return true; @@ -46,7 +46,7 @@ public function transform($number) * * @return int|null */ - public function reverseTransform($number) + public function reverseTransform($number): mixed { if ($number) { return TicketMessageInterface::STATUS_CLOSED; diff --git a/Form/Type/PriorityType.php b/Form/Type/PriorityType.php index e5a19f6..1a7d0a0 100644 --- a/Form/Type/PriorityType.php +++ b/Form/Type/PriorityType.php @@ -20,7 +20,7 @@ final class PriorityType extends AbstractType { - public function configureOptions(OptionsResolver $resolver) + public function configureOptions(OptionsResolver $resolver): void { $choices = TicketMessageInterface::PRIORITIES; unset($choices[TicketMessageInterface::PRIORITY_INVALID]); diff --git a/Form/Type/StatusType.php b/Form/Type/StatusType.php index 52abf07..7eaff0a 100644 --- a/Form/Type/StatusType.php +++ b/Form/Type/StatusType.php @@ -20,7 +20,7 @@ final class StatusType extends AbstractType { - public function configureOptions(OptionsResolver $resolver) + public function configureOptions(OptionsResolver $resolver): void { $choices = TicketMessageInterface::STATUSES; unset($choices[TicketMessageInterface::STATUS_INVALID]); diff --git a/Form/Type/TicketMessageType.php b/Form/Type/TicketMessageType.php index df24dc6..0e4fbc7 100644 --- a/Form/Type/TicketMessageType.php +++ b/Form/Type/TicketMessageType.php @@ -31,7 +31,7 @@ public function __construct(protected UserManagerInterface $userManager, protect { } - public function buildForm(FormBuilderInterface $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options): void { $builder ->add( @@ -96,7 +96,7 @@ public function buildForm(FormBuilderInterface $builder, array $options) } } - public function configureOptions(OptionsResolver $resolver) + public function configureOptions(OptionsResolver $resolver): void { $resolver->setDefaults( [ diff --git a/Form/Type/TicketType.php b/Form/Type/TicketType.php index d8fd6f7..149393c 100644 --- a/Form/Type/TicketType.php +++ b/Form/Type/TicketType.php @@ -25,7 +25,7 @@ public function __construct(protected string $ticketClass) { } - public function buildForm(FormBuilderInterface $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options): void { $builder ->add( @@ -50,7 +50,7 @@ public function buildForm(FormBuilderInterface $builder, array $options) ; } - public function configureOptions(OptionsResolver $resolver) + public function configureOptions(OptionsResolver $resolver): void { $resolver->setDefaults( [ diff --git a/Maker/AbstractMaker.php b/Maker/AbstractMaker.php index 27b991f..b41c65c 100644 --- a/Maker/AbstractMaker.php +++ b/Maker/AbstractMaker.php @@ -14,6 +14,10 @@ namespace Hackzilla\Bundle\TicketBundle\Maker; +use UnitEnum; +use Exception; +use ReflectionClass; +use ReflectionProperty; use Hackzilla\Bundle\TicketBundle\Maker\Util\ClassSourceManipulator; use Symfony\Bundle\MakerBundle\ConsoleStyle; use Symfony\Bundle\MakerBundle\DependencyBuilder; @@ -37,9 +41,9 @@ */ abstract class AbstractMaker extends \Symfony\Bundle\MakerBundle\Maker\AbstractMaker { - private $userClass; - private $ticketClass; - private $messageClass; + private readonly bool|string|int|float|UnitEnum|array|null $userClass; + private readonly bool|string|int|float|UnitEnum|array|null $ticketClass; + private readonly bool|string|int|float|UnitEnum|array|null $messageClass; public function __construct(private readonly FileManager $fileManager, private readonly DoctrineHelper $doctrineHelper, ParameterBagInterface $bag) { @@ -69,7 +73,7 @@ public function getMessageClass(): string * By default, all arguments will be asked interactively. If you want * to avoid that, use the $inputConfig->setArgumentAsNonInteractive() method. */ - public function configureCommand(Command $command, InputConfiguration $inputConfig) + public function configureCommand(Command $command, InputConfiguration $inputConfig): void { $command ->addOption('api-resource', 'a', InputOption::VALUE_NONE, 'Mark this class as an API Platform resource (expose a CRUD API for it)') @@ -94,7 +98,7 @@ public function interact(InputInterface $input, ConsoleStyle $io, Command $comma /** * Called after normal code generation: allows you to do anything. */ - public function generate(InputInterface $input, ConsoleStyle $io, Generator $generator) + public function generate(InputInterface $input, ConsoleStyle $io, Generator $generator): void { $entityClass = $this->entityClass(); @@ -160,7 +164,7 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen // The *other* class will receive the ManyToOne $otherManipulator->addManyToOneRelation($newField->getOwningRelation()); if (!$newField->getMapInverseRelation()) { - throw new \Exception('Somehow a OneToMany relationship is being created, but the inverse side will not be mapped?'); + throw new Exception('Somehow a OneToMany relationship is being created, but the inverse side will not be mapped?'); } $manipulator->addOneToManyRelation($newField->getInverseRelation()); } @@ -181,7 +185,7 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen break; default: - throw new \Exception('Invalid relation type'); + throw new Exception('Invalid relation type'); } // save the inverse side if it's being mapped @@ -190,7 +194,7 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen } $currentFields[] = $newFieldName; } else { - throw new \Exception('Invalid value'); + throw new Exception('Invalid value'); } foreach ($fileManagerOperations as $path => $manipulatorOrMessage) { @@ -223,7 +227,7 @@ private function createClassManipulator(string $path, ConsoleStyle $io, bool $ov } if (!$useAnnotations && !$useAttributes) { - throw new \Exception('No support for either Annotations or Attributes'); + throw new Exception('No support for either Annotations or Attributes'); } $manipulator = new ClassSourceManipulator($this->fileManager->getFileContents($path), $overwrite, $useAnnotations, $useAttributes); @@ -257,9 +261,9 @@ private function getPropertyNames(string $class): array return []; } - $reflClass = new \ReflectionClass($class); + $reflClass = new ReflectionClass($class); - return array_map(static fn(\ReflectionProperty $prop) => $prop->getName(), $reflClass->getProperties()); + return array_map(static fn(ReflectionProperty $prop): string => $prop->getName(), $reflClass->getProperties()); } private function doesEntityUseAnnotationMapping(string $className): bool diff --git a/Maker/MessageMaker.php b/Maker/MessageMaker.php index 16b005b..c3df535 100644 --- a/Maker/MessageMaker.php +++ b/Maker/MessageMaker.php @@ -40,14 +40,14 @@ public static function getCommandDescription(): string return MakeEntity::getCommandDescription(); } - public function configureCommand(Command $command, InputConfiguration $inputConfig) + public function configureCommand(Command $command, InputConfiguration $inputConfig): void { $command->addOption('attachment', null, InputOption::VALUE_NONE, 'Overwrite any existing getter/setter methods'); parent::configureCommand($command, $inputConfig); } - public function generate(InputInterface $input, ConsoleStyle $io, Generator $generator) + public function generate(InputInterface $input, ConsoleStyle $io, Generator $generator): void { $this->hasAttachment = $input->getOption('attachment'); diff --git a/Maker/Util/ClassSourceManipulator.php b/Maker/Util/ClassSourceManipulator.php index 23cca04..3e00aac 100644 --- a/Maker/Util/ClassSourceManipulator.php +++ b/Maker/Util/ClassSourceManipulator.php @@ -14,19 +14,56 @@ namespace Hackzilla\Bundle\TicketBundle\Maker\Util; +use PhpParser\Lexer\Emulative; +use PhpParser\Parser\Php7; +use PhpParser\Node\Stmt\Expression; +use PhpParser\Node\Expr\Assign; +use PhpParser\Node\Expr\PropertyFetch; +use PhpParser\Node\Expr\Variable; +use PhpParser\Node\Expr\New_; +use PhpParser\Node\Name; +use PhpParser\Node\Expr\Array_; +use PhpParser\Node\Stmt\TraitUse; +use LogicException; +use PhpParser\Builder\Method; +use PhpParser\Node\NullableType; +use PhpParser\Builder\Property; +use PhpParser\Node\Stmt\Use_; +use PhpParser\Node\Stmt\Class_; +use Exception; +use PhpParser\Node\Stmt; +use ReflectionClass; +use PhpParser\Node\Expr\StaticCall; +use PhpParser\Node\Identifier; +use ReflectionException; +use PhpParser\Node\Stmt\ClassMethod; +use PhpParser\NodeVisitor\CloningVisitor; +use PhpParser\NodeVisitor\NameResolver; +use PhpParser\Node\Stmt\Namespace_; +use PhpParser\NodeVisitor\FirstFindingVisitor; +use PhpParser\NodeVisitor\FindingVisitor; +use DateTimeInterface; +use DateTimeImmutable; +use DateInterval; +use PhpParser\Node\Stmt\ClassConst; +use PhpParser\Node\Expr; +use PhpParser\Node\Scalar\String_; +use PhpParser\Node\Scalar\LNumber; +use PhpParser\Node\Scalar\DNumber; +use PhpParser\Node\Expr\ConstFetch; +use PhpParser\Node\Expr\ArrayItem; +use PhpParser\Node\Attribute; +use PhpParser\Node\Arg; +use ReflectionParameter; use Doctrine\Common\Collections\ArrayCollection; use PhpParser\Builder; use PhpParser\BuilderHelpers; use PhpParser\Comment\Doc; -use PhpParser\Lexer; use PhpParser\Node; use PhpParser\NodeTraverser; -use PhpParser\NodeVisitor; -use PhpParser\Parser; use Symfony\Bundle\MakerBundle\ConsoleStyle; use Symfony\Bundle\MakerBundle\Doctrine\BaseCollectionRelation; use Symfony\Bundle\MakerBundle\Doctrine\BaseRelation; -use Symfony\Bundle\MakerBundle\Doctrine\BaseSingleRelation; use Symfony\Bundle\MakerBundle\Doctrine\RelationManyToMany; use Symfony\Bundle\MakerBundle\Doctrine\RelationManyToOne; use Symfony\Bundle\MakerBundle\Doctrine\RelationOneToMany; @@ -48,29 +85,28 @@ final class ClassSourceManipulator private const CONTEXT_OUTSIDE_CLASS = 'outside_class'; private const CONTEXT_CLASS = 'class'; private const CONTEXT_CLASS_METHOD = 'class_method'; - private $parser; - private $lexer; - private $printer; - /** @var ConsoleStyle|null */ - private $io; + private readonly Php7 $parser; + private readonly Emulative $lexer; + private readonly PrettyPrinter $printer; + private ?ConsoleStyle $io = null; - private $sourceCode; + private string $sourceCode; private $oldStmts; - private $oldTokens; - private $newStmts; + private array $oldTokens; + private array $newStmts; - private $pendingComments = []; + private array $pendingComments = []; public function __construct(string $sourceCode, private readonly bool $overwrite = false, private readonly bool $useAnnotations = true, private readonly bool $useAttributesForDoctrineMapping = false) { - $this->lexer = new Lexer\Emulative([ + $this->lexer = new Emulative([ 'usedAttributes' => [ 'comments', 'startLine', 'endLine', 'startTokenPos', 'endTokenPos', ], ]); - $this->parser = new Parser\Php7($this->lexer); + $this->parser = new Php7($this->lexer); $this->printer = new PrettyPrinter(); $this->setSourceCode($sourceCode); @@ -86,10 +122,10 @@ public function getSourceCode(): string return $this->sourceCode; } - public function addCreatedToContructor() + public function addCreatedToContructor(): void { $addCreatedAt = true; - if ($this->getConstructorNode()) { + if ($this->getConstructorNode() instanceof ClassMethod) { // We print the constructor to a string, then // look for "$this->propertyName = " @@ -101,9 +137,9 @@ public function addCreatedToContructor() if ($addCreatedAt) { $this->addStatementToConstructor( - new Node\Stmt\Expression(new Node\Expr\Assign( - new Node\Expr\PropertyFetch(new Node\Expr\Variable('this'), 'createdAt'), - new Node\Expr\New_(new Node\Name('\DateTime')) + new Expression(new Assign( + new PropertyFetch(new Variable('this'), 'createdAt'), + new New_(new Name('\DateTime')) )) ); } @@ -112,8 +148,6 @@ public function addCreatedToContructor() public function addEntityField(string $propertyName, array $columnOptions, array $comments = []): void { $typeHint = $this->getEntityTypeHint($columnOptions['type']); - $nullable = $columnOptions['nullable'] ?? false; - $isId = (bool) ($columnOptions['id'] ?? false); $attributes = []; if ($this->useAttributesForDoctrineMapping) { @@ -124,7 +158,7 @@ public function addEntityField(string $propertyName, array $columnOptions, array $defaultValue = null; if ('array' === $typeHint) { - $defaultValue = new Node\Expr\Array_([], ['kind' => Node\Expr\Array_::KIND_SHORT]); + $defaultValue = new Array_([], ['kind' => Array_::KIND_SHORT]); } $this->addProperty($propertyName, $comments, $defaultValue, $attributes); @@ -160,7 +194,7 @@ public function addInterface(string $interfaceName): void } } - $this->getClassNode()->implements[] = new Node\Name(Str::getShortClassName($interfaceName)); + $this->getClassNode()->implements[] = new Name(Str::getShortClassName($interfaceName)); $this->updateSourceCodeFromNewStmts(); } @@ -171,8 +205,8 @@ public function addTrait(string $trait): void { $importedClassName = $this->addUseStatementIfNecessary($trait); - /** @var Node\Stmt\TraitUse[] $traitNodes */ - $traitNodes = $this->findAllNodes(static fn($node) => $node instanceof Node\Stmt\TraitUse); + /** @var TraitUse[] $traitNodes */ + $traitNodes = $this->findAllNodes(static fn($node): bool => $node instanceof TraitUse); foreach ($traitNodes as $node) { if ($node->traits[0]->toString() === $importedClassName) { @@ -180,7 +214,7 @@ public function addTrait(string $trait): void } } - $traitNodes[] = new Node\Stmt\TraitUse([new Node\Name($importedClassName)]); + $traitNodes[] = new TraitUse([new Name($importedClassName)]); $classNode = $this->getClassNode(); @@ -191,7 +225,7 @@ public function addTrait(string $trait): void // avoid all the use traits in class for unshift all the new UseTrait // in the right order. foreach ($classNode->stmts as $key => $node) { - if ($node instanceof Node\Stmt\TraitUse) { + if ($node instanceof TraitUse) { unset($classNode->stmts[$key]); } } @@ -206,8 +240,8 @@ public function addTrait(string $trait): void */ public function addConstructor(array $params, string $methodBody): void { - if (null !== $this->getConstructorNode()) { - throw new \LogicException('Constructor already exists.'); + if ($this->getConstructorNode() instanceof ClassMethod) { + throw new LogicException('Constructor already exists.'); } $methodBuilder = $this->createMethodBuilder('__construct', null, false); @@ -223,7 +257,7 @@ public function addConstructor(array $params, string $methodBody): void /** * @param Node[] $params */ - public function addMethodBuilder(Builder\Method $methodBuilder, array $params = [], ?string $methodBody = null): void + public function addMethodBuilder(Method $methodBuilder, array $params = [], ?string $methodBody = null): void { $this->addMethodParams($methodBuilder, $params); @@ -234,15 +268,15 @@ public function addMethodBuilder(Builder\Method $methodBuilder, array $params = $this->addMethod($methodBuilder->getNode()); } - public function addMethodBody(Builder\Method $methodBuilder, string $methodBody): void + public function addMethodBody(Method $methodBuilder, string $methodBody): void { $nodes = $this->parser->parse($methodBody); $methodBuilder->addStmts($nodes); } - public function createMethodBuilder(string $methodName, $returnType, bool $isReturnTypeNullable, array $commentLines = []): Builder\Method + public function createMethodBuilder(string $methodName, $returnType, bool $isReturnTypeNullable, array $commentLines = []): Method { - $methodNodeBuilder = (new Builder\Method($methodName)) + $methodNodeBuilder = (new Method($methodName)) ->makePublic() ; @@ -250,17 +284,17 @@ public function createMethodBuilder(string $methodName, $returnType, bool $isRet if (class_exists($returnType) || interface_exists($returnType)) { $returnType = $this->addUseStatementIfNecessary($returnType); } - $methodNodeBuilder->setReturnType($isReturnTypeNullable ? new Node\NullableType($returnType) : $returnType); + $methodNodeBuilder->setReturnType($isReturnTypeNullable ? new NullableType($returnType) : $returnType); } - if ($commentLines) { + if ($commentLines !== []) { $methodNodeBuilder->setDocComment($this->createDocBlock($commentLines)); } return $methodNodeBuilder; } - public function createMethodLevelCommentNode(string $comment) + public function createMethodLevelCommentNode(string $comment): Stmt { return $this->createSingleLineCommentNode($comment, self::CONTEXT_CLASS_METHOD); } @@ -277,7 +311,7 @@ public function addProperty(string $name, array $annotationLines = [], $defaultV return; } - $newPropertyBuilder = (new Builder\Property($name))->makePrivate(); + $newPropertyBuilder = (new Property($name))->makePrivate(); if ($annotationLines && $this->useAnnotations) { $newPropertyBuilder->setDocComment($this->createDocBlock($annotationLines)); @@ -301,7 +335,7 @@ public function addAnnotationToClass(string $annotationClass, array $options): v $docComment = $this->getClassNode()->getDocComment(); $docLines = $docComment ? explode("\n", $docComment->getText()) : []; - if (0 === \count($docLines)) { + if ([] === $docLines) { $docLines = ['/**', ' */']; } elseif (1 === \count($docLines)) { // /** inline doc syntax */ @@ -313,7 +347,7 @@ public function addAnnotationToClass(string $annotationClass, array $options): v substr($docLines[0], 0, $endOfOpening + 1), ]; - if ($extraComments) { + if ($extraComments !== '' && $extraComments !== '0') { $newDocLines[] = ' * '.$extraComments; } @@ -349,7 +383,7 @@ public function addUseStatementIfNecessary(string $class): string $addLineBreak = false; $lastUseStmtIndex = null; foreach ($namespaceNode->stmts as $index => $stmt) { - if ($stmt instanceof Node\Stmt\Use_) { + if ($stmt instanceof Use_) { // I believe this is an array to account for use statements with {} foreach ($stmt->uses as $use) { $alias = $use->alias ? $use->alias->name : $use->name->getLast(); @@ -374,7 +408,7 @@ public function addUseStatementIfNecessary(string $class): string } $lastUseStmtIndex = $index; - } elseif ($stmt instanceof Node\Stmt\Class_) { + } elseif ($stmt instanceof Class_) { if (null !== $targetIndex) { // we already found where to place the use statement @@ -395,10 +429,10 @@ public function addUseStatementIfNecessary(string $class): string } if (null === $targetIndex) { - throw new \Exception('Could not find a class!'); + throw new Exception('Could not find a class!'); } - $newUseNode = (new Builder\Use_($class, Node\Stmt\Use_::TYPE_NORMAL))->getNode(); + $newUseNode = (new Builder\Use_($class, Use_::TYPE_NORMAL))->getNode(); array_splice( $namespaceNode->stmts, $targetIndex, @@ -417,13 +451,13 @@ public function addUseStatementIfNecessary(string $class): string */ private function buildAnnotationLine(string $annotationClass, array $options): string { - $formattedOptions = array_map(function ($option, $value) { + $formattedOptions = array_map(function ($option, $value): string { if (\is_array($value)) { if (!isset($value[0])) { - return sprintf('%s={%s}', $option, implode(', ', array_map(fn($val, $key) => sprintf('"%s" = %s', $key, $this->quoteAnnotationValue($val)), $value, array_keys($value)))); + return sprintf('%s={%s}', $option, implode(', ', array_map(fn($val, $key): string => sprintf('"%s" = %s', $key, $this->quoteAnnotationValue($val)), $value, array_keys($value)))); } - return sprintf('%s={%s}', $option, implode(', ', array_map(fn($val) => $this->quoteAnnotationValue($val), $value))); + return sprintf('%s={%s}', $option, implode(', ', array_map(fn($val): int|string => $this->quoteAnnotationValue($val), $value))); } return sprintf('%s=%s', $option, $this->quoteAnnotationValue($value)); @@ -432,7 +466,7 @@ private function buildAnnotationLine(string $annotationClass, array $options): s return sprintf('%s(%s)', $annotationClass, implode(', ', $formattedOptions)); } - private function quoteAnnotationValue($value) + private function quoteAnnotationValue($value): int|string { if (\is_bool($value)) { return $value ? 'true' : 'false'; @@ -451,7 +485,7 @@ private function quoteAnnotationValue($value) } if (\is_array($value)) { - throw new \Exception('Invalid value: loop before quoting.'); + throw new Exception('Invalid value: loop before quoting.'); } return sprintf('"%s"', $value); @@ -460,7 +494,7 @@ private function quoteAnnotationValue($value) private function addSingularRelation(BaseRelation $relation): void { $typeHint = $this->addUseStatementIfNecessary($relation->getTargetClassName()); - if ($relation->getTargetClassName() == $this->getThisFullClassName()) { + if ($relation->getTargetClassName() === $this->getThisFullClassName()) { $typeHint = 'self'; } @@ -547,7 +581,7 @@ private function addCollectionRelation(BaseCollectionRelation $relation): void // logic to avoid re-adding the same ArrayCollection line $addArrayCollection = true; - if ($this->getConstructorNode()) { + if ($this->getConstructorNode() instanceof ClassMethod) { // We print the constructor to a string, then // look for "$this->propertyName = " @@ -559,31 +593,31 @@ private function addCollectionRelation(BaseCollectionRelation $relation): void if ($addArrayCollection) { $this->addStatementToConstructor( - new Node\Stmt\Expression(new Node\Expr\Assign( - new Node\Expr\PropertyFetch(new Node\Expr\Variable('this'), $relation->getPropertyName()), - new Node\Expr\New_(new Node\Name($arrayCollectionTypeHint)) + new Expression(new Assign( + new PropertyFetch(new Variable('this'), $relation->getPropertyName()), + new New_(new Name($arrayCollectionTypeHint)) )) ); } - $argName = Str::pluralCamelCaseToSingular($relation->getPropertyName()); + Str::pluralCamelCaseToSingular($relation->getPropertyName()); } - private function addStatementToConstructor(Node\Stmt $stmt): void + private function addStatementToConstructor(Stmt $stmt): void { - if (!$this->getConstructorNode()) { - $constructorNode = (new Builder\Method('__construct'))->makePublic()->getNode(); + if (!$this->getConstructorNode() instanceof ClassMethod) { + $constructorNode = (new Method('__construct'))->makePublic()->getNode(); // add call to parent::__construct() if there is a need to try { - $ref = new \ReflectionClass($this->getThisFullClassName()); + $ref = new ReflectionClass($this->getThisFullClassName()); if ($ref->getParentClass() && $ref->getParentClass()->getConstructor()) { - $constructorNode->stmts[] = new Node\Stmt\Expression( - new Node\Expr\StaticCall(new Node\Name('parent'), new Node\Identifier('__construct')) + $constructorNode->stmts[] = new Expression( + new StaticCall(new Name('parent'), new Identifier('__construct')) ); } - } catch (\ReflectionException) { + } catch (ReflectionException) { } $this->addNodeAfterProperties($constructorNode); @@ -595,12 +629,12 @@ private function addStatementToConstructor(Node\Stmt $stmt): void } /** - * @throws \Exception + * @throws Exception */ - private function getConstructorNode(): ?Node\Stmt\ClassMethod + private function getConstructorNode(): ?ClassMethod { foreach ($this->getClassNode()->stmts as $classNode) { - if ($classNode instanceof Node\Stmt\ClassMethod && '__construct' == $classNode->name) { + if ($classNode instanceof ClassMethod && '__construct' == $classNode->name) { return $classNode; } } @@ -645,31 +679,31 @@ private function setSourceCode(string $sourceCode): void $this->oldTokens = $this->lexer->getTokens(); $traverser = new NodeTraverser(); - $traverser->addVisitor(new NodeVisitor\CloningVisitor()); - $traverser->addVisitor(new NodeVisitor\NameResolver(null, [ + $traverser->addVisitor(new CloningVisitor()); + $traverser->addVisitor(new NameResolver(null, [ 'replaceNodes' => false, ])); $this->newStmts = $traverser->traverse($this->oldStmts); } - private function getClassNode(): Node\Stmt\Class_ + private function getClassNode(): Class_ { - $node = $this->findFirstNode(static fn($node) => $node instanceof Node\Stmt\Class_); + $node = $this->findFirstNode(static fn($node): bool => $node instanceof Class_); - if (!$node) { - throw new \Exception('Could not find class node'); + if (!$node instanceof Node) { + throw new Exception('Could not find class node'); } /* @phpstan-ignore-next-line */ return $node; } - private function getNamespaceNode(): Node\Stmt\Namespace_ + private function getNamespaceNode(): Namespace_ { - $node = $this->findFirstNode(static fn($node) => $node instanceof Node\Stmt\Namespace_); + $node = $this->findFirstNode(static fn($node): bool => $node instanceof Namespace_); - if (!$node) { - throw new \Exception('Could not find namespace node'); + if (!$node instanceof Node) { + throw new Exception('Could not find namespace node'); } /* @phpstan-ignore-next-line */ @@ -679,7 +713,7 @@ private function getNamespaceNode(): Node\Stmt\Namespace_ private function findFirstNode(callable $filterCallback): ?Node { $traverser = new NodeTraverser(); - $visitor = new NodeVisitor\FirstFindingVisitor($filterCallback); + $visitor = new FirstFindingVisitor($filterCallback); $traverser->addVisitor($visitor); $traverser->traverse($this->newStmts); @@ -689,7 +723,7 @@ private function findFirstNode(callable $filterCallback): ?Node private function findLastNode(callable $filterCallback, array $ast): ?Node { $traverser = new NodeTraverser(); - $visitor = new NodeVisitor\FindingVisitor($filterCallback); + $visitor = new FindingVisitor($filterCallback); $traverser->addVisitor($visitor); $traverser->traverse($ast); @@ -705,7 +739,7 @@ private function findLastNode(callable $filterCallback, array $ast): ?Node private function findAllNodes(callable $filterCallback): array { $traverser = new NodeTraverser(); - $visitor = new NodeVisitor\FindingVisitor($filterCallback); + $visitor = new FindingVisitor($filterCallback); $traverser->addVisitor($visitor); $traverser->traverse($this->newStmts); @@ -715,30 +749,30 @@ private function findAllNodes(callable $filterCallback): array private function createBlankLineNode(string $context) { return match ($context) { - self::CONTEXT_OUTSIDE_CLASS => (new Builder\Use_('__EXTRA__LINE', Node\Stmt\Use_::TYPE_NORMAL)) + self::CONTEXT_OUTSIDE_CLASS => (new Builder\Use_('__EXTRA__LINE', Use_::TYPE_NORMAL)) ->getNode(), - self::CONTEXT_CLASS => (new Builder\Property('__EXTRA__LINE')) + self::CONTEXT_CLASS => (new Property('__EXTRA__LINE')) ->makePrivate() ->getNode(), - self::CONTEXT_CLASS_METHOD => new Node\Expr\Variable('__EXTRA__LINE'), - default => throw new \Exception('Unknown context: '.$context), + self::CONTEXT_CLASS_METHOD => new Variable('__EXTRA__LINE'), + default => throw new Exception('Unknown context: '.$context), }; } - private function createSingleLineCommentNode(string $comment, string $context): Node\Stmt + private function createSingleLineCommentNode(string $comment, string $context): Stmt { $this->pendingComments[] = $comment; switch ($context) { case self::CONTEXT_OUTSIDE_CLASS: // just not needed yet - throw new \Exception('not supported'); + throw new Exception('not supported'); case self::CONTEXT_CLASS: // just not needed yet - throw new \Exception('not supported'); + throw new Exception('not supported'); case self::CONTEXT_CLASS_METHOD: - return BuilderHelpers::normalizeStmt(new Node\Expr\Variable(sprintf('__COMMENT__VAR_%d', \count($this->pendingComments) - 1))); + return BuilderHelpers::normalizeStmt(new Variable(sprintf('__COMMENT__VAR_%d', \count($this->pendingComments) - 1))); default: - throw new \Exception('Unknown context: '.$context); + throw new Exception('Unknown context: '.$context); } } @@ -753,12 +787,11 @@ private function createDocBlock(array $commentLines): string $docBlock .= " *\n"; } } - $docBlock .= "\n */"; - return $docBlock; + return $docBlock . "\n */"; } - private function addMethod(Node\Stmt\ClassMethod $methodNode): void + private function addMethod(ClassMethod $methodNode): void { $classNode = $this->getClassNode(); $methodName = $methodNode->name; @@ -811,16 +844,16 @@ private function getEntityTypeHint($doctrineType): ?string 'boolean' => 'bool', 'integer', 'smallint' => 'int', 'float' => 'float', - 'datetime', 'datetimetz', 'date', 'time' => '\\'.\DateTimeInterface::class, - 'datetime_immutable', 'datetimetz_immutable', 'date_immutable', 'time_immutable' => '\\'.\DateTimeImmutable::class, - 'dateinterval' => '\\'.\DateInterval::class, + 'datetime', 'datetimetz', 'date', 'time' => '\\'.DateTimeInterface::class, + 'datetime_immutable', 'datetimetz_immutable', 'date_immutable', 'time_immutable' => '\\'.DateTimeImmutable::class, + 'dateinterval' => '\\'.DateInterval::class, default => null, }; } - private function isInSameNamespace($class): bool + private function isInSameNamespace(string $class): bool { - $namespace = substr((string) $class, 0, strrpos((string) $class, '\\')); + $namespace = substr($class, 0, strrpos($class, '\\')); return $this->getNamespaceNode()->name->toCodeString() === $namespace; } @@ -840,20 +873,20 @@ private function addNodeAfterProperties(Node $newNode): void $classNode = $this->getClassNode(); // try to add after last property - $targetNode = $this->findLastNode(static fn($node) => $node instanceof Node\Stmt\Property, [$classNode]); + $targetNode = $this->findLastNode(static fn($node): bool => $node instanceof Node\Stmt\Property, [$classNode]); // otherwise, try to add after the last constant - if (!$targetNode) { - $targetNode = $this->findLastNode(static fn($node) => $node instanceof Node\Stmt\ClassConst, [$classNode]); + if (!$targetNode instanceof Node) { + $targetNode = $this->findLastNode(static fn($node): bool => $node instanceof ClassConst, [$classNode]); } // otherwise, try to add after the last trait - if (!$targetNode) { - $targetNode = $this->findLastNode(static fn($node) => $node instanceof Node\Stmt\TraitUse, [$classNode]); + if (!$targetNode instanceof Node) { + $targetNode = $this->findLastNode(static fn($node): bool => $node instanceof TraitUse, [$classNode]); } // add the new property after this node - if ($targetNode) { + if ($targetNode instanceof Node) { $index = array_search($targetNode, $classNode->stmts, true); array_splice( @@ -885,7 +918,7 @@ private function methodExists(string $methodName): bool private function getMethodIndex(string $methodName) { foreach ($this->getClassNode()->stmts as $i => $node) { - if ($node instanceof Node\Stmt\ClassMethod && strtolower($node->name->toString()) === strtolower($methodName)) { + if ($node instanceof ClassMethod && strtolower($node->name->toString()) === strtolower($methodName)) { return $i; } } @@ -895,7 +928,7 @@ private function getMethodIndex(string $methodName) private function propertyExists(string $propertyName): bool { - foreach ($this->getClassNode()->stmts as $i => $node) { + foreach ($this->getClassNode()->stmts as $node) { if ($node instanceof Node\Stmt\Property && $node->props[0]->name->toString() === $propertyName) { return true; } @@ -906,12 +939,12 @@ private function propertyExists(string $propertyName): bool private function writeNote(string $note): void { - if (null !== $this->io) { + if ($this->io instanceof ConsoleStyle) { $this->io->text($note); } } - private function addMethodParams(Builder\Method $methodBuilder, array $params): void + private function addMethodParams(Method $methodBuilder, array $params): void { foreach ($params as $param) { $methodBuilder->addParam($param); @@ -923,30 +956,30 @@ private function addMethodParams(Builder\Method $methodBuilder, array $params): * throws an Exception when the given $value is not resolvable by this method. * * - * @throws \Exception + * @throws Exception */ - private function buildNodeExprByValue(mixed $value): Node\Expr + private function buildNodeExprByValue(mixed $value): Expr { switch (\gettype($value)) { case 'string': - $nodeValue = new Node\Scalar\String_($value); + $nodeValue = new String_($value); break; case 'integer': - $nodeValue = new Node\Scalar\LNumber($value); + $nodeValue = new LNumber($value); break; case 'double': - $nodeValue = new Node\Scalar\DNumber($value); + $nodeValue = new DNumber($value); break; case 'boolean': - $nodeValue = new Node\Expr\ConstFetch(new Node\Name($value ? 'true' : 'false')); + $nodeValue = new ConstFetch(new Name($value ? 'true' : 'false')); break; case 'array': $context = $this; - $arrayItems = array_map(static fn($key, $value) => new Node\Expr\ArrayItem( + $arrayItems = array_map(static fn($key, $value): ArrayItem => new ArrayItem( $context->buildNodeExprByValue($value), - !\is_int($key) ? $context->buildNodeExprByValue($key) : null + \is_int($key) ? null : $context->buildNodeExprByValue($key) ), array_keys($value), array_values($value)); - $nodeValue = new Node\Expr\Array_($arrayItems, ['kind' => Node\Expr\Array_::KIND_SHORT]); + $nodeValue = new Array_($arrayItems, ['kind' => Array_::KIND_SHORT]); break; default: $nodeValue = null; @@ -954,13 +987,13 @@ private function buildNodeExprByValue(mixed $value): Node\Expr if (null === $nodeValue) { if ($value instanceof ClassNameValue) { - $nodeValue = new Node\Expr\ConstFetch( - new Node\Name( + $nodeValue = new ConstFetch( + new Name( sprintf('%s::class', $value->isSelf() ? 'self' : $value->getShortName()) ) ); } else { - throw new \Exception(sprintf('Cannot build a node expr for value of type "%s"', \gettype($value))); + throw new Exception(sprintf('Cannot build a node expr for value of type "%s"', \gettype($value))); } } @@ -973,15 +1006,15 @@ private function buildNodeExprByValue(mixed $value): Node\Expr * @param string $attributeClass the attribute class which should be used for the attribute * @param array $options the named arguments for the attribute ($key = argument name, $value = argument value) */ - private function buildAttributeNode(string $attributeClass, array $options): Node\Attribute + private function buildAttributeNode(string $attributeClass, array $options): Attribute { $options = $this->sortOptionsByClassConstructorParameters($options, $attributeClass); $context = $this; - $nodeArguments = array_map(static fn($option, $value) => new Node\Arg($context->buildNodeExprByValue($value), false, false, [], new Node\Identifier($option)), array_keys($options), array_values($options)); + $nodeArguments = array_map(static fn($option, $value): Arg => new Arg($context->buildNodeExprByValue($value), false, false, [], new Identifier($option)), array_keys($options), array_values($options)); - return new Node\Attribute( - new Node\Name($attributeClass), + return new Attribute( + new Name($attributeClass), $nodeArguments ); } @@ -998,7 +1031,7 @@ private function sortOptionsByClassConstructorParameters(array $options, string $classString = sprintf('Doctrine\\ORM\\Mapping\\%s', substr($classString, 4)); } - $constructorParameterNames = array_map(static fn(\ReflectionParameter $reflectionParameter) => $reflectionParameter->getName(), (new \ReflectionClass($classString))->getConstructor()->getParameters()); + $constructorParameterNames = array_map(static fn(ReflectionParameter $reflectionParameter): string => $reflectionParameter->getName(), (new ReflectionClass($classString))->getConstructor()->getParameters()); $sorted = []; foreach ($constructorParameterNames as $name) { diff --git a/Manager/PermissionManager.php b/Manager/PermissionManager.php index 865f671..740d42e 100644 --- a/Manager/PermissionManager.php +++ b/Manager/PermissionManager.php @@ -49,13 +49,11 @@ public function addUserPermissionsCondition($query, ?UserInterface $user) /** * used by UserManager::hasPermission(). - * - * @param ?UserInterface $user */ public function hasPermission(?UserInterface $user, TicketInterface $ticket): void { if (!\is_object($user) || (!$this->getUserManager()->hasRole($user, TicketRole::ADMIN) && - (null === $ticket->getUserCreated() || $ticket->getUserCreated()->getId() != $user->getId())) + (!$ticket->getUserCreated() instanceof UserInterface || $ticket->getUserCreated()->getId() != $user->getId())) ) { throw new AccessDeniedHttpException(); } diff --git a/Manager/PermissionManagerInterface.php b/Manager/PermissionManagerInterface.php index 9215339..e19b97f 100644 --- a/Manager/PermissionManagerInterface.php +++ b/Manager/PermissionManagerInterface.php @@ -27,8 +27,6 @@ public function addUserPermissionsCondition($query, UserInterface $user); /** * used by UserManager::hasPermission(). - * - * @param ?UserInterface $user */ public function hasPermission(?UserInterface $user, TicketInterface $ticket): void; } diff --git a/Manager/TicketManager.php b/Manager/TicketManager.php index 774d9c7..fdce858 100644 --- a/Manager/TicketManager.php +++ b/Manager/TicketManager.php @@ -13,6 +13,8 @@ namespace Hackzilla\Bundle\TicketBundle\Manager; +use DateTime; +use DateInterval; use Doctrine\ORM\QueryBuilder; use Doctrine\Persistence\ObjectManager; use Hackzilla\Bundle\TicketBundle\Model\TicketInterface; @@ -25,11 +27,11 @@ final class TicketManager implements TicketManagerInterface use PermissionManagerTrait; use UserManagerTrait; - private $translator; + private ?TranslatorInterface $translator = null; - private $translationDomain = 'HackzillaTicketBundle'; + private string $translationDomain = 'HackzillaTicketBundle'; - private $objectManager; + private ?ObjectManager $objectManager = null; private $ticketRepository; @@ -58,11 +60,11 @@ public function setObjectManager(ObjectManager $objectManager): self { $this->objectManager = $objectManager; - if ($this->ticketClass) { + if ($this->ticketClass !== '' && $this->ticketClass !== '0') { $this->ticketRepository = $objectManager->getRepository($this->ticketClass); } - if ($this->ticketMessageClass) { + if ($this->ticketMessageClass !== '' && $this->ticketMessageClass !== '0') { $this->messageRepository = $objectManager->getRepository($this->ticketMessageClass); } @@ -106,7 +108,7 @@ public function createMessage(?TicketInterface $ticket = null) /* @var TicketMessageInterface $ticket */ $message = new $this->ticketMessageClass(); - if ($ticket) { + if ($ticket instanceof TicketInterface) { $message->setPriority($ticket->getPriority()); $message->setStatus($ticket->getStatus()); $message->setTicket($ticket); @@ -125,7 +127,7 @@ public function updateTicket(TicketInterface $ticket, ?TicketMessageInterface $m if (null === $ticket->getId()) { $this->objectManager->persist($ticket); } - if (null !== $message) { + if ($message instanceof TicketMessageInterface) { $message->setTicket($ticket); $this->objectManager->persist($message); $ticket->setPriority($message->getPriority()); @@ -136,7 +138,7 @@ public function updateTicket(TicketInterface $ticket, ?TicketMessageInterface $m /** * Delete a ticket from the database. */ - public function deleteTicket(TicketInterface $ticket) + public function deleteTicket(TicketInterface $ticket): void { $this->objectManager->remove($ticket); $this->objectManager->flush(); @@ -156,8 +158,6 @@ public function findTickets() * Find ticket in the database. * * @param int $ticketId - * - * @return ?TicketInterface */ public function getTicketById($ticketId): ?TicketInterface { @@ -226,8 +226,8 @@ public function getTicketListQuery($ticketStatus, $ticketPriority = null): Query */ public function getResolvedTicketOlderThan($days) { - $closeBeforeDate = new \DateTime(); - $closeBeforeDate->sub(new \DateInterval('P'.$days.'D')); + $closeBeforeDate = new DateTime(); + $closeBeforeDate->sub(new DateInterval('P'.$days.'D')); $query = $this->ticketRepository->createQueryBuilder('t') // ->select($this->ticketClass.' t') @@ -247,7 +247,7 @@ public function getResolvedTicketOlderThan($days) * * @return int */ - public function getTicketStatus($statusStr) + public function getTicketStatus($statusStr): int|string|false { static $statuses = false; @@ -269,7 +269,7 @@ public function getTicketStatus($statusStr) * * @return int */ - public function getTicketPriority($priorityStr) + public function getTicketPriority($priorityStr): int|string|false { static $priorities = false; diff --git a/Manager/UserManager.php b/Manager/UserManager.php index 64381f5..1e52423 100644 --- a/Manager/UserManager.php +++ b/Manager/UserManager.php @@ -13,6 +13,10 @@ namespace Hackzilla\Bundle\TicketBundle\Manager; +use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; +use InvalidArgumentException; +use LogicException; +use Exception; use Doctrine\Persistence\ObjectRepository; use Hackzilla\Bundle\TicketBundle\Model\TicketInterface; use Hackzilla\Bundle\TicketBundle\Model\UserInterface; @@ -23,10 +27,7 @@ final class UserManager implements UserManagerInterface { use PermissionManagerTrait; - /** - * @var ObjectRepository - */ - private $userRepository; + private ObjectRepository $userRepository; public function __construct( private TokenStorageInterface $tokenStorage, @@ -34,7 +35,7 @@ public function __construct( private AuthorizationCheckerInterface $authorizationChecker, ) { if (!is_subclass_of($userRepository->getClassName(), UserInterface::class)) { - throw new \InvalidArgumentException(sprintf('Argument 2 passed to "%s()" MUST be an object repository for a class implementing "%s".', __METHOD__, UserInterface::class)); + throw new InvalidArgumentException(sprintf('Argument 2 passed to "%s()" MUST be an object repository for a class implementing "%s".', __METHOD__, UserInterface::class)); } $this->userRepository = $userRepository; @@ -42,14 +43,14 @@ public function __construct( public function getCurrentUser(): ?UserInterface { - if (null === $this->tokenStorage->getToken()) { + if (!$this->tokenStorage->getToken() instanceof TokenInterface) { return null; } $user = $this->tokenStorage->getToken()->getUser(); - if (null !== $user && !$user instanceof UserInterface) { - throw new \LogicException(sprintf('The object representing the authenticated user MUST implement "%s".', UserInterface::class)); + if ($user instanceof \Symfony\Component\Security\Core\User\UserInterface && !$user instanceof UserInterface) { + throw new LogicException(sprintf('The object representing the authenticated user MUST implement "%s".', UserInterface::class)); } return $user; @@ -75,14 +76,11 @@ public function hasRole(?UserInterface $user, string $role): bool return $this->authorizationChecker->isGranted($role); } - /** - * @param ?UserInterface $user - */ public function hasPermission(?UserInterface $user, TicketInterface $ticket): bool { try { $this->getPermissionManager()->hasPermission($user, $ticket); - } catch (\Exception) { + } catch (Exception) { return false; } diff --git a/Model/MessageAttachmentInterface.php b/Model/MessageAttachmentInterface.php index 9058918..0e27c66 100644 --- a/Model/MessageAttachmentInterface.php +++ b/Model/MessageAttachmentInterface.php @@ -13,12 +13,13 @@ namespace Hackzilla\Bundle\TicketBundle\Model; +use Symfony\Component\HttpFoundation\File\UploadedFile; use Symfony\Component\HttpFoundation\File\File; interface MessageAttachmentInterface extends TicketMessageInterface { /** - * @param File|\Symfony\Component\HttpFoundation\File\UploadedFile $file + * @param File|UploadedFile $file * * @return $this */ diff --git a/Model/TicketInterface.php b/Model/TicketInterface.php index 922e164..ef6c9d5 100644 --- a/Model/TicketInterface.php +++ b/Model/TicketInterface.php @@ -13,6 +13,7 @@ namespace Hackzilla\Bundle\TicketBundle\Model; +use DateTimeInterface; use Doctrine\Common\Collections\Collection; interface TicketInterface @@ -73,7 +74,6 @@ public function getPriorityString(): ?string; /** * Set userCreated. * - * @param ?UserInterface $userCreated * * @return $this */ @@ -81,15 +81,12 @@ public function setUserCreated(?UserInterface $userCreated); /** * Get userCreated. - * - * @return ?UserInterface */ public function getUserCreated(): ?UserInterface; /** * Set lastUser. * - * @param ?UserInterface $lastUser * * @return $this */ @@ -105,24 +102,24 @@ public function getLastUser(): ?UserInterface; * * @return $this */ - public function setLastMessage(\DateTimeInterface $lastMessage); + public function setLastMessage(DateTimeInterface $lastMessage); /** * Get lastMessage. */ - public function getLastMessage(): ?\DateTimeInterface; + public function getLastMessage(): ?DateTimeInterface; /** * Set createdAt. * * @return $this */ - public function setCreatedAt(\DateTimeInterface $createdAt); + public function setCreatedAt(DateTimeInterface $createdAt); /** * Get createdAt. */ - public function getCreatedAt(): ?\DateTimeInterface; + public function getCreatedAt(): ?DateTimeInterface; /** * Set subject. diff --git a/Model/TicketMessageInterface.php b/Model/TicketMessageInterface.php index 6bba724..e824822 100644 --- a/Model/TicketMessageInterface.php +++ b/Model/TicketMessageInterface.php @@ -13,6 +13,8 @@ namespace Hackzilla\Bundle\TicketBundle\Model; +use DateTime; + interface TicketMessageInterface { public const STATUS_INVALID = 0; @@ -110,7 +112,6 @@ public function getPriorityString(): ?string; /** * Set user. * - * @param ?UserInterface $user * * @return $this */ @@ -140,12 +141,12 @@ public function getMessage(): ?string; * * @return $this */ - public function setCreatedAt(\DateTime $createdAt); + public function setCreatedAt(DateTime $createdAt); /** * Get createdAt. * - * @return \DateTime + * @return DateTime */ public function getCreatedAt(); diff --git a/Model/TicketMessageTrait.php b/Model/TicketMessageTrait.php index 07d11e2..2effc22 100644 --- a/Model/TicketMessageTrait.php +++ b/Model/TicketMessageTrait.php @@ -13,6 +13,8 @@ namespace Hackzilla\Bundle\TicketBundle\Model; +use DateTime; + /** * Ticket Message Trait. */ @@ -59,7 +61,7 @@ public function getStatus(): ?int */ public function getStatusString(): ?string { - if (!empty(TicketMessageInterface::STATUSES[$this->status])) { + if (isset(TicketMessageInterface::STATUSES[$this->status]) && (TicketMessageInterface::STATUSES[$this->status] !== '' && TicketMessageInterface::STATUSES[$this->status] !== '0')) { return TicketMessageInterface::STATUSES[$this->status]; } @@ -107,7 +109,7 @@ public function getPriority(): ?int */ public function getPriorityString(): ?string { - if (!empty(TicketMessageInterface::PRIORITIES[$this->priority])) { + if (isset(TicketMessageInterface::PRIORITIES[$this->priority]) && (TicketMessageInterface::PRIORITIES[$this->priority] !== '' && TicketMessageInterface::PRIORITIES[$this->priority] !== '0')) { return TicketMessageInterface::PRIORITIES[$this->priority]; } @@ -161,7 +163,7 @@ public function getMessage(): ?string * * @return $this */ - public function setCreatedAt(\DateTime $createdAt) + public function setCreatedAt(DateTime $createdAt) { $this->createdAt = $createdAt; @@ -171,7 +173,7 @@ public function setCreatedAt(\DateTime $createdAt) /** * Get createdAt. * - * @return \DateTime + * @return DateTime */ public function getCreatedAt() { @@ -189,7 +191,7 @@ public function setTicket(?TicketInterface $ticket = null) $user = $this->getUser(); // if null, then new ticket - if (null === $ticket->getUserCreated()) { + if (!$ticket->getUserCreated() instanceof UserInterface) { $ticket->setUserCreated($user); } diff --git a/Model/TicketTrait.php b/Model/TicketTrait.php index e6793de..1104611 100644 --- a/Model/TicketTrait.php +++ b/Model/TicketTrait.php @@ -13,6 +13,7 @@ namespace Hackzilla\Bundle\TicketBundle\Model; +use DateTimeInterface; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; @@ -120,7 +121,6 @@ public function getPriorityString(): ?string /** * Set userCreated. * - * @param ?UserInterface $userCreated * * @return $this */ @@ -133,8 +133,6 @@ public function setUserCreated(?UserInterface $userCreated) /** * Get userCreated. - * - * @return ?UserInterface */ public function getUserCreated(): ?UserInterface { @@ -144,7 +142,6 @@ public function getUserCreated(): ?UserInterface /** * Set lastUser. * - * @param ?UserInterface $lastUser * * @return $this */ @@ -157,8 +154,6 @@ public function setLastUser(?UserInterface $lastUser) /** * Get lastUser. - * - * @return ?UserInterface */ public function getLastUser(): ?UserInterface { @@ -170,7 +165,7 @@ public function getLastUser(): ?UserInterface * * @return $this */ - public function setLastMessage(\DateTimeInterface $lastMessage) + public function setLastMessage(DateTimeInterface $lastMessage) { $this->lastMessage = $lastMessage; @@ -180,7 +175,7 @@ public function setLastMessage(\DateTimeInterface $lastMessage) /** * Get lastMessage. */ - public function getLastMessage(): ?\DateTimeInterface + public function getLastMessage(): ?DateTimeInterface { return $this->lastMessage; } @@ -190,7 +185,7 @@ public function getLastMessage(): ?\DateTimeInterface * * @return $this */ - public function setCreatedAt(\DateTimeInterface $createdAt) + public function setCreatedAt(DateTimeInterface $createdAt) { $this->createdAt = $createdAt; @@ -200,7 +195,7 @@ public function setCreatedAt(\DateTimeInterface $createdAt) /** * Get createdAt. */ - public function getCreatedAt(): ?\DateTimeInterface + public function getCreatedAt(): ?DateTimeInterface { return $this->createdAt; } diff --git a/Model/UserInterface.php b/Model/UserInterface.php index dca43d2..2e57379 100644 --- a/Model/UserInterface.php +++ b/Model/UserInterface.php @@ -13,11 +13,12 @@ namespace Hackzilla\Bundle\TicketBundle\Model; +use Symfony\Component\HttpKernel\Kernel; use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface; use Symfony\Component\Security\Core\User\UserInterface as BaseUserInterface; /* @phpstan-ignore-next-line */ -if (\Symfony\Component\HttpKernel\Kernel::MAJOR_VERSION < 5) { +if (Kernel::MAJOR_VERSION < 5) { interface UserInterface extends BaseUserInterface { public function __toString(): string; diff --git a/Resources/config/commands.php b/Resources/config/commands.php index 11aeaa3..57e1780 100644 --- a/Resources/config/commands.php +++ b/Resources/config/commands.php @@ -24,9 +24,6 @@ $containerConfigurator->services() ->set('hackzilla_ticket.command.autoclosing', AutoClosingCommand::class) - ->tag('console.command', [ - 'command' => 'ticket:autoclosing', - ]) ->args([ new ReferenceConfigurator(TicketManagerInterface::class), new ReferenceConfigurator(UserManagerInterface::class), @@ -35,9 +32,6 @@ ]) ->set('hackzilla_ticket.command.create', TicketManagerCommand::class) - ->tag('console.command', [ - 'command' => 'ticket:create', - ]) ->args([ new ReferenceConfigurator(TicketManagerInterface::class), new ReferenceConfigurator(UserManagerInterface::class), diff --git a/Resources/config/controllers.php b/Resources/config/controllers.php index b42bbf0..29487cd 100644 --- a/Resources/config/controllers.php +++ b/Resources/config/controllers.php @@ -10,7 +10,7 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ - +use Vich\UploaderBundle\Handler\DownloadHandler; use Hackzilla\Bundle\TicketBundle\Controller\TicketAttachmentController; use Hackzilla\Bundle\TicketBundle\Controller\TicketController; use Hackzilla\Bundle\TicketBundle\Manager\TicketManagerInterface; @@ -22,7 +22,7 @@ // Use "service" function for creating references to services when dropping support for Symfony 4.4 // Use "param" function for creating references to parameters when dropping support for Symfony 5.1 - if (class_exists(\Vich\UploaderBundle\Handler\DownloadHandler::class)) { + if (class_exists(DownloadHandler::class)) { $container->services() ->set(TicketAttachmentController::class) ->args([ diff --git a/Resources/config/event_listener.php b/Resources/config/event_listener.php index b854777..37e2737 100644 --- a/Resources/config/event_listener.php +++ b/Resources/config/event_listener.php @@ -20,6 +20,5 @@ $containerConfigurator->services() ->set('hackzilla_ticket.file_upload_subscriber', FileSubscriber::class) - ->tag('kernel.event_subscriber') ; }; diff --git a/Resources/config/maker.php b/Resources/config/maker.php index 813e9ce..47abef1 100644 --- a/Resources/config/maker.php +++ b/Resources/config/maker.php @@ -10,7 +10,8 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ - +use Hackzilla\Bundle\TicketBundle\Maker\TicketMaker; +use Hackzilla\Bundle\TicketBundle\Maker\MessageMaker; use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; use Symfony\Component\DependencyInjection\Loader\Configurator\ReferenceConfigurator; @@ -19,7 +20,7 @@ // Use "param" function for creating references to parameters when dropping support for Symfony 5.1 $containerConfigurator->services() - ->set('hackzilla_ticket.maker.ticket', \Hackzilla\Bundle\TicketBundle\Maker\TicketMaker::class) + ->set('hackzilla_ticket.maker.ticket', TicketMaker::class) ->args([ new ReferenceConfigurator('maker.file_manager'), new ReferenceConfigurator('maker.doctrine_helper'), @@ -27,7 +28,7 @@ ]) ->tag('maker.command') - ->set('hackzilla_ticket.maker.message', \Hackzilla\Bundle\TicketBundle\Maker\MessageMaker::class) + ->set('hackzilla_ticket.maker.message', MessageMaker::class) ->args([ new ReferenceConfigurator('maker.file_manager'), new ReferenceConfigurator('maker.doctrine_helper'), diff --git a/Resources/config/twig.php b/Resources/config/twig.php index 349fff8..f9de4ac 100644 --- a/Resources/config/twig.php +++ b/Resources/config/twig.php @@ -22,13 +22,11 @@ $containerConfigurator->services() ->set('hackzilla_ticket.component.twig_extension.ticket_features', TicketFeatureExtension::class) - ->tag('twig.extension') ->args([ new ReferenceConfigurator('hackzilla_ticket.features'), ]) ->set('hackzilla_ticket.component.twig_extension.ticket_global', TicketGlobalExtension::class) - ->tag('twig.extension') ->args([ '%hackzilla_ticket.templates%', ]) diff --git a/Tests/Component/TicketFeaturesTest.php b/Tests/Component/TicketFeaturesTest.php index 269f617..fc9148c 100644 --- a/Tests/Component/TicketFeaturesTest.php +++ b/Tests/Component/TicketFeaturesTest.php @@ -13,6 +13,8 @@ namespace Hackzilla\Bundle\TicketBundle\Tests\Extension; +use Iterator; +use stdClass; use Hackzilla\Bundle\TicketBundle\Component\TicketFeatures; use Hackzilla\Bundle\TicketBundle\Tests\Fixtures\Entity\TicketMessage; use Hackzilla\Bundle\TicketBundle\Tests\Fixtures\Entity\TicketMessageWithAttachment; @@ -22,28 +24,23 @@ final class TicketFeaturesTest extends WebTestCase { /** * @dataProvider constructProvider - * - * @param string $class */ - public function testConstruct(array $features, $class) + public function testConstruct(array $features, string $class): void { $this->assertInstanceOf(TicketFeatures::class, new TicketFeatures($features, $class)); } - public function constructProvider() + public function constructProvider(): Iterator { - return [ - [[], \stdClass::class], - ]; + yield [[], stdClass::class]; } /** * @dataProvider featureAttachmentProvider * - * @param string $class * @param bool|null $compare */ - public function testFeatureAttachment(array $features, $class, $compare) + public function testFeatureAttachment(array $features, string $class, bool $compare): void { $obj = new TicketFeatures($features, $class); @@ -51,12 +48,10 @@ public function testFeatureAttachment(array $features, $class, $compare) $this->assertSame($obj->hasFeature('attachment'), $compare); } - public function featureAttachmentProvider() + public function featureAttachmentProvider(): Iterator { - return [ - [[], TicketMessage::class, false], - [['attachment' => true], TicketMessage::class, false], - [['attachment' => true], TicketMessageWithAttachment::class, true], - ]; + yield [[], TicketMessage::class, false]; + yield [['attachment' => true], TicketMessage::class, false]; + yield [['attachment' => true], TicketMessageWithAttachment::class, true]; } } diff --git a/Tests/DependencyInjection/ConfigurationTest.php b/Tests/DependencyInjection/ConfigurationTest.php index 0a49194..a753e12 100644 --- a/Tests/DependencyInjection/ConfigurationTest.php +++ b/Tests/DependencyInjection/ConfigurationTest.php @@ -18,7 +18,7 @@ final class ConfigurationTest extends WebTestCase { - private $object; + private ?Configuration $object = null; protected function setUp(): void { @@ -30,7 +30,7 @@ protected function tearDown(): void $this->object = null; } - public function testObjectCreated() + public function testObjectCreated(): void { $this->assertInstanceOf(Configuration::class, $this->object); } diff --git a/Tests/DependencyInjection/HackzillaTicketExtensionTest.php b/Tests/DependencyInjection/HackzillaTicketExtensionTest.php index a281c6e..ff5b117 100644 --- a/Tests/DependencyInjection/HackzillaTicketExtensionTest.php +++ b/Tests/DependencyInjection/HackzillaTicketExtensionTest.php @@ -18,7 +18,7 @@ class HackzillaTicketExtensionTest extends WebTestCase { - private $object; + private ?HackzillaTicketExtension $object = null; protected function setUp(): void { diff --git a/Tests/Fixtures/Entity/Ticket.php b/Tests/Fixtures/Entity/Ticket.php index e2efd96..5f2ef6c 100644 --- a/Tests/Fixtures/Entity/Ticket.php +++ b/Tests/Fixtures/Entity/Ticket.php @@ -13,6 +13,10 @@ namespace Hackzilla\Bundle\TicketBundle\Tests\Fixtures\Entity; +use Doctrine\DBAL\Types\Types; +use DateTimeInterface; +use Doctrine\Common\Collections\Collection; +use DateTime; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\ORM\Mapping as ORM; use Hackzilla\Bundle\TicketBundle\Model\TicketInterface; @@ -29,36 +33,39 @@ class Ticket implements TicketInterface #[ORM\Id] #[ORM\GeneratedValue] - #[ORM\Column(type: 'integer')] - private $id; + #[ORM\Column(type: Types::INTEGER)] + private ?int $id = null; - #[ORM\Column(type: 'datetime', nullable: false)] - private $lastMessage; + #[ORM\Column(type: Types::DATETIME_MUTABLE, nullable: false)] + private DateTimeInterface $lastMessage; - #[ORM\Column(type: 'text', nullable: false)] - private $subject; + #[ORM\Column(type: Types::TEXT, nullable: false)] + private string $subject; - #[ORM\Column(type: 'integer', nullable: false)] - private $status; + #[ORM\Column(type: Types::INTEGER, nullable: false)] + private int $status; - #[ORM\Column(type: 'integer', nullable: false)] - private $priority; + #[ORM\Column(type: Types::INTEGER, nullable: false)] + private int $priority; - #[ORM\Column(type: 'datetime', nullable: false)] - private $createdAt; + #[ORM\Column(type: Types::DATETIME_MUTABLE, nullable: false)] + private DateTimeInterface $createdAt; + /** + * @var Collection + */ #[ORM\OneToMany(mappedBy: 'ticket', targetEntity: TicketMessage::class)] - private $messages; + private Collection $messages; #[ORM\ManyToOne(targetEntity: User::class)] - private $userCreated; + private ?User $userCreated = null; #[ORM\ManyToOne(targetEntity: User::class)] - private $lastUser; + private ?User $lastUser = null; public function __construct() { - $this->createdAt = new \DateTime(); + $this->createdAt = new DateTime(); $this->messages = new ArrayCollection(); } diff --git a/Tests/Fixtures/Entity/TicketMessage.php b/Tests/Fixtures/Entity/TicketMessage.php index b498f78..139e7b0 100644 --- a/Tests/Fixtures/Entity/TicketMessage.php +++ b/Tests/Fixtures/Entity/TicketMessage.php @@ -13,6 +13,9 @@ namespace Hackzilla\Bundle\TicketBundle\Tests\Fixtures\Entity; +use Doctrine\DBAL\Types\Types; +use DateTimeInterface; +use DateTime; use Doctrine\ORM\Mapping as ORM; use Hackzilla\Bundle\TicketBundle\Model\TicketMessageInterface; use Hackzilla\Bundle\TicketBundle\Model\TicketMessageTrait; @@ -28,31 +31,31 @@ class TicketMessage implements TicketMessageInterface #[ORM\Id] #[ORM\GeneratedValue] - #[ORM\Column(type: 'integer')] - private $id; + #[ORM\Column(type: Types::INTEGER)] + private ?int $id = null; - #[ORM\Column(type: 'text', nullable: true)] - private $message; + #[ORM\Column(type: Types::TEXT, nullable: true)] + private ?string $message = null; - #[ORM\Column(type: 'integer', nullable: false)] - private $status; + #[ORM\Column(type: Types::INTEGER, nullable: false)] + private int $status; - #[ORM\Column(type: 'integer', nullable: false)] - private $priority; + #[ORM\Column(type: Types::INTEGER, nullable: false)] + private int $priority; - #[ORM\Column(type: 'datetime', nullable: false)] - private $createdAt; + #[ORM\Column(type: Types::DATETIME_MUTABLE, nullable: false)] + private DateTimeInterface $createdAt; #[ORM\ManyToOne(targetEntity: Ticket::class, inversedBy: 'messages')] #[ORM\JoinColumn(nullable: false)] - private $ticket; + private ?Ticket $ticket = null; #[ORM\ManyToOne(targetEntity: User::class)] - private $user; + private ?User $user = null; public function __construct() { - $this->createdAt = new \DateTime(); + $this->createdAt = new DateTime(); } public function getId(): ?int diff --git a/Tests/Fixtures/Entity/TicketMessageWithAttachment.php b/Tests/Fixtures/Entity/TicketMessageWithAttachment.php index ca27d62..327b90f 100644 --- a/Tests/Fixtures/Entity/TicketMessageWithAttachment.php +++ b/Tests/Fixtures/Entity/TicketMessageWithAttachment.php @@ -13,6 +13,9 @@ namespace Hackzilla\Bundle\TicketBundle\Tests\Fixtures\Entity; +use Doctrine\DBAL\Types\Types; +use DateTimeInterface; +use DateTime; use Doctrine\ORM\Mapping as ORM; use Hackzilla\Bundle\TicketBundle\Model\MessageAttachmentInterface; use Hackzilla\Bundle\TicketBundle\Model\MessageAttachmentTrait; @@ -31,40 +34,40 @@ class TicketMessageWithAttachment implements TicketMessageInterface, MessageAtta #[ORM\Id] #[ORM\GeneratedValue] - #[ORM\Column(type: 'integer')] - private $id; + #[ORM\Column(type: Types::INTEGER)] + private ?int $id = null; - #[ORM\Column(type: 'text', nullable: true)] - private $message; + #[ORM\Column(type: Types::TEXT, nullable: true)] + private ?string $message = null; - #[ORM\Column(type: 'integer', nullable: false)] - private $status; + #[ORM\Column(type: Types::INTEGER, nullable: false)] + private int $status; - #[ORM\Column(type: 'integer', nullable: false)] - private $priority; + #[ORM\Column(type: Types::INTEGER, nullable: false)] + private int $priority; - #[ORM\Column(type: 'datetime', nullable: false)] - private $createdAt; + #[ORM\Column(type: Types::DATETIME_MUTABLE, nullable: false)] + private DateTimeInterface $createdAt; - #[ORM\Column(type: 'string', length: 255, nullable: true)] - private $attachmentName; + #[ORM\Column(type: Types::STRING, length: 255, nullable: true)] + private ?string $attachmentName = null; - #[ORM\Column(type: 'integer', nullable: true)] - private $attachmentSize; + #[ORM\Column(type: Types::INTEGER, nullable: true)] + private ?int $attachmentSize = null; - #[ORM\Column(type: 'string', length: 255, nullable: true)] - private $attachmentMimeType; + #[ORM\Column(type: Types::STRING, length: 255, nullable: true)] + private ?string $attachmentMimeType = null; #[ORM\ManyToOne(targetEntity: Ticket::class, inversedBy: 'messages')] #[ORM\JoinColumn(nullable: false)] - private $ticket; + private ?Ticket $ticket = null; #[ORM\ManyToOne(targetEntity: User::class)] - private $user; + private ?User $user = null; public function __construct() { - $this->createdAt = new \DateTime(); + $this->createdAt = new DateTime(); } public function getId(): ?int diff --git a/Tests/Fixtures/Entity/User.php b/Tests/Fixtures/Entity/User.php index 10eebc5..ecad122 100644 --- a/Tests/Fixtures/Entity/User.php +++ b/Tests/Fixtures/Entity/User.php @@ -13,6 +13,7 @@ namespace Hackzilla\Bundle\TicketBundle\Tests\Fixtures\Entity; +use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping as ORM; use Hackzilla\Bundle\TicketBundle\Model\UserInterface as TicketBundleUserInterface; @@ -26,17 +27,17 @@ class User implements TicketBundleUserInterface { #[ORM\Id] #[ORM\GeneratedValue] - #[ORM\Column(type: 'integer')] - private $id; + #[ORM\Column(type: Types::INTEGER)] + private ?int $id = null; - #[ORM\Column(type: 'string', length: 180, unique: true)] - private $email; + #[ORM\Column(type: Types::STRING, length: 180, unique: true)] + private ?string $email = null; - #[ORM\Column(type: 'json')] + #[ORM\Column(type: Types::JSON)] private $roles = []; - #[ORM\Column(type: 'string')] - private $password; + #[ORM\Column(type: Types::STRING)] + private ?string $password = null; public function __toString(): string { @@ -126,7 +127,7 @@ public function getSalt(): ?string /** * @see UserInterface */ - public function eraseCredentials() + public function eraseCredentials(): void { // If you store any temporary, sensitive data on the user, clear it here // $this->plainPassword = null; diff --git a/Tests/Form/DataTransformer/StatusTransformerTest.php b/Tests/Form/DataTransformer/StatusTransformerTest.php index 800d9fd..0397780 100644 --- a/Tests/Form/DataTransformer/StatusTransformerTest.php +++ b/Tests/Form/DataTransformer/StatusTransformerTest.php @@ -20,7 +20,7 @@ class StatusTransformerTest extends WebTestCase { - private $object; + private ?StatusTransformer $object = null; protected function setUp(): void { diff --git a/Tests/Form/Type/PriorityTypeTest.php b/Tests/Form/Type/PriorityTypeTest.php index 767d424..959d578 100644 --- a/Tests/Form/Type/PriorityTypeTest.php +++ b/Tests/Form/Type/PriorityTypeTest.php @@ -18,7 +18,7 @@ class PriorityTypeTest extends TypeTestCase { - private $object; + private ?PriorityType $object = null; protected function setUp(): void { diff --git a/Tests/Form/Type/StatusTypeTest.php b/Tests/Form/Type/StatusTypeTest.php index ba00967..814016b 100644 --- a/Tests/Form/Type/StatusTypeTest.php +++ b/Tests/Form/Type/StatusTypeTest.php @@ -18,7 +18,7 @@ class StatusTypeTest extends TypeTestCase { - private $object; + private ?StatusType $object = null; protected function setUp(): void { diff --git a/Tests/Form/Type/TicketMessageTypeTest.php b/Tests/Form/Type/TicketMessageTypeTest.php index 7fcfca9..0ceea6f 100644 --- a/Tests/Form/Type/TicketMessageTypeTest.php +++ b/Tests/Form/Type/TicketMessageTypeTest.php @@ -13,6 +13,7 @@ namespace Hackzilla\Bundle\TicketBundle\Tests\Form\Type; +use PHPUnit\Framework\MockObject\MockObject; use Hackzilla\Bundle\TicketBundle\Component\TicketFeatures; use Hackzilla\Bundle\TicketBundle\Form\Type\TicketMessageType; use Hackzilla\Bundle\TicketBundle\Manager\UserManagerInterface; @@ -23,16 +24,16 @@ class TicketMessageTypeTest extends TypeTestCase { - private $user; + private MockObject $user; protected function setUp(): void { - $this->user = $this->getMockBuilder(UserManagerInterface::class)->getMock(); + $this->user = $this->createMock(UserManagerInterface::class); parent::setUp(); } - public function testSubmitValidData() + public function testSubmitValidData(): void { $formData = [ 'priority' => TicketMessageInterface::PRIORITY_HIGH, diff --git a/Tests/Form/Type/TicketTypeTest.php b/Tests/Form/Type/TicketTypeTest.php index 255fc44..6c0cf73 100644 --- a/Tests/Form/Type/TicketTypeTest.php +++ b/Tests/Form/Type/TicketTypeTest.php @@ -13,6 +13,7 @@ namespace Hackzilla\Bundle\TicketBundle\Tests\Form\Type; +use PHPUnit\Framework\MockObject\MockObject; use Hackzilla\Bundle\TicketBundle\Component\TicketFeatures; use Hackzilla\Bundle\TicketBundle\Form\Type\TicketMessageType; use Hackzilla\Bundle\TicketBundle\Form\Type\TicketType; @@ -24,7 +25,7 @@ class TicketTypeTest extends TypeTestCase { - private $user; + private MockObject $user; protected function setUp(): void { @@ -33,7 +34,7 @@ protected function setUp(): void parent::setUp(); } - public function testSubmitValidData() + public function testSubmitValidData(): void { $formData = []; diff --git a/Tests/Functional/Command/ApplicationTest.php b/Tests/Functional/Command/ApplicationTest.php index ec5e536..c4bc114 100644 --- a/Tests/Functional/Command/ApplicationTest.php +++ b/Tests/Functional/Command/ApplicationTest.php @@ -13,6 +13,7 @@ namespace Hackzilla\Bundle\TicketBundle\Tests\Functional\Command; +use Iterator; use Hackzilla\Bundle\TicketBundle\Command\AutoClosingCommand; use Hackzilla\Bundle\TicketBundle\Command\TicketManagerCommand; use Hackzilla\Bundle\TicketBundle\Tests\Functional\WebTestCase; @@ -25,22 +26,17 @@ final class ApplicationTest extends WebTestCase { /** * @dataProvider getCommands - * - * @param string $expectedClass - * @param string $commandName */ - public function testCommandRegistration($expectedClass, $commandName) + public function testCommandRegistration(string $expectedClass, string $commandName): void { $application = new Application(static::$kernel); $this->assertInstanceOf($expectedClass, $application->find($commandName)); } - public function getCommands() + public function getCommands(): Iterator { - return [ - [AutoClosingCommand::class, 'ticket:autoclosing'], - [TicketManagerCommand::class, 'ticket:create'], - ]; + yield [AutoClosingCommand::class, 'ticket:autoclosing']; + yield [TicketManagerCommand::class, 'ticket:create']; } } diff --git a/Tests/Functional/FunctionalTest.php b/Tests/Functional/FunctionalTest.php index b8c0e00..a44ac8e 100644 --- a/Tests/Functional/FunctionalTest.php +++ b/Tests/Functional/FunctionalTest.php @@ -13,6 +13,7 @@ namespace Hackzilla\Bundle\TicketBundle\Tests\Functional; +use Iterator; use Hackzilla\Bundle\TicketBundle\Manager\TicketManagerInterface; use Hackzilla\Bundle\TicketBundle\Tests\Fixtures\Entity\Ticket; use Hackzilla\Bundle\TicketBundle\Tests\Fixtures\Entity\TicketMessage; @@ -29,30 +30,27 @@ class FunctionalTest extends WebTestCase /** * @dataProvider getParameters */ - public function testConfiguredParameter($parameter, $value): void + public function testConfiguredParameter(string $parameter, string|array $value): void { $this->assertTrue(static::$kernel->getContainer()->hasParameter($parameter)); $this->assertSame($value, static::$kernel->getContainer()->getParameter($parameter)); } - public function getParameters(): array + public function getParameters(): Iterator { - $messageCLass = !class_exists(VichUploaderBundle::class) ? TicketMessage::class : TicketMessageWithAttachment::class; - - return [ - ['hackzilla_ticket.model.user.class', User::class], - ['hackzilla_ticket.model.ticket.class', Ticket::class], - ['hackzilla_ticket.model.message.class', $messageCLass], - ['hackzilla_ticket.features', ['attachment' => true]], - ['hackzilla_ticket.templates', [ - 'index' => '@HackzillaTicket/Ticket/index.html.twig', - 'new' => '@HackzillaTicket/Ticket/new.html.twig', - 'prototype' => '@HackzillaTicket/Ticket/prototype.html.twig', - 'show' => '@HackzillaTicket/Ticket/show.html.twig', - 'show_attachment' => '@HackzillaTicket/Ticket/show_attachment.html.twig', - 'macros' => '@HackzillaTicket/Macros/macros.html.twig', - ]], - ]; + $messageCLass = class_exists(VichUploaderBundle::class) ? TicketMessageWithAttachment::class : TicketMessage::class; + yield ['hackzilla_ticket.model.user.class', User::class]; + yield ['hackzilla_ticket.model.ticket.class', Ticket::class]; + yield ['hackzilla_ticket.model.message.class', $messageCLass]; + yield ['hackzilla_ticket.features', ['attachment' => true]]; + yield ['hackzilla_ticket.templates', [ + 'index' => '@HackzillaTicket/Ticket/index.html.twig', + 'new' => '@HackzillaTicket/Ticket/new.html.twig', + 'prototype' => '@HackzillaTicket/Ticket/prototype.html.twig', + 'show' => '@HackzillaTicket/Ticket/show.html.twig', + 'show_attachment' => '@HackzillaTicket/Ticket/show_attachment.html.twig', + 'macros' => '@HackzillaTicket/Macros/macros.html.twig', + ]]; } public function testConfiguredTicketManager(): void diff --git a/Tests/Functional/TestKernel.php b/Tests/Functional/TestKernel.php index 02c623b..9402e83 100644 --- a/Tests/Functional/TestKernel.php +++ b/Tests/Functional/TestKernel.php @@ -31,7 +31,7 @@ use Symfony\Component\Routing\RouteCollectionBuilder; use Vich\UploaderBundle\VichUploaderBundle; -if (\Symfony\Component\HttpKernel\Kernel::MAJOR_VERSION >= 5) { +if (Kernel::MAJOR_VERSION >= 5) { trait ConfigureRoutes { protected function configureRoutes(RoutingConfigurator $routes): void @@ -69,7 +69,7 @@ protected function configureRoutes(RouteCollectionBuilder $routes) trait KernelDirectories { - public function getCacheDir() + public function getCacheDir(): string { return $this->getBaseDir().'cache'; } @@ -77,7 +77,7 @@ public function getCacheDir() /** * {@inheritdoc} */ - public function getLogDir() + public function getLogDir(): string { return $this->getBaseDir().'log'; } @@ -96,7 +96,7 @@ final class TestKernel extends Kernel KernelDirectories::getLogDir insteadof MicroKernelTrait; } - private $useVichUploaderBundle = false; + private bool $useVichUploaderBundle; public function __construct() { @@ -152,11 +152,6 @@ protected function configureContainer(ContainerBuilder $c, LoaderInterface $load 'test' => true, ]; - if (version_compare(self::VERSION, '5.1', '>=') && version_compare(self::VERSION, '6.0', '<')) { - $frameworkConfig['session'] = ['storage_factory_id' => 'session.storage.factory.native']; - $frameworkConfig['router'] = ['utf8' => true]; - } - $c->loadFromExtension('framework', $frameworkConfig); // SecurityBundle config @@ -166,11 +161,6 @@ protected function configureContainer(ContainerBuilder $c, LoaderInterface $load 'provider' => 'in_memory', ], ]; - - // "logout_on_user_change" configuration was marked as mandatory since version 3.4 and deprecated as of 4.1. - if (version_compare(self::VERSION, '3.4', '>=') && version_compare(self::VERSION, '4.1', '<')) { - $mainFirewallConfig['logout_on_user_change'] = true; - } $securityConfig = [ 'providers' => [ 'in_memory' => [ @@ -182,10 +172,6 @@ protected function configureContainer(ContainerBuilder $c, LoaderInterface $load ], ]; - if (version_compare(self::VERSION, '5.3', '>=') && version_compare(self::VERSION, '7.0', '<')) { - $securityConfig['enable_authenticator_manager'] = true; - } - $c->loadFromExtension('security', $securityConfig); // DoctrineBundle config @@ -218,9 +204,7 @@ protected function configureContainer(ContainerBuilder $c, LoaderInterface $load 'autoescape' => 'name', ]; // "default_path" configuration is available since version 3.4. - if (version_compare(self::VERSION, '3.4', '>=')) { - $twigConfig['default_path'] = __DIR__.'/Resources/views'; - } + $twigConfig['default_path'] = __DIR__.'/Resources/views'; $c->loadFromExtension('twig', $twigConfig); // HackzillaBundle config @@ -244,7 +228,7 @@ protected function configureContainer(ContainerBuilder $c, LoaderInterface $load } } - private function getBaseDir() + private function getBaseDir(): string { return sys_get_temp_dir().'/hackzilla-ticket-bundle/var/'.(int) $this->useVichUploaderBundle.'/'; } diff --git a/Tests/Functional/WebTestCase.php b/Tests/Functional/WebTestCase.php index 2f846fc..a6ff163 100644 --- a/Tests/Functional/WebTestCase.php +++ b/Tests/Functional/WebTestCase.php @@ -13,10 +13,11 @@ namespace Hackzilla\Bundle\TicketBundle\Tests\Functional; +use Symfony\Component\HttpKernel\Kernel; use Symfony\Bundle\FrameworkBundle\Test\WebTestCase as BaseWebTestCase; use Symfony\Component\HttpKernel\KernelInterface; -if (\Symfony\Component\HttpKernel\Kernel::MAJOR_VERSION >= 6) { +if (Kernel::MAJOR_VERSION >= 6) { trait CreateKernel { protected static function createKernel(array $options = []): KernelInterface @@ -30,7 +31,7 @@ trait CreateKernel /** * @return KernelInterface */ - protected static function createKernel(array $options = []) + protected static function createKernel(array $options = []): TestKernel { return new TestKernel(); } diff --git a/Tests/Manager/UserManagerTest.php b/Tests/Manager/UserManagerTest.php index 3fa06dc..dd99b20 100644 --- a/Tests/Manager/UserManagerTest.php +++ b/Tests/Manager/UserManagerTest.php @@ -13,6 +13,7 @@ namespace Hackzilla\Bundle\TicketBundle\Tests\User; +use PHPUnit\Framework\MockObject\MockObject; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityRepository; use Doctrine\ORM\Mapping\ClassMetadata; @@ -24,17 +25,15 @@ class UserManagerTest extends WebTestCase { - private $object; - - private $tokenStorage; + private ?UserManager $object = null; protected function setUp(): void { self::bootKernel(); - $this->tokenStorage = new TokenStorage(); + $tokenStorage = new TokenStorage(); $this->object = new UserManager( - $this->tokenStorage, + $tokenStorage, $this->getMockUserRepository(), $this->getAuthorizationChecker(), ); @@ -57,7 +56,7 @@ private function getMockUserRepository(): EntityRepository return new EntityRepository($em, new ClassMetadata(User::class)); } - private function getAuthorizationChecker() + private function getAuthorizationChecker(): MockObject { return $this->createMock(AuthorizationChecker::class); } diff --git a/Tests/TwigExtension/TicketFeaturesTest.php b/Tests/TwigExtension/TicketFeaturesTest.php index 4ed1294..2e7d96d 100644 --- a/Tests/TwigExtension/TicketFeaturesTest.php +++ b/Tests/TwigExtension/TicketFeaturesTest.php @@ -19,7 +19,7 @@ class TicketFeaturesTest extends WebTestCase { - private $object; + private ?TicketFeatureExtension $object = null; protected function setUp(): void { diff --git a/Tests/bootstrap.php b/Tests/bootstrap.php index 35202bc..dff9154 100644 --- a/Tests/bootstrap.php +++ b/Tests/bootstrap.php @@ -16,5 +16,5 @@ } elseif (is_file($autoloadFile = __DIR__.'/../vendor/autoload.php')) { $loader = require $autoloadFile; } else { - throw new \LogicException('Run "composer install --dev" to create autoloader.'); + throw new LogicException('Run "composer install --dev" to create autoloader.'); } diff --git a/TwigExtension/TicketFeatureExtension.php b/TwigExtension/TicketFeatureExtension.php index a8574fc..3951192 100644 --- a/TwigExtension/TicketFeatureExtension.php +++ b/TwigExtension/TicketFeatureExtension.php @@ -38,7 +38,7 @@ public function hasFeature(string $feature): ?bool /** * {@inheritdoc} */ - public function getName() + public function getName(): string { return 'ticketFeature'; } diff --git a/TwigExtension/TicketGlobalExtension.php b/TwigExtension/TicketGlobalExtension.php index 9ca5e7d..6833f8d 100644 --- a/TwigExtension/TicketGlobalExtension.php +++ b/TwigExtension/TicketGlobalExtension.php @@ -38,10 +38,7 @@ public function getGlobals(): array ]; } - /** - * @return string - */ - public function getName() + public function getName(): string { return 'ticketGlobal'; } diff --git a/composer.json b/composer.json index 1abaa7d..63e8967 100644 --- a/composer.json +++ b/composer.json @@ -52,6 +52,7 @@ "friendsofphp/php-cs-fixer": "^3.0", "phpstan/phpstan": "^1.3", "phpunit/phpunit": "^9.5", + "rector/rector": "^1.2", "symfony/maker-bundle": "^1.61", "symfony/phpunit-bridge": "^7.0", "symfony/test-pack": "^1.0" diff --git a/rector.php b/rector.php new file mode 100644 index 0000000..e09ff69 --- /dev/null +++ b/rector.php @@ -0,0 +1,27 @@ +withPaths([__DIR__]) + ->withSkip([__DIR__ . '/vendor']) + // uncomment to reach your current PHP version +// ->withTypeCoverageLevel(0) + ->withPhpSets(php83: true) + ->withPreparedSets(deadCode: true, codeQuality: true, typeDeclarations: true, doctrineCodeQuality: true, symfonyCodeQuality: true, symfonyConfigs: true, twig: true, phpunit: true) + ->withImportNames(importNames: true, removeUnusedImports: true) + ->withSets([ + LevelSetList::UP_TO_PHP_74, + DoctrineSetList::ANNOTATIONS_TO_ATTRIBUTES, + SymfonySetList::ANNOTATIONS_TO_ATTRIBUTES, + SymfonySetList::SYMFONY_CONSTRUCTOR_INJECTION, + SetList::TYPE_DECLARATION, + PHPUnitSetList::PHPUNIT_CODE_QUALITY, + ]); From 7ffbf97574aeab0fcdbbf1a8b2ba3788896556b6 Mon Sep 17 00:00:00 2001 From: Regis Grison Date: Tue, 5 Nov 2024 07:48:30 +0100 Subject: [PATCH 05/18] fix A void function must not return a value --- Maker/MessageMaker.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Maker/MessageMaker.php b/Maker/MessageMaker.php index c3df535..0ae3aa3 100644 --- a/Maker/MessageMaker.php +++ b/Maker/MessageMaker.php @@ -51,7 +51,7 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen { $this->hasAttachment = $input->getOption('attachment'); - return parent::generate($input, $io, $generator); + parent::generate($input, $io, $generator); } protected function fields(): array From dca3450391c1cb91c876bb6d0745ab2bfd34059b Mon Sep 17 00:00:00 2001 From: Regis Grison Date: Tue, 5 Nov 2024 08:19:05 +0100 Subject: [PATCH 06/18] fix method that had "Action" postfix removed --- Resources/config/routing/hackzilla_ticket.xml | 14 +++++++------- Resources/config/routing/ticket.yml | 14 +++++++------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/Resources/config/routing/hackzilla_ticket.xml b/Resources/config/routing/hackzilla_ticket.xml index 632b5bb..b950039 100644 --- a/Resources/config/routing/hackzilla_ticket.xml +++ b/Resources/config/routing/hackzilla_ticket.xml @@ -1,10 +1,10 @@ - - - - - - - + + + + + + + diff --git a/Resources/config/routing/ticket.yml b/Resources/config/routing/ticket.yml index 631b480..12233b4 100644 --- a/Resources/config/routing/ticket.yml +++ b/Resources/config/routing/ticket.yml @@ -1,30 +1,30 @@ # NEXT_MAJOR: remove this file and add upgrade note. hackzilla_ticket: path: / - controller: 'Hackzilla\Bundle\TicketBundle\Controller\TicketController::indexAction' + controller: 'Hackzilla\Bundle\TicketBundle\Controller\TicketController::index' hackzilla_ticket_show: path: /{ticketId}/show - controller: 'Hackzilla\Bundle\TicketBundle\Controller\TicketController::showAction' + controller: 'Hackzilla\Bundle\TicketBundle\Controller\TicketController::show' hackzilla_ticket_new: path: /new - controller: 'Hackzilla\Bundle\TicketBundle\Controller\TicketController::newAction' + controller: 'Hackzilla\Bundle\TicketBundle\Controller\TicketController::new' hackzilla_ticket_create: path: /create - controller: 'Hackzilla\Bundle\TicketBundle\Controller\TicketController::createAction' + controller: 'Hackzilla\Bundle\TicketBundle\Controller\TicketController::create' methods: post hackzilla_ticket_delete: path: /{ticketId}/delete - controller: 'Hackzilla\Bundle\TicketBundle\Controller\TicketController::deleteAction' + controller: 'Hackzilla\Bundle\TicketBundle\Controller\TicketController::delete' methods: post|delete hackzilla_ticket_reply: path: /{ticketId}/reply - controller: 'Hackzilla\Bundle\TicketBundle\Controller\TicketController::replyAction' + controller: 'Hackzilla\Bundle\TicketBundle\Controller\TicketController::reply' hackzilla_ticket_attachment: path: /attachment/{ticketMessageId}/download - controller: 'Hackzilla\Bundle\TicketBundle\Controller\TicketAttachmentController::downloadAction' + controller: 'Hackzilla\Bundle\TicketBundle\Controller\TicketAttachmentController::download' From 6fbf8f6773dbb3fb766fed5caac721139a56d13e Mon Sep 17 00:00:00 2001 From: Regis Grison Date: Tue, 5 Nov 2024 11:34:52 +0100 Subject: [PATCH 07/18] fix some syntax using sonarlint and phpstan --- Command/AutoClosingCommand.php | 2 +- Command/TicketManagerCommand.php | 2 +- Controller/TicketController.php | 17 +- .../HackzillaTicketExtension.php | 3 +- EventListener/FileSubscriber.php | 4 +- Form/DataTransformer/StatusTransformer.php | 14 +- Maker/AbstractMaker.php | 7 +- Maker/MessageMaker.php | 6 +- Maker/TicketMaker.php | 4 + Maker/Util/ClassSourceManipulator.php | 148 +++++++++++++++--- Manager/PermissionManager.php | 12 +- Manager/PermissionManagerInterface.php | 3 +- Manager/TicketManager.php | 41 +++-- Manager/TicketManagerInterface.php | 6 +- Manager/UserManager.php | 4 +- Model/MessageAttachmentInterface.php | 19 ++- Model/MessageAttachmentTrait.php | 18 +-- Model/TicketInterface.php | 20 +-- Model/TicketMessageInterface.php | 20 +-- Model/TicketMessageTrait.php | 50 ++++-- Model/TicketTrait.php | 77 +++++---- Tests/Component/TicketFeaturesTest.php | 6 +- Tests/Fixtures/Entity/Ticket.php | 4 +- Tests/Fixtures/Entity/TicketMessage.php | 2 +- .../Entity/TicketMessageWithAttachment.php | 2 +- Tests/Fixtures/Entity/User.php | 4 +- Tests/Form/Type/TicketMessageTypeTest.php | 2 +- Tests/Form/Type/TicketTypeTest.php | 2 +- Tests/Functional/Command/ApplicationTest.php | 2 +- Tests/Functional/RoutingTest.php | 2 +- Tests/Functional/TestKernel.php | 76 +++------ Tests/Functional/WebTestCase.php | 22 +-- TwigExtension/TicketFeatureExtension.php | 2 +- 33 files changed, 371 insertions(+), 232 deletions(-) diff --git a/Command/AutoClosingCommand.php b/Command/AutoClosingCommand.php index eeb6a61..bf023f2 100644 --- a/Command/AutoClosingCommand.php +++ b/Command/AutoClosingCommand.php @@ -38,7 +38,7 @@ final class AutoClosingCommand extends Command /** * @var TranslatorInterface */ - private readonly LocaleAwareInterface $translator; + private readonly TranslatorInterface $translator; public function __construct(private readonly TicketManagerInterface $ticketManager, private readonly UserManagerInterface $userManager, LocaleAwareInterface $translator, ParameterBagInterface $parameterBag) { diff --git a/Command/TicketManagerCommand.php b/Command/TicketManagerCommand.php index e68327c..e5ed1b7 100644 --- a/Command/TicketManagerCommand.php +++ b/Command/TicketManagerCommand.php @@ -77,7 +77,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $this->ticketManager->updateTicket($ticket, $message); $output->writeln( - "Ticket with subject '".$ticket->getSubject()."' has been created with ticketnumber #".$ticket->getId().'' + "Ticket with subject '".$ticket->getSubject()."' has been created with ticketnumber #".$ticket->getId() ); return Command::SUCCESS; diff --git a/Controller/TicketController.php b/Controller/TicketController.php index 9dc5c50..351aee0 100644 --- a/Controller/TicketController.php +++ b/Controller/TicketController.php @@ -34,6 +34,7 @@ use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; use Symfony\Contracts\Translation\TranslatorInterface; +use function is_object; /** * Ticket controller. @@ -143,8 +144,10 @@ public function new(): Response * Finds and displays a TicketInterface entity. * * @param int $ticketId + * + * @return RedirectResponse|Response */ - public function show($ticketId): RedirectResponse|Response + public function show(int $ticketId): RedirectResponse|Response { $ticketManager = $this->ticketManager; $ticket = $ticketManager->getTicketById($ticketId); @@ -177,9 +180,12 @@ public function show($ticketId): RedirectResponse|Response /** * Finds and displays a TicketInterface entity. * + * @param Request $request * @param int $ticketId + * + * @return RedirectResponse|Response */ - public function reply(Request $request, $ticketId): RedirectResponse|Response + public function reply(Request $request, int $ticketId): RedirectResponse|Response { $ticketManager = $this->ticketManager; $ticket = $ticketManager->getTicketById($ticketId); @@ -219,14 +225,17 @@ public function reply(Request $request, $ticketId): RedirectResponse|Response /** * Deletes a Ticket entity. * + * @param Request $request * @param int $ticketId + * + * @return RedirectResponse */ - public function delete(Request $request, $ticketId): RedirectResponse + public function delete(Request $request, int $ticketId): RedirectResponse { $userManager = $this->userManager; $user = $userManager->getCurrentUser(); - if (!\is_object($user) || !$userManager->hasRole($user, TicketRole::ADMIN)) { + if ( ! is_object($user) || !$userManager->hasRole($user, TicketRole::ADMIN)) { throw new HttpException(403); } diff --git a/DependencyInjection/HackzillaTicketExtension.php b/DependencyInjection/HackzillaTicketExtension.php index d05fb0e..606e7c0 100644 --- a/DependencyInjection/HackzillaTicketExtension.php +++ b/DependencyInjection/HackzillaTicketExtension.php @@ -29,6 +29,7 @@ final class HackzillaTicketExtension extends Extension { /** * {@inheritdoc} + * @throws Exception */ public function load(array $configs, ContainerBuilder $container): void { @@ -67,7 +68,7 @@ public function load(array $configs, ContainerBuilder $container): void } } - public static function bundleDirectory() + public static function bundleDirectory(): bool|string { return realpath(__DIR__.'/..'); } diff --git a/EventListener/FileSubscriber.php b/EventListener/FileSubscriber.php index db64ffa..7e0df77 100644 --- a/EventListener/FileSubscriber.php +++ b/EventListener/FileSubscriber.php @@ -27,7 +27,7 @@ final class FileSubscriber implements EventSubscriberInterface /** * @return array */ - public static function getSubscribedEvents() + public static function getSubscribedEvents(): array { return [ VichEvent\Events::POST_UPLOAD => 'postUpload', @@ -38,7 +38,7 @@ public function postUpload(VichEvent\Event $event): void { /** @var MessageAttachmentInterface $object */ $object = $event->getObject(); - // Ignore any entity lifecycle events not relating to this bundles entities. + // Ignore any entity lifecycle events not relating to these bundles entities. if (!($object instanceof MessageAttachmentInterface)) { return; } diff --git a/Form/DataTransformer/StatusTransformer.php b/Form/DataTransformer/StatusTransformer.php index 6619e6e..a5681b7 100644 --- a/Form/DataTransformer/StatusTransformer.php +++ b/Form/DataTransformer/StatusTransformer.php @@ -26,13 +26,13 @@ public function __construct(private readonly TicketInterface $ticket) /** * Transforms checkbox value into Ticket Message Status Closed. * - * @param int $number + * @param $value * - * @return true|null + * @return bool|null */ - public function transform($number): mixed + public function transform($value): ?bool { - if (TicketMessageInterface::STATUS_CLOSED === $number) { + if (TicketMessageInterface::STATUS_CLOSED === $value) { return true; } @@ -42,13 +42,13 @@ public function transform($number): mixed /** * Transforms Ticket Message Status Closed into checkbox value checked. * - * @param bool $number + * @param $value * * @return int|null */ - public function reverseTransform($number): mixed + public function reverseTransform($value): ?int { - if ($number) { + if ($value) { return TicketMessageInterface::STATUS_CLOSED; } diff --git a/Maker/AbstractMaker.php b/Maker/AbstractMaker.php index b41c65c..b71248c 100644 --- a/Maker/AbstractMaker.php +++ b/Maker/AbstractMaker.php @@ -34,6 +34,7 @@ use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; +use function is_array; /** * A lot of this class is a duplication of the Symfony Maker component. @@ -97,6 +98,7 @@ public function interact(InputInterface $input, ConsoleStyle $io, Command $comma /** * Called after normal code generation: allows you to do anything. + * @throws Exception */ public function generate(InputInterface $input, ConsoleStyle $io, Generator $generator): void { @@ -130,7 +132,7 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen $fileManagerOperations = []; $fileManagerOperations[$entityPath] = $manipulator; - if (\is_array($newField)) { + if (is_array($newField)) { $annotationOptions = $newField; unset($annotationOptions['fieldName']); $manipulator->addEntityField($newField['fieldName'], $annotationOptions); @@ -217,6 +219,9 @@ abstract protected function traits(): array; abstract protected function interfaces(): array; + /** + * @throws Exception + */ private function createClassManipulator(string $path, ConsoleStyle $io, bool $overwrite, string $className, bool $originalClass = true): ClassSourceManipulator { $useAttributes = $this->doctrineHelper->doesClassUsesAttributes($className) && $this->doctrineHelper->isDoctrineSupportingAttributes(); diff --git a/Maker/MessageMaker.php b/Maker/MessageMaker.php index 0ae3aa3..b369f11 100644 --- a/Maker/MessageMaker.php +++ b/Maker/MessageMaker.php @@ -13,6 +13,7 @@ namespace Hackzilla\Bundle\TicketBundle\Maker; +use Exception; use Hackzilla\Bundle\TicketBundle\Model\MessageAttachmentInterface; use Hackzilla\Bundle\TicketBundle\Model\MessageAttachmentTrait; use Hackzilla\Bundle\TicketBundle\Model\TicketMessageInterface; @@ -28,7 +29,7 @@ final class MessageMaker extends AbstractMaker { - private $hasAttachment = false; + private bool $hasAttachment = false; public static function getCommandName(): string { @@ -54,6 +55,9 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen parent::generate($input, $io, $generator); } + /** + * @throws Exception + */ protected function fields(): array { $userRelation = new EntityRelation(EntityRelation::MANY_TO_ONE, $this->getMessageClass(), $this->getUserClass()); diff --git a/Maker/TicketMaker.php b/Maker/TicketMaker.php index d6f8aa3..7c7d092 100644 --- a/Maker/TicketMaker.php +++ b/Maker/TicketMaker.php @@ -13,6 +13,7 @@ namespace Hackzilla\Bundle\TicketBundle\Maker; +use Exception; use Hackzilla\Bundle\TicketBundle\Model\TicketInterface; use Hackzilla\Bundle\TicketBundle\Model\TicketTrait; use Symfony\Bundle\MakerBundle\Doctrine\EntityRelation; @@ -30,6 +31,9 @@ public static function getCommandDescription(): string return MakeEntity::getCommandDescription(); } + /** + * @throws Exception + */ protected function fields(): array { $lastUserRelation = new EntityRelation(EntityRelation::MANY_TO_ONE, $this->getTicketClass(), $this->getUserClass()); diff --git a/Maker/Util/ClassSourceManipulator.php b/Maker/Util/ClassSourceManipulator.php index 3e00aac..2a34340 100644 --- a/Maker/Util/ClassSourceManipulator.php +++ b/Maker/Util/ClassSourceManipulator.php @@ -71,6 +71,12 @@ use Symfony\Bundle\MakerBundle\Str; use Symfony\Bundle\MakerBundle\Util\ClassNameValue; use Symfony\Bundle\MakerBundle\Util\PrettyPrinter; +use function array_key_exists; +use function count; +use function gettype; +use function is_array; +use function is_bool; +use function is_int; /** * @internal @@ -91,7 +97,7 @@ final class ClassSourceManipulator private ?ConsoleStyle $io = null; private string $sourceCode; - private $oldStmts; + private ?array $oldStmts; private array $oldTokens; private array $newStmts; @@ -122,6 +128,9 @@ public function getSourceCode(): string return $this->sourceCode; } + /** + * @throws Exception + */ public function addCreatedToContructor(): void { $addCreatedAt = true; @@ -145,6 +154,9 @@ public function addCreatedToContructor(): void } } + /** + * @throws Exception + */ public function addEntityField(string $propertyName, array $columnOptions, array $comments = []): void { $typeHint = $this->getEntityTypeHint($columnOptions['type']); @@ -164,26 +176,41 @@ public function addEntityField(string $propertyName, array $columnOptions, array $this->addProperty($propertyName, $comments, $defaultValue, $attributes); } + /** + * @throws Exception + */ public function addManyToOneRelation(RelationManyToOne $manyToOne): void { $this->addSingularRelation($manyToOne); } + /** + * @throws Exception + */ public function addOneToOneRelation(RelationOneToOne $oneToOne): void { $this->addSingularRelation($oneToOne); } + /** + * @throws Exception + */ public function addOneToManyRelation(RelationOneToMany $oneToMany): void { $this->addCollectionRelation($oneToMany); } + /** + * @throws Exception + */ public function addManyToManyRelation(RelationManyToMany $manyToMany): void { $this->addCollectionRelation($manyToMany); } + /** + * @throws Exception + */ public function addInterface(string $interfaceName): void { $this->addUseStatementIfNecessary($interfaceName); @@ -200,6 +227,8 @@ public function addInterface(string $interfaceName): void /** * @param string $trait the fully-qualified trait name + * + * @throws Exception */ public function addTrait(string $trait): void { @@ -218,7 +247,7 @@ public function addTrait(string $trait): void $classNode = $this->getClassNode(); - if (!empty($classNode->stmts) && 1 === \count($traitNodes)) { + if (!empty($classNode->stmts) && 1 === count($traitNodes)) { $traitNodes[] = $this->createBlankLineNode(self::CONTEXT_CLASS); } @@ -237,6 +266,9 @@ public function addTrait(string $trait): void /** * @param Node[] $params + * @param string $methodBody + * + * @throws Exception */ public function addConstructor(array $params, string $methodBody): void { @@ -255,7 +287,11 @@ public function addConstructor(array $params, string $methodBody): void } /** + * @param Method $methodBuilder * @param Node[] $params + * @param string|null $methodBody + * + * @throws Exception */ public function addMethodBuilder(Method $methodBuilder, array $params = [], ?string $methodBody = null): void { @@ -274,6 +310,9 @@ public function addMethodBody(Method $methodBuilder, string $methodBody): void $methodBuilder->addStmts($nodes); } + /** + * @throws Exception + */ public function createMethodBuilder(string $methodName, $returnType, bool $isReturnTypeNullable, array $commentLines = []): Method { $methodNodeBuilder = (new Method($methodName)) @@ -294,16 +333,25 @@ public function createMethodBuilder(string $methodName, $returnType, bool $isRet return $methodNodeBuilder; } + /** + * @throws Exception + */ public function createMethodLevelCommentNode(string $comment): Stmt { return $this->createSingleLineCommentNode($comment, self::CONTEXT_CLASS_METHOD); } - public function createMethodLevelBlankLine() + /** + * @throws Exception + */ + public function createMethodLevelBlankLine(): Use_|Node|Stmt\Property|Variable { return $this->createBlankLineNode(self::CONTEXT_CLASS_METHOD); } + /** + * @throws Exception + */ public function addProperty(string $name, array $annotationLines = [], $defaultValue = null, array $attributes = []): void { if ($this->propertyExists($name)) { @@ -329,6 +377,9 @@ public function addProperty(string $name, array $annotationLines = [], $defaultV $this->addNodeAfterProperties($newPropertyNode); } + /** + * @throws Exception + */ public function addAnnotationToClass(string $annotationClass, array $options): void { $annotationClassAlias = $this->addUseStatementIfNecessary($annotationClass); @@ -337,7 +388,7 @@ public function addAnnotationToClass(string $annotationClass, array $options): v $docLines = $docComment ? explode("\n", $docComment->getText()) : []; if ([] === $docLines) { $docLines = ['/**', ' */']; - } elseif (1 === \count($docLines)) { + } elseif (1 === count($docLines)) { // /** inline doc syntax */ // imperfect way to try to find where to split the lines $endOfOpening = strpos($docLines[0], '* '); @@ -357,7 +408,7 @@ public function addAnnotationToClass(string $annotationClass, array $options): v array_splice( $docLines, - \count($docLines) - 1, + count($docLines) - 1, 0, ' * '.$this->buildAnnotationLine('@'.$annotationClassAlias, $options) ); @@ -368,7 +419,10 @@ public function addAnnotationToClass(string $annotationClass, array $options): v } /** + * @param string $class + * * @return string The alias to use when referencing this class + * @throws Exception */ public function addUseStatementIfNecessary(string $class): string { @@ -447,12 +501,14 @@ public function addUseStatementIfNecessary(string $class): string /** * @param string $annotationClass The annotation: e.g. "@ORM\Column" - * @param array $options Key-value pair of options for the annotation + * @param array $options Key-value pair of options for the annotation + * + * @throws Exception */ private function buildAnnotationLine(string $annotationClass, array $options): string { $formattedOptions = array_map(function ($option, $value): string { - if (\is_array($value)) { + if (is_array($value)) { if (!isset($value[0])) { return sprintf('%s={%s}', $option, implode(', ', array_map(fn($val, $key): string => sprintf('"%s" = %s', $key, $this->quoteAnnotationValue($val)), $value, array_keys($value)))); } @@ -466,9 +522,12 @@ private function buildAnnotationLine(string $annotationClass, array $options): s return sprintf('%s(%s)', $annotationClass, implode(', ', $formattedOptions)); } + /** + * @throws Exception + */ private function quoteAnnotationValue($value): int|string { - if (\is_bool($value)) { + if (is_bool($value)) { return $value ? 'true' : 'false'; } @@ -476,7 +535,7 @@ private function quoteAnnotationValue($value): int|string return 'null'; } - if (\is_int($value) || '0' === $value) { + if (is_int($value) || '0' === $value) { return $value; } @@ -484,13 +543,16 @@ private function quoteAnnotationValue($value): int|string return sprintf('%s::class', $value->getShortName()); } - if (\is_array($value)) { + if (is_array($value)) { throw new Exception('Invalid value: loop before quoting.'); } return sprintf('"%s"', $value); } + /** + * @throws Exception + */ private function addSingularRelation(BaseRelation $relation): void { $typeHint = $this->addUseStatementIfNecessary($relation->getTargetClassName()); @@ -536,6 +598,9 @@ private function addSingularRelation(BaseRelation $relation): void $this->addProperty($relation->getPropertyName(), $annotations, null, $attributes); } + /** + * @throws Exception + */ private function addCollectionRelation(BaseCollectionRelation $relation): void { $typeHint = $relation->isSelfReferencing() ? 'self' : $this->addUseStatementIfNecessary($relation->getTargetClassName()); @@ -603,6 +668,9 @@ private function addCollectionRelation(BaseCollectionRelation $relation): void Str::pluralCamelCaseToSingular($relation->getPropertyName()); } + /** + * @throws Exception + */ private function addStatementToConstructor(Stmt $stmt): void { if (!$this->getConstructorNode() instanceof ClassMethod) { @@ -618,6 +686,7 @@ private function addStatementToConstructor(Stmt $stmt): void ); } } catch (ReflectionException) { + // nothing to do here } $this->addNodeAfterProperties($constructorNode); @@ -651,9 +720,9 @@ private function updateSourceCodeFromNewStmts(): void ); // replace the 3 "fake" items that may be in the code (allowing for different indentation) - $newCode = preg_replace('/(\ |\t)*private\ \$__EXTRA__LINE;/', '', $newCode); - $newCode = preg_replace('/use __EXTRA__LINE;/', '', (string) $newCode); - $newCode = preg_replace('/(\ |\t)*\$__EXTRA__LINE;/', '', (string) $newCode); + $newCode = preg_replace('/\s*private \$__EXTRA__LINE;/', '', $newCode); + $newCode = str_replace('use __EXTRA__LINE;', '', (string) $newCode); + $newCode = preg_replace('/\s*\$__EXTRA__LINE;/', '', (string) $newCode); // process comment lines foreach ($this->pendingComments as $i => $comment) { @@ -686,6 +755,9 @@ private function setSourceCode(string $sourceCode): void $this->newStmts = $traverser->traverse($this->oldStmts); } + /** + * @throws Exception + */ private function getClassNode(): Class_ { $node = $this->findFirstNode(static fn($node): bool => $node instanceof Class_); @@ -698,6 +770,9 @@ private function getClassNode(): Class_ return $node; } + /** + * @throws Exception + */ private function getNamespaceNode(): Namespace_ { $node = $this->findFirstNode(static fn($node): bool => $node instanceof Namespace_); @@ -746,7 +821,10 @@ private function findAllNodes(callable $filterCallback): array return $visitor->getFoundNodes(); } - private function createBlankLineNode(string $context) + /** + * @throws Exception + */ + private function createBlankLineNode(string $context): Use_|Node|Stmt\Property|Variable { return match ($context) { self::CONTEXT_OUTSIDE_CLASS => (new Builder\Use_('__EXTRA__LINE', Use_::TYPE_NORMAL)) @@ -759,6 +837,9 @@ private function createBlankLineNode(string $context) }; } + /** + * @throws Exception + */ private function createSingleLineCommentNode(string $comment, string $context): Stmt { $this->pendingComments[] = $comment; @@ -770,7 +851,7 @@ private function createSingleLineCommentNode(string $comment, string $context): // just not needed yet throw new Exception('not supported'); case self::CONTEXT_CLASS_METHOD: - return BuilderHelpers::normalizeStmt(new Variable(sprintf('__COMMENT__VAR_%d', \count($this->pendingComments) - 1))); + return BuilderHelpers::normalizeStmt(new Variable(sprintf('__COMMENT__VAR_%d', count($this->pendingComments) - 1))); default: throw new Exception('Unknown context: '.$context); } @@ -781,7 +862,7 @@ private function createDocBlock(array $commentLines): string $docBlock = "/**\n"; foreach ($commentLines as $commentLine) { if ($commentLine) { - $docBlock .= " * ${commentLine}\n"; + $docBlock .= " * $commentLine\n"; } else { // avoid the empty, extra space on blank lines $docBlock .= " *\n"; @@ -791,6 +872,9 @@ private function createDocBlock(array $commentLines): string return $docBlock . "\n */"; } + /** + * @throws Exception + */ private function addMethod(ClassMethod $methodNode): void { $classNode = $this->getClassNode(); @@ -851,6 +935,9 @@ private function getEntityTypeHint($doctrineType): ?string }; } + /** + * @throws Exception + */ private function isInSameNamespace(string $class): bool { $namespace = substr($class, 0, strrpos($class, '\\')); @@ -858,6 +945,9 @@ private function isInSameNamespace(string $class): bool return $this->getNamespaceNode()->name->toCodeString() === $namespace; } + /** + * @throws Exception + */ private function getThisFullClassName(): string { return (string) $this->getClassNode()->namespacedName; @@ -867,6 +957,7 @@ private function getThisFullClassName(): string * Adds this new node where a new property should go. * * Useful for adding properties, or adding a constructor. + * @throws Exception */ private function addNodeAfterProperties(Node $newNode): void { @@ -910,12 +1001,18 @@ private function addNodeAfterProperties(Node $newNode): void $this->updateSourceCodeFromNewStmts(); } + /** + * @throws Exception + */ private function methodExists(string $methodName): bool { return false !== $this->getMethodIndex($methodName); } - private function getMethodIndex(string $methodName) + /** + * @throws Exception + */ + private function getMethodIndex(string $methodName): bool|int|string { foreach ($this->getClassNode()->stmts as $i => $node) { if ($node instanceof ClassMethod && strtolower($node->name->toString()) === strtolower($methodName)) { @@ -926,6 +1023,9 @@ private function getMethodIndex(string $methodName) return false; } + /** + * @throws Exception + */ private function propertyExists(string $propertyName): bool { foreach ($this->getClassNode()->stmts as $node) { @@ -960,7 +1060,7 @@ private function addMethodParams(Method $methodBuilder, array $params): void */ private function buildNodeExprByValue(mixed $value): Expr { - switch (\gettype($value)) { + switch (gettype($value)) { case 'string': $nodeValue = new String_($value); break; @@ -977,7 +1077,7 @@ private function buildNodeExprByValue(mixed $value): Expr $context = $this; $arrayItems = array_map(static fn($key, $value): ArrayItem => new ArrayItem( $context->buildNodeExprByValue($value), - \is_int($key) ? null : $context->buildNodeExprByValue($key) + is_int($key) ? null : $context->buildNodeExprByValue($key) ), array_keys($value), array_values($value)); $nodeValue = new Array_($arrayItems, ['kind' => Array_::KIND_SHORT]); break; @@ -993,7 +1093,7 @@ private function buildNodeExprByValue(mixed $value): Expr ) ); } else { - throw new Exception(sprintf('Cannot build a node expr for value of type "%s"', \gettype($value))); + throw new Exception(sprintf('Cannot build a node expr for value of type "%s"', gettype($value))); } } @@ -1004,7 +1104,10 @@ private function buildNodeExprByValue(mixed $value): Expr * builds an PHPParser attribute node. * * @param string $attributeClass the attribute class which should be used for the attribute - * @param array $options the named arguments for the attribute ($key = argument name, $value = argument value) + * @param array $options the named arguments for the attribute ($key = argument name, $value = argument value) + * + * @return Attribute + * @throws Exception */ private function buildAttributeNode(string $attributeClass, array $options): Attribute { @@ -1024,6 +1127,7 @@ private function buildAttributeNode(string $attributeClass, array $options): Att * this prevents code inspections warnings for IDEs like intellij/phpstorm. * * option keys that are not found in the constructor will be added at the end of the sorted array + * @throws ReflectionException */ private function sortOptionsByClassConstructorParameters(array $options, string $classString): array { @@ -1035,7 +1139,7 @@ private function sortOptionsByClassConstructorParameters(array $options, string $sorted = []; foreach ($constructorParameterNames as $name) { - if (\array_key_exists($name, $options)) { + if (array_key_exists($name, $options)) { $sorted[$name] = $options[$name]; unset($options[$name]); } diff --git a/Manager/PermissionManager.php b/Manager/PermissionManager.php index 740d42e..d3e7c8e 100644 --- a/Manager/PermissionManager.php +++ b/Manager/PermissionManager.php @@ -17,6 +17,7 @@ use Hackzilla\Bundle\TicketBundle\Model\UserInterface; use Hackzilla\Bundle\TicketBundle\TicketRole; use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; +use function is_object; class PermissionManager implements PermissionManagerInterface { @@ -26,10 +27,13 @@ class PermissionManager implements PermissionManagerInterface * used in TicketManager::getTicketListQuery(). * * @param object $query + * @param UserInterface|null $user + * + * @return object */ - public function addUserPermissionsCondition($query, ?UserInterface $user) + public function addUserPermissionsCondition(object $query, ?UserInterface $user): object { - if (\is_object($user)) { + if (is_object($user)) { if (!$this->getUserManager()->hasRole($user, TicketRole::ADMIN)) { $query ->andWhere('t.userCreated = :user') @@ -52,8 +56,8 @@ public function addUserPermissionsCondition($query, ?UserInterface $user) */ public function hasPermission(?UserInterface $user, TicketInterface $ticket): void { - if (!\is_object($user) || (!$this->getUserManager()->hasRole($user, TicketRole::ADMIN) && - (!$ticket->getUserCreated() instanceof UserInterface || $ticket->getUserCreated()->getId() != $user->getId())) + if ( ! is_object($user) || ( !$this->getUserManager()->hasRole($user, TicketRole::ADMIN) && + (!$ticket->getUserCreated() instanceof UserInterface || $ticket->getUserCreated()->getId() != $user->getId())) ) { throw new AccessDeniedHttpException(); } diff --git a/Manager/PermissionManagerInterface.php b/Manager/PermissionManagerInterface.php index e19b97f..0983e63 100644 --- a/Manager/PermissionManagerInterface.php +++ b/Manager/PermissionManagerInterface.php @@ -22,8 +22,9 @@ interface PermissionManagerInterface * used in TicketManager::getTicketListQuery(). * * @param object $query + * @param UserInterface $user */ - public function addUserPermissionsCondition($query, UserInterface $user); + public function addUserPermissionsCondition(object $query, UserInterface $user); /** * used by UserManager::hasPermission(). diff --git a/Manager/TicketManager.php b/Manager/TicketManager.php index fdce858..106c645 100644 --- a/Manager/TicketManager.php +++ b/Manager/TicketManager.php @@ -13,10 +13,12 @@ namespace Hackzilla\Bundle\TicketBundle\Manager; +use DateMalformedIntervalStringException; use DateTime; use DateInterval; use Doctrine\ORM\QueryBuilder; use Doctrine\Persistence\ObjectManager; +use Doctrine\Persistence\ObjectRepository; use Hackzilla\Bundle\TicketBundle\Model\TicketInterface; use Hackzilla\Bundle\TicketBundle\Model\TicketMessageInterface; use Psr\Log\LoggerInterface; @@ -33,14 +35,14 @@ final class TicketManager implements TicketManagerInterface private ?ObjectManager $objectManager = null; - private $ticketRepository; + private ObjectRepository $ticketRepository; - private $messageRepository; + private ObjectRepository $messageRepository; /** * TicketManager constructor. */ - public function __construct(private string $ticketClass, private string $ticketMessageClass) + public function __construct(private readonly string $ticketClass, private readonly string $ticketMessageClass) { } @@ -86,7 +88,7 @@ public function setTranslator(TranslatorInterface $translator): self * * @return TicketInterface */ - public function createTicket() + public function createTicket(): TicketInterface { /* @var TicketInterface $ticket */ $ticket = new $this->ticketClass(); @@ -99,11 +101,11 @@ public function createTicket() /** * Create a new instance of TicketMessage Entity. * - * @param TicketInterface $ticket + * @param TicketInterface|null $ticket * * @return TicketMessageInterface */ - public function createMessage(?TicketInterface $ticket = null) + public function createMessage(?TicketInterface $ticket = null): TicketMessageInterface { /* @var TicketMessageInterface $ticket */ $message = new $this->ticketMessageClass(); @@ -120,7 +122,10 @@ public function createMessage(?TicketInterface $ticket = null) } /** - * {@inheritdoc} + * @param TicketInterface $ticket + * @param TicketMessageInterface|null $message + * + * @return void */ public function updateTicket(TicketInterface $ticket, ?TicketMessageInterface $message = null): void { @@ -149,7 +154,7 @@ public function deleteTicket(TicketInterface $ticket): void * * @return TicketInterface[] */ - public function findTickets() + public function findTickets(): array { return $this->ticketRepository->findAll(); } @@ -169,7 +174,7 @@ public function getTicketById($ticketId): ?TicketInterface * * @param int $ticketMessageId * - * @return TicketMessageInterface + * @return TicketMessageInterface|null */ public function getMessageById($ticketMessageId): ?TicketMessageInterface { @@ -181,13 +186,16 @@ public function getMessageById($ticketMessageId): ?TicketMessageInterface * * @return array|TicketInterface[] */ - public function findTicketsBy(array $criteria) + public function findTicketsBy(array $criteria): array { return $this->ticketRepository->findBy($criteria); } /** - * {@inheritdoc} + * @param $ticketStatus + * @param $ticketPriority + * + * @return QueryBuilder */ public function getTicketListQuery($ticketStatus, $ticketPriority = null): QueryBuilder { @@ -223,8 +231,9 @@ public function getTicketListQuery($ticketStatus, $ticketPriority = null): Query * @param int $days * * @return mixed + * @throws DateMalformedIntervalStringException */ - public function getResolvedTicketOlderThan($days) + public function getResolvedTicketOlderThan(int $days) { $closeBeforeDate = new DateTime(); $closeBeforeDate->sub(new DateInterval('P'.$days.'D')); @@ -245,9 +254,9 @@ public function getResolvedTicketOlderThan($days) * * @param string $statusStr * - * @return int + * @return int|string|false */ - public function getTicketStatus($statusStr): int|string|false + public function getTicketStatus(string $statusStr): int|string|false { static $statuses = false; @@ -267,9 +276,9 @@ public function getTicketStatus($statusStr): int|string|false * * @param string $priorityStr * - * @return int + * @return int|string|false */ - public function getTicketPriority($priorityStr): int|string|false + public function getTicketPriority(string $priorityStr): int|string|false { static $priorities = false; diff --git a/Manager/TicketManagerInterface.php b/Manager/TicketManagerInterface.php index 4619c8f..2d3a909 100644 --- a/Manager/TicketManagerInterface.php +++ b/Manager/TicketManagerInterface.php @@ -42,7 +42,7 @@ public function getTicketListQuery($ticketStatus, $ticketPriority = null): Query * * @return mixed */ - public function getResolvedTicketOlderThan($days); + public function getResolvedTicketOlderThan(int $days): mixed; /** * Lookup status code. @@ -51,7 +51,7 @@ public function getResolvedTicketOlderThan($days); * * @return int */ - public function getTicketStatus($statusStr); + public function getTicketStatus(string $statusStr): int; /** * Lookup priority code. @@ -60,5 +60,5 @@ public function getTicketStatus($statusStr); * * @return int */ - public function getTicketPriority($priorityStr); + public function getTicketPriority(string $priorityStr): int; } diff --git a/Manager/UserManager.php b/Manager/UserManager.php index 1e52423..392b2e5 100644 --- a/Manager/UserManager.php +++ b/Manager/UserManager.php @@ -30,9 +30,9 @@ final class UserManager implements UserManagerInterface private ObjectRepository $userRepository; public function __construct( - private TokenStorageInterface $tokenStorage, + private readonly TokenStorageInterface $tokenStorage, ObjectRepository $userRepository, - private AuthorizationCheckerInterface $authorizationChecker, + private readonly AuthorizationCheckerInterface $authorizationChecker, ) { if (!is_subclass_of($userRepository->getClassName(), UserInterface::class)) { throw new InvalidArgumentException(sprintf('Argument 2 passed to "%s()" MUST be an object repository for a class implementing "%s".', __METHOD__, UserInterface::class)); diff --git a/Model/MessageAttachmentInterface.php b/Model/MessageAttachmentInterface.php index 0e27c66..e723333 100644 --- a/Model/MessageAttachmentInterface.php +++ b/Model/MessageAttachmentInterface.php @@ -13,54 +13,53 @@ namespace Hackzilla\Bundle\TicketBundle\Model; -use Symfony\Component\HttpFoundation\File\UploadedFile; use Symfony\Component\HttpFoundation\File\File; interface MessageAttachmentInterface extends TicketMessageInterface { /** - * @param File|UploadedFile $file + * @param File|null $file * * @return $this */ - public function setAttachmentFile(?File $file = null); + public function setAttachmentFile(?File $file = null): self; /** * @return File */ - public function getAttachmentFile(); + public function getAttachmentFile(): File; /** * @return $this */ - public function setAttachmentName(string $name); + public function setAttachmentName(string $name): self; /** * @return string */ - public function getAttachmentName(); + public function getAttachmentName(): string; /** * @param int $size Size in bytes * * @return $this */ - public function setAttachmentSize(int $size); + public function setAttachmentSize(int $size): self; /** * @return string */ - public function getAttachmentSize(); + public function getAttachmentSize(): string; /** * @param string $mimeType Attachment mime type * * @return $this */ - public function setAttachmentMimeType(string $mimeType); + public function setAttachmentMimeType(string $mimeType): self; /** * @return string */ - public function getAttachmentMimeType(); + public function getAttachmentMimeType(): string; } diff --git a/Model/MessageAttachmentTrait.php b/Model/MessageAttachmentTrait.php index 089f9fb..b89ec52 100644 --- a/Model/MessageAttachmentTrait.php +++ b/Model/MessageAttachmentTrait.php @@ -25,12 +25,12 @@ trait MessageAttachmentTrait * * @var File|null */ - protected $attachmentFile; + protected ?File $attachmentFile; /** * {@inheritdoc} */ - public function setAttachmentFile(?File $file = null) + public function setAttachmentFile(?File $file = null): self { $this->attachmentFile = $file; @@ -40,7 +40,7 @@ public function setAttachmentFile(?File $file = null) /** * {@inheritdoc} */ - public function getAttachmentFile() + public function getAttachmentFile(): ?File { return $this->attachmentFile; } @@ -48,7 +48,7 @@ public function getAttachmentFile() /** * {@inheritdoc} */ - public function setAttachmentName($name) + public function setAttachmentName($name): self { $this->attachmentName = $name; @@ -58,7 +58,7 @@ public function setAttachmentName($name) /** * {@inheritdoc} */ - public function getAttachmentName() + public function getAttachmentName(): ?string { return $this->attachmentName; } @@ -66,7 +66,7 @@ public function getAttachmentName() /** * {@inheritdoc} */ - public function setAttachmentSize($size) + public function setAttachmentSize($size): self { $this->attachmentSize = $size; @@ -76,7 +76,7 @@ public function setAttachmentSize($size) /** * {@inheritdoc} */ - public function getAttachmentSize() + public function getAttachmentSize(): ?int { return $this->attachmentSize; } @@ -84,7 +84,7 @@ public function getAttachmentSize() /** * {@inheritdoc} */ - public function setAttachmentMimeType($mimeType) + public function setAttachmentMimeType($mimeType): self { $this->attachmentMimeType = $mimeType; @@ -94,7 +94,7 @@ public function setAttachmentMimeType($mimeType) /** * {@inheritdoc} */ - public function getAttachmentMimeType() + public function getAttachmentMimeType(): ?string { return $this->attachmentMimeType; } diff --git a/Model/TicketInterface.php b/Model/TicketInterface.php index ef6c9d5..7465423 100644 --- a/Model/TicketInterface.php +++ b/Model/TicketInterface.php @@ -28,14 +28,14 @@ public function getId(); * * @return $this */ - public function setStatus(int $status); + public function setStatus(int $status): self; /** * Set ticket status by string. * * @return $this */ - public function setStatusString(string $status); + public function setStatusString(string $status): self; /** * Get ticket status. @@ -52,14 +52,14 @@ public function getStatusString(): ?string; * * @return $this */ - public function setPriority(int $priority); + public function setPriority(int $priority): self; /** * Set ticket priority string. * * @return $this */ - public function setPriorityString(string $priority); + public function setPriorityString(string $priority): self; /** * Get priority. @@ -77,7 +77,7 @@ public function getPriorityString(): ?string; * * @return $this */ - public function setUserCreated(?UserInterface $userCreated); + public function setUserCreated(?UserInterface $userCreated): self; /** * Get userCreated. @@ -90,7 +90,7 @@ public function getUserCreated(): ?UserInterface; * * @return $this */ - public function setLastUser(?UserInterface $lastUser); + public function setLastUser(?UserInterface $lastUser): self; /** * Get lastUser . @@ -102,7 +102,7 @@ public function getLastUser(): ?UserInterface; * * @return $this */ - public function setLastMessage(DateTimeInterface $lastMessage); + public function setLastMessage(DateTimeInterface $lastMessage): self; /** * Get lastMessage. @@ -114,7 +114,7 @@ public function getLastMessage(): ?DateTimeInterface; * * @return $this */ - public function setCreatedAt(DateTimeInterface $createdAt); + public function setCreatedAt(DateTimeInterface $createdAt): self; /** * Get createdAt. @@ -126,7 +126,7 @@ public function getCreatedAt(): ?DateTimeInterface; * * @return $this */ - public function setSubject(string $subject); + public function setSubject(string $subject): self; /** * Get ticket subject. @@ -138,7 +138,7 @@ public function getSubject(): ?string; * * @return $this */ - public function addMessage(TicketMessageInterface $message); + public function addMessage(TicketMessageInterface $message): self; /** * Remove message. diff --git a/Model/TicketMessageInterface.php b/Model/TicketMessageInterface.php index e824822..95e5e7f 100644 --- a/Model/TicketMessageInterface.php +++ b/Model/TicketMessageInterface.php @@ -66,14 +66,14 @@ public function getId(); * * @return $this */ - public function setStatus(int $status); + public function setStatus(int $status): self; /** * Set status string. * * @return $this */ - public function setStatusString(string $status); + public function setStatusString(string $status): self; /** * Get status. @@ -90,14 +90,14 @@ public function getStatusString(): ?string; * * @return $this */ - public function setPriority(int $priority); + public function setPriority(int $priority): self; /** * Set priority string. * * @return $this */ - public function setPriorityString(string $priority); + public function setPriorityString(string $priority): self; /** * Get priority. @@ -115,21 +115,21 @@ public function getPriorityString(): ?string; * * @return $this */ - public function setUser(?UserInterface $user); + public function setUser(?UserInterface $user): self; /** * Get user. * * @return ?UserInterface */ - public function getUser(); + public function getUser(): ?UserInterface; /** * Set message. * * @return $this */ - public function setMessage(string $message); + public function setMessage(string $message): self; /** * Get message. @@ -141,21 +141,21 @@ public function getMessage(): ?string; * * @return $this */ - public function setCreatedAt(DateTime $createdAt); + public function setCreatedAt(DateTime $createdAt): self; /** * Get createdAt. * * @return DateTime */ - public function getCreatedAt(); + public function getCreatedAt(): DateTime; /** * Set ticket. * * @return $this */ - public function setTicket(?TicketInterface $ticket = null); + public function setTicket(?TicketInterface $ticket = null): self; /** * Get ticket. diff --git a/Model/TicketMessageTrait.php b/Model/TicketMessageTrait.php index 2effc22..746a0fc 100644 --- a/Model/TicketMessageTrait.php +++ b/Model/TicketMessageTrait.php @@ -14,6 +14,8 @@ namespace Hackzilla\Bundle\TicketBundle\Model; use DateTime; +use Hackzilla\Bundle\TicketBundle\Tests\Fixtures\Entity\TicketMessage; +use Hackzilla\Bundle\TicketBundle\Tests\Fixtures\Entity\TicketMessageWithAttachment; /** * Ticket Message Trait. @@ -23,9 +25,11 @@ trait TicketMessageTrait /** * Set status. * - * @return $this + * @param int $status + * + * @return TicketMessage|TicketMessageTrait|TicketMessageWithAttachment */ - public function setStatus(int $status) + public function setStatus(int $status): self { $this->status = $status; @@ -35,9 +39,11 @@ public function setStatus(int $status) /** * Set status string. * - * @return $this + * @param string $status + * + * @return TicketMessage|TicketMessageTrait|TicketMessageWithAttachment */ - public function setStatusString(string $status) + public function setStatusString(string $status): self { $status = array_search(strtolower($status), TicketMessageInterface::STATUSES, true); @@ -71,9 +77,11 @@ public function getStatusString(): ?string /** * Set priority. * - * @return $this + * @param int $priority + * + * @return TicketMessage|TicketMessageTrait|TicketMessageWithAttachment */ - public function setPriority(int $priority) + public function setPriority(int $priority): self { $this->priority = $priority; @@ -83,9 +91,11 @@ public function setPriority(int $priority) /** * Set priority string. * - * @return $this + * @param string $priority + * + * @return TicketMessage|TicketMessageTrait|TicketMessageWithAttachment */ - public function setPriorityString(string $priority) + public function setPriorityString(string $priority): self { $priority = array_search(strtolower($priority), TicketMessageInterface::PRIORITIES, true); @@ -121,9 +131,9 @@ public function getPriorityString(): ?string * * @param ?UserInterface $user * - * @return $this + * @return TicketMessage|TicketMessageTrait|TicketMessageWithAttachment */ - public function setUser($user) + public function setUser(?UserInterface $user): self { $this->user = $user; @@ -141,9 +151,11 @@ public function getUser(): ?UserInterface /** * Set message. * - * @return $this + * @param string $message + * + * @return TicketMessage|TicketMessageTrait|TicketMessageWithAttachment */ - public function setMessage(string $message) + public function setMessage(string $message): self { $this->message = $message; @@ -161,9 +173,11 @@ public function getMessage(): ?string /** * Set createdAt. * - * @return $this + * @param DateTime $createdAt + * + * @return TicketMessage|TicketMessageTrait|TicketMessageWithAttachment */ - public function setCreatedAt(DateTime $createdAt) + public function setCreatedAt(DateTime $createdAt): self { $this->createdAt = $createdAt; @@ -175,7 +189,7 @@ public function setCreatedAt(DateTime $createdAt) * * @return DateTime */ - public function getCreatedAt() + public function getCreatedAt(): DateTime { return $this->createdAt; } @@ -183,9 +197,11 @@ public function getCreatedAt() /** * Set ticket. * - * @return $this + * @param TicketInterface|null $ticket + * + * @return TicketMessage|TicketMessageTrait|TicketMessageWithAttachment */ - public function setTicket(?TicketInterface $ticket = null) + public function setTicket(?TicketInterface $ticket = null): self { $this->ticket = $ticket; $user = $this->getUser(); diff --git a/Model/TicketTrait.php b/Model/TicketTrait.php index 1104611..c460022 100644 --- a/Model/TicketTrait.php +++ b/Model/TicketTrait.php @@ -14,8 +14,9 @@ namespace Hackzilla\Bundle\TicketBundle\Model; use DateTimeInterface; -use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; +use Hackzilla\Bundle\TicketBundle\Tests\Fixtures\Entity\Ticket; +use function array_key_exists; /** * Ticket Trait. @@ -25,9 +26,11 @@ trait TicketTrait /** * Set status. * - * @return $this + * @param int $status + * + * @return Ticket|TicketTrait */ - public function setStatus(int $status) + public function setStatus(int $status): self { $this->status = $status; @@ -37,9 +40,11 @@ public function setStatus(int $status) /** * Set status string. * - * @return $this + * @param string $status + * + * @return Ticket|TicketTrait */ - public function setStatusString(string $status) + public function setStatusString(string $status): self { $status = array_search(strtolower($status), TicketMessageInterface::STATUSES, true); @@ -63,7 +68,7 @@ public function getStatus(): ?int */ public function getStatusString(): ?string { - if (\array_key_exists($this->status, TicketMessageInterface::STATUSES)) { + if (array_key_exists($this->status, TicketMessageInterface::STATUSES)) { return TicketMessageInterface::STATUSES[$this->status]; } @@ -73,9 +78,11 @@ public function getStatusString(): ?string /** * Set priority. * - * @return $this + * @param int $priority + * + * @return Ticket|TicketTrait */ - public function setPriority(int $priority) + public function setPriority(int $priority): self { $this->priority = $priority; @@ -85,9 +92,11 @@ public function setPriority(int $priority) /** * Set priority string. * - * @return $this + * @param string $priority + * + * @return Ticket|TicketTrait */ - public function setPriorityString(string $priority) + public function setPriorityString(string $priority): self { $priority = array_search(strtolower($priority), TicketMessageInterface::PRIORITIES, true); @@ -111,7 +120,7 @@ public function getPriority(): ?int */ public function getPriorityString(): ?string { - if (\array_key_exists($this->priority, TicketMessageInterface::PRIORITIES)) { + if (array_key_exists($this->priority, TicketMessageInterface::PRIORITIES)) { return TicketMessageInterface::PRIORITIES[$this->priority]; } @@ -122,9 +131,11 @@ public function getPriorityString(): ?string * Set userCreated. * * - * @return $this + * @param UserInterface|null $userCreated + * + * @return Ticket|TicketTrait */ - public function setUserCreated(?UserInterface $userCreated) + public function setUserCreated(?UserInterface $userCreated): self { $this->userCreated = $userCreated; @@ -143,9 +154,11 @@ public function getUserCreated(): ?UserInterface * Set lastUser. * * - * @return $this + * @param UserInterface|null $lastUser + * + * @return Ticket|TicketTrait */ - public function setLastUser(?UserInterface $lastUser) + public function setLastUser(?UserInterface $lastUser): self { $this->lastUser = $lastUser; @@ -163,9 +176,11 @@ public function getLastUser(): ?UserInterface /** * Set lastMessage. * - * @return $this + * @param DateTimeInterface $lastMessage + * + * @return Ticket|TicketTrait */ - public function setLastMessage(DateTimeInterface $lastMessage) + public function setLastMessage(DateTimeInterface $lastMessage): self { $this->lastMessage = $lastMessage; @@ -183,9 +198,11 @@ public function getLastMessage(): ?DateTimeInterface /** * Set createdAt. * - * @return $this + * @param DateTimeInterface $createdAt + * + * @return Ticket|TicketTrait */ - public function setCreatedAt(DateTimeInterface $createdAt) + public function setCreatedAt(DateTimeInterface $createdAt): self { $this->createdAt = $createdAt; @@ -203,9 +220,11 @@ public function getCreatedAt(): ?DateTimeInterface /** * Set subject. * - * @return $this + * @param string $subject + * + * @return Ticket|TicketTrait */ - public function setSubject(string $subject) + public function setSubject(string $subject): self { $this->subject = $subject; @@ -223,9 +242,11 @@ public function getSubject(): ?string /** * Add message. * - * @return $this + * @param TicketMessageInterface $message + * + * @return Ticket|TicketTrait */ - public function addMessage(TicketMessageInterface $message) + public function addMessage(TicketMessageInterface $message): self { $this->messages[] = $message; @@ -235,9 +256,11 @@ public function addMessage(TicketMessageInterface $message) /** * Remove message. * - * @return $this + * @param TicketMessageInterface $message + * + * @return Ticket|TicketTrait */ - public function removeMessage(TicketMessageInterface $message) + public function removeMessage(TicketMessageInterface $message): self { $this->messages->removeElement($message); @@ -249,10 +272,6 @@ public function removeMessage(TicketMessageInterface $message) */ public function getMessages(): Collection { - if (null === $this->messages) { - $this->messages = new ArrayCollection(); - } - return $this->messages; } } diff --git a/Tests/Component/TicketFeaturesTest.php b/Tests/Component/TicketFeaturesTest.php index fc9148c..89b247f 100644 --- a/Tests/Component/TicketFeaturesTest.php +++ b/Tests/Component/TicketFeaturesTest.php @@ -38,7 +38,11 @@ public function constructProvider(): Iterator /** * @dataProvider featureAttachmentProvider * - * @param bool|null $compare + * @param array $features + * @param string $class + * @param bool $compare + * + * @return void */ public function testFeatureAttachment(array $features, string $class, bool $compare): void { diff --git a/Tests/Fixtures/Entity/Ticket.php b/Tests/Fixtures/Entity/Ticket.php index 5f2ef6c..f0e41eb 100644 --- a/Tests/Fixtures/Entity/Ticket.php +++ b/Tests/Fixtures/Entity/Ticket.php @@ -26,7 +26,7 @@ * @author Javier Spagnoletti * @author Daniel Platt */ -#[ORM\Entity()] +#[ORM\Entity] class Ticket implements TicketInterface { use TicketTrait; @@ -54,7 +54,7 @@ class Ticket implements TicketInterface /** * @var Collection */ - #[ORM\OneToMany(mappedBy: 'ticket', targetEntity: TicketMessage::class)] + #[ORM\OneToMany(targetEntity: TicketMessage::class, mappedBy: 'ticket')] private Collection $messages; #[ORM\ManyToOne(targetEntity: User::class)] diff --git a/Tests/Fixtures/Entity/TicketMessage.php b/Tests/Fixtures/Entity/TicketMessage.php index 139e7b0..6864dc5 100644 --- a/Tests/Fixtures/Entity/TicketMessage.php +++ b/Tests/Fixtures/Entity/TicketMessage.php @@ -24,7 +24,7 @@ * @author Javier Spagnoletti * @author Daniel Platt */ -#[ORM\Entity()] +#[ORM\Entity] class TicketMessage implements TicketMessageInterface { use TicketMessageTrait; diff --git a/Tests/Fixtures/Entity/TicketMessageWithAttachment.php b/Tests/Fixtures/Entity/TicketMessageWithAttachment.php index 327b90f..16acf8d 100644 --- a/Tests/Fixtures/Entity/TicketMessageWithAttachment.php +++ b/Tests/Fixtures/Entity/TicketMessageWithAttachment.php @@ -26,7 +26,7 @@ * @author Javier Spagnoletti * @author Daniel Platt */ -#[ORM\Entity()] +#[ORM\Entity] class TicketMessageWithAttachment implements TicketMessageInterface, MessageAttachmentInterface { use MessageAttachmentTrait; diff --git a/Tests/Fixtures/Entity/User.php b/Tests/Fixtures/Entity/User.php index ecad122..d20f698 100644 --- a/Tests/Fixtures/Entity/User.php +++ b/Tests/Fixtures/Entity/User.php @@ -21,7 +21,7 @@ * @author Javier Spagnoletti * @author Daniel Platt */ -#[ORM\Entity()] +#[ORM\Entity] #[ORM\Table(name: '`user`')] class User implements TicketBundleUserInterface { @@ -34,7 +34,7 @@ class User implements TicketBundleUserInterface private ?string $email = null; #[ORM\Column(type: Types::JSON)] - private $roles = []; + private array $roles = []; #[ORM\Column(type: Types::STRING)] private ?string $password = null; diff --git a/Tests/Form/Type/TicketMessageTypeTest.php b/Tests/Form/Type/TicketMessageTypeTest.php index 0ceea6f..30ff271 100644 --- a/Tests/Form/Type/TicketMessageTypeTest.php +++ b/Tests/Form/Type/TicketMessageTypeTest.php @@ -68,7 +68,7 @@ public function testSubmitValidData(): void } } - protected function getExtensions() + protected function getExtensions(): array { $ticketMessageType = new TicketMessageType($this->user, new TicketFeatures([], ''), TicketMessage::class); diff --git a/Tests/Form/Type/TicketTypeTest.php b/Tests/Form/Type/TicketTypeTest.php index 6c0cf73..572013b 100644 --- a/Tests/Form/Type/TicketTypeTest.php +++ b/Tests/Form/Type/TicketTypeTest.php @@ -63,7 +63,7 @@ public function testSubmitValidData(): void } } - protected function getExtensions() + protected function getExtensions(): array { $ticketType = new TicketType(Ticket::class); $ticketMessageType = new TicketMessageType($this->user, new TicketFeatures([], ''), TicketMessage::class); diff --git a/Tests/Functional/Command/ApplicationTest.php b/Tests/Functional/Command/ApplicationTest.php index c4bc114..c74b109 100644 --- a/Tests/Functional/Command/ApplicationTest.php +++ b/Tests/Functional/Command/ApplicationTest.php @@ -29,7 +29,7 @@ final class ApplicationTest extends WebTestCase */ public function testCommandRegistration(string $expectedClass, string $commandName): void { - $application = new Application(static::$kernel); + $application = new Application(ApplicationTest::$kernel); $this->assertInstanceOf($expectedClass, $application->find($commandName)); } diff --git a/Tests/Functional/RoutingTest.php b/Tests/Functional/RoutingTest.php index 85b0cc3..e7885f0 100644 --- a/Tests/Functional/RoutingTest.php +++ b/Tests/Functional/RoutingTest.php @@ -25,7 +25,7 @@ final class RoutingTest extends WebTestCase */ public function testRoutes(string $name, string $path, array $methods): void { - $client = static::createClient(); + $client = RoutingTest::createClient(); $router = $client->getContainer()->get('router'); $route = $router->getRouteCollection()->get($name); diff --git a/Tests/Functional/TestKernel.php b/Tests/Functional/TestKernel.php index 9402e83..1769df0 100644 --- a/Tests/Functional/TestKernel.php +++ b/Tests/Functional/TestKernel.php @@ -31,56 +31,27 @@ use Symfony\Component\Routing\RouteCollectionBuilder; use Vich\UploaderBundle\VichUploaderBundle; -if (Kernel::MAJOR_VERSION >= 5) { - trait ConfigureRoutes +trait ConfigureRoutes +{ + protected function configureRoutes(RoutingConfigurator $routes): void { - protected function configureRoutes(RoutingConfigurator $routes): void - { - $routes->import(__DIR__.'/routes.yaml', 'yaml'); - } + $routes->import(__DIR__.'/routes.yaml', 'yaml'); } +} - trait KernelDirectories +trait KernelDirectories +{ + public function getCacheDir(): string { - public function getCacheDir(): string - { - return $this->getBaseDir().'cache'; - } - - /** - * {@inheritdoc} - */ - public function getLogDir(): string - { - return $this->getBaseDir().'log'; - } - } -} else { - trait ConfigureRoutes - { - /** - * {@inheritdoc} - */ - protected function configureRoutes(RouteCollectionBuilder $routes) - { - $routes->import(__DIR__.'/routes.yaml', '/', 'yaml'); - } + return $this->getBaseDir().'cache'; } - trait KernelDirectories + /** + * {@inheritdoc} + */ + public function getLogDir(): string { - public function getCacheDir(): string - { - return $this->getBaseDir().'cache'; - } - - /** - * {@inheritdoc} - */ - public function getLogDir(): string - { - return $this->getBaseDir().'log'; - } + return $this->getBaseDir().'log'; } } @@ -128,9 +99,12 @@ public function registerBundles(): array } /** - * {@inheritdoc} + * @param ContainerBuilder $container + * @param LoaderInterface $loader + * + * @return void */ - protected function configureContainer(ContainerBuilder $c, LoaderInterface $loader) + protected function configureContainer(ContainerBuilder $container, LoaderInterface $loader): void { // FrameworkBundle config $frameworkConfig = [ @@ -152,7 +126,7 @@ protected function configureContainer(ContainerBuilder $c, LoaderInterface $load 'test' => true, ]; - $c->loadFromExtension('framework', $frameworkConfig); + $container->loadFromExtension('framework', $frameworkConfig); // SecurityBundle config $mainFirewallConfig = [ @@ -172,10 +146,10 @@ protected function configureContainer(ContainerBuilder $c, LoaderInterface $load ], ]; - $c->loadFromExtension('security', $securityConfig); + $container->loadFromExtension('security', $securityConfig); // DoctrineBundle config - $c->loadFromExtension('doctrine', [ + $container->loadFromExtension('doctrine', [ 'dbal' => [ 'connections' => [ 'default' => [ @@ -205,7 +179,7 @@ protected function configureContainer(ContainerBuilder $c, LoaderInterface $load ]; // "default_path" configuration is available since version 3.4. $twigConfig['default_path'] = __DIR__.'/Resources/views'; - $c->loadFromExtension('twig', $twigConfig); + $container->loadFromExtension('twig', $twigConfig); // HackzillaBundle config $bundleConfig = [ @@ -218,11 +192,11 @@ protected function configureContainer(ContainerBuilder $c, LoaderInterface $load $bundleConfig['message_class'] = TicketMessageWithAttachment::class; } - $c->loadFromExtension('hackzilla_ticket', $bundleConfig); + $container->loadFromExtension('hackzilla_ticket', $bundleConfig); if ($this->useVichUploaderBundle) { // VichUploaderBundle config - $c->loadFromExtension('vich_uploader', [ + $container->loadFromExtension('vich_uploader', [ 'db_driver' => 'orm', ]); } diff --git a/Tests/Functional/WebTestCase.php b/Tests/Functional/WebTestCase.php index a6ff163..c5067aa 100644 --- a/Tests/Functional/WebTestCase.php +++ b/Tests/Functional/WebTestCase.php @@ -13,28 +13,14 @@ namespace Hackzilla\Bundle\TicketBundle\Tests\Functional; -use Symfony\Component\HttpKernel\Kernel; use Symfony\Bundle\FrameworkBundle\Test\WebTestCase as BaseWebTestCase; use Symfony\Component\HttpKernel\KernelInterface; -if (Kernel::MAJOR_VERSION >= 6) { - trait CreateKernel - { - protected static function createKernel(array $options = []): KernelInterface - { - return new TestKernel(); - } - } -} else { - trait CreateKernel +trait CreateKernel +{ + protected static function createKernel(array $options = []): KernelInterface { - /** - * @return KernelInterface - */ - protected static function createKernel(array $options = []): TestKernel - { - return new TestKernel(); - } + return new TestKernel(); } } diff --git a/TwigExtension/TicketFeatureExtension.php b/TwigExtension/TicketFeatureExtension.php index 3951192..6760043 100644 --- a/TwigExtension/TicketFeatureExtension.php +++ b/TwigExtension/TicketFeatureExtension.php @@ -36,7 +36,7 @@ public function hasFeature(string $feature): ?bool } /** - * {@inheritdoc} + * @return string */ public function getName(): string { From 1cac9de7ba2a4cccc10965408b7b8ad2c1ec4890 Mon Sep 17 00:00:00 2001 From: Regis Grison Date: Tue, 5 Nov 2024 11:41:28 +0100 Subject: [PATCH 08/18] fix fatal errors --- Maker/Util/ClassSourceManipulator.php | 2 +- Manager/TicketManager.php | 10 +++++----- Manager/TicketManagerInterface.php | 8 ++++---- Model/MessageAttachmentInterface.php | 16 ++++++++-------- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/Maker/Util/ClassSourceManipulator.php b/Maker/Util/ClassSourceManipulator.php index 2a34340..b36f7bf 100644 --- a/Maker/Util/ClassSourceManipulator.php +++ b/Maker/Util/ClassSourceManipulator.php @@ -878,7 +878,7 @@ private function createDocBlock(array $commentLines): string private function addMethod(ClassMethod $methodNode): void { $classNode = $this->getClassNode(); - $methodName = $methodNode->name; + $methodName = $methodNode->name->toString(); $existingIndex = null; if ($this->methodExists($methodName)) { if (!$this->overwrite) { diff --git a/Manager/TicketManager.php b/Manager/TicketManager.php index 106c645..1be0f2c 100644 --- a/Manager/TicketManager.php +++ b/Manager/TicketManager.php @@ -233,7 +233,7 @@ public function getTicketListQuery($ticketStatus, $ticketPriority = null): Query * @return mixed * @throws DateMalformedIntervalStringException */ - public function getResolvedTicketOlderThan(int $days) + public function getResolvedTicketOlderThan(int $days): mixed { $closeBeforeDate = new DateTime(); $closeBeforeDate->sub(new DateInterval('P'.$days.'D')); @@ -254,9 +254,9 @@ public function getResolvedTicketOlderThan(int $days) * * @param string $statusStr * - * @return int|string|false + * @return int|string|bool */ - public function getTicketStatus(string $statusStr): int|string|false + public function getTicketStatus(string $statusStr): int|string|bool { static $statuses = false; @@ -276,9 +276,9 @@ public function getTicketStatus(string $statusStr): int|string|false * * @param string $priorityStr * - * @return int|string|false + * @return int|string|bool */ - public function getTicketPriority(string $priorityStr): int|string|false + public function getTicketPriority(string $priorityStr): int|string|bool { static $priorities = false; diff --git a/Manager/TicketManagerInterface.php b/Manager/TicketManagerInterface.php index 2d3a909..af84e15 100644 --- a/Manager/TicketManagerInterface.php +++ b/Manager/TicketManagerInterface.php @@ -49,16 +49,16 @@ public function getResolvedTicketOlderThan(int $days): mixed; * * @param string $statusStr * - * @return int + * @return int|string|bool */ - public function getTicketStatus(string $statusStr): int; + public function getTicketStatus(string $statusStr): int|string|bool; /** * Lookup priority code. * * @param string $priorityStr * - * @return int + * @return int|string|bool */ - public function getTicketPriority(string $priorityStr): int; + public function getTicketPriority(string $priorityStr): int|string|bool; } diff --git a/Model/MessageAttachmentInterface.php b/Model/MessageAttachmentInterface.php index e723333..eb3c80c 100644 --- a/Model/MessageAttachmentInterface.php +++ b/Model/MessageAttachmentInterface.php @@ -25,9 +25,9 @@ interface MessageAttachmentInterface extends TicketMessageInterface public function setAttachmentFile(?File $file = null): self; /** - * @return File + * @return File|null */ - public function getAttachmentFile(): File; + public function getAttachmentFile(): ?File; /** * @return $this @@ -35,9 +35,9 @@ public function getAttachmentFile(): File; public function setAttachmentName(string $name): self; /** - * @return string + * @return string|null */ - public function getAttachmentName(): string; + public function getAttachmentName(): ?string; /** * @param int $size Size in bytes @@ -47,9 +47,9 @@ public function getAttachmentName(): string; public function setAttachmentSize(int $size): self; /** - * @return string + * @return int|null */ - public function getAttachmentSize(): string; + public function getAttachmentSize(): ?int; /** * @param string $mimeType Attachment mime type @@ -59,7 +59,7 @@ public function getAttachmentSize(): string; public function setAttachmentMimeType(string $mimeType): self; /** - * @return string + * @return string|null */ - public function getAttachmentMimeType(): string; + public function getAttachmentMimeType(): ?string; } From 8ec6401312985ae05dbf505f10ee8d01e612b1d7 Mon Sep 17 00:00:00 2001 From: Regis Grison Date: Tue, 5 Nov 2024 11:57:40 +0100 Subject: [PATCH 09/18] fix some more syntax --- Maker/AbstractMaker.php | 34 +++------------------------ Maker/Util/ClassSourceManipulator.php | 18 ++++++++------ Manager/TicketManager.php | 18 +++++++------- Tests/Manager/UserManagerTest.php | 3 +-- 4 files changed, 24 insertions(+), 49 deletions(-) diff --git a/Maker/AbstractMaker.php b/Maker/AbstractMaker.php index b71248c..0408e2f 100644 --- a/Maker/AbstractMaker.php +++ b/Maker/AbstractMaker.php @@ -115,10 +115,7 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen throw new RuntimeCommandException('To use Doctrine entity attributes you\'ll need PHP 8, doctrine/orm 2.9, doctrine/doctrine-bundle 2.4 and symfony/framework-bundle 5.2.'); } - if ( - !$this->doesEntityUseAnnotationMapping($entityClassDetails->getFullName()) - && !$this->doesEntityUseAttributeMapping($entityClassDetails->getFullName()) - ) { + if (!$this->doesEntityUseAttributeMapping($entityClassDetails->getFullName())) { throw new RuntimeCommandException(sprintf('Only annotation or attribute mapping is supported by this command, but the %s class uses a different format.', $entityClassDetails->getFullName())); } @@ -225,17 +222,12 @@ abstract protected function interfaces(): array; private function createClassManipulator(string $path, ConsoleStyle $io, bool $overwrite, string $className, bool $originalClass = true): ClassSourceManipulator { $useAttributes = $this->doctrineHelper->doesClassUsesAttributes($className) && $this->doctrineHelper->isDoctrineSupportingAttributes(); - $useAnnotations = false ; - if (method_exists($this->doctrineHelper, 'isClassAnnotated')) { - $useAnnotations = $this->doctrineHelper->isClassAnnotated($className) ||!$useAttributes; - } - - if (!$useAnnotations && !$useAttributes) { + if (!$useAttributes) { throw new Exception('No support for either Annotations or Attributes'); } - $manipulator = new ClassSourceManipulator($this->fileManager->getFileContents($path), $overwrite, $useAnnotations, $useAttributes); + $manipulator = new ClassSourceManipulator($this->fileManager->getFileContents($path), $overwrite, false, true); if ($originalClass) { foreach ($this->traits() as $trait) { @@ -271,26 +263,6 @@ private function getPropertyNames(string $class): array return array_map(static fn(ReflectionProperty $prop): string => $prop->getName(), $reflClass->getProperties()); } - private function doesEntityUseAnnotationMapping(string $className): bool - { - if (!class_exists($className)) { - $otherClassMetadatas = $this->doctrineHelper->getMetadata(Str::getNamespace($className).'\\', true); - - // if we have no metadata, we should assume this is the first class being mapped - if (empty($otherClassMetadatas)) { - return false; - } - - $className = reset($otherClassMetadatas)->getName(); - } - - if (!method_exists($this->doctrineHelper, 'isClassAnnotated')) { - return false; - } - - return $this->doctrineHelper->isClassAnnotated($className); - } - private function doesEntityUseAttributeMapping(string $className): bool { if (!class_exists($className)) { diff --git a/Maker/Util/ClassSourceManipulator.php b/Maker/Util/ClassSourceManipulator.php index b36f7bf..e6ad230 100644 --- a/Maker/Util/ClassSourceManipulator.php +++ b/Maker/Util/ClassSourceManipulator.php @@ -15,6 +15,7 @@ namespace Hackzilla\Bundle\TicketBundle\Maker\Util; use PhpParser\Lexer\Emulative; +use PhpParser\Node; use PhpParser\Parser\Php7; use PhpParser\Node\Stmt\Expression; use PhpParser\Node\Expr\Assign; @@ -32,6 +33,7 @@ use PhpParser\Node\Stmt\Class_; use Exception; use PhpParser\Node\Stmt; +use PHPStan\Php\PhpVersion; use ReflectionClass; use PhpParser\Node\Expr\StaticCall; use PhpParser\Node\Identifier; @@ -51,7 +53,7 @@ use PhpParser\Node\Scalar\LNumber; use PhpParser\Node\Scalar\DNumber; use PhpParser\Node\Expr\ConstFetch; -use PhpParser\Node\Expr\ArrayItem; +use PhpParser\Node\ArrayItem; use PhpParser\Node\Attribute; use PhpParser\Node\Arg; use ReflectionParameter; @@ -59,7 +61,6 @@ use PhpParser\Builder; use PhpParser\BuilderHelpers; use PhpParser\Comment\Doc; -use PhpParser\Node; use PhpParser\NodeTraverser; use Symfony\Bundle\MakerBundle\ConsoleStyle; use Symfony\Bundle\MakerBundle\Doctrine\BaseCollectionRelation; @@ -105,6 +106,9 @@ final class ClassSourceManipulator public function __construct(string $sourceCode, private readonly bool $overwrite = false, private readonly bool $useAnnotations = true, private readonly bool $useAttributesForDoctrineMapping = false) { + $this->lexer = new Emulative(null); + + /* $this->lexer = new Emulative([ 'usedAttributes' => [ 'comments', @@ -112,6 +116,8 @@ public function __construct(string $sourceCode, private readonly bool $overwrite 'startTokenPos', 'endTokenPos', ], ]); + */ + $this->parser = new Php7($this->lexer); $this->printer = new PrettyPrinter(); @@ -215,7 +221,7 @@ public function addInterface(string $interfaceName): void { $this->addUseStatementIfNecessary($interfaceName); - foreach ($this->getClassNode()->implements as $node) { + foreach ($this->getClassNode()->implements as $node) { if (implode('\\', $node->getAttribute('resolvedName')->parts) === $interfaceName) { return; } @@ -758,7 +764,7 @@ private function setSourceCode(string $sourceCode): void /** * @throws Exception */ - private function getClassNode(): Class_ + private function getClassNode(): Node { $node = $this->findFirstNode(static fn($node): bool => $node instanceof Class_); @@ -766,14 +772,13 @@ private function getClassNode(): Class_ throw new Exception('Could not find class node'); } - /* @phpstan-ignore-next-line */ return $node; } /** * @throws Exception */ - private function getNamespaceNode(): Namespace_ + private function getNamespaceNode(): Node { $node = $this->findFirstNode(static fn($node): bool => $node instanceof Namespace_); @@ -781,7 +786,6 @@ private function getNamespaceNode(): Namespace_ throw new Exception('Could not find namespace node'); } - /* @phpstan-ignore-next-line */ return $node; } diff --git a/Manager/TicketManager.php b/Manager/TicketManager.php index 1be0f2c..e384d20 100644 --- a/Manager/TicketManager.php +++ b/Manager/TicketManager.php @@ -16,9 +16,9 @@ use DateMalformedIntervalStringException; use DateTime; use DateInterval; +use Doctrine\ORM\EntityManagerInterface; +use Doctrine\ORM\EntityRepository; use Doctrine\ORM\QueryBuilder; -use Doctrine\Persistence\ObjectManager; -use Doctrine\Persistence\ObjectRepository; use Hackzilla\Bundle\TicketBundle\Model\TicketInterface; use Hackzilla\Bundle\TicketBundle\Model\TicketMessageInterface; use Psr\Log\LoggerInterface; @@ -33,11 +33,11 @@ final class TicketManager implements TicketManagerInterface private string $translationDomain = 'HackzillaTicketBundle'; - private ?ObjectManager $objectManager = null; + private ?EntityManagerInterface $objectManager = null; - private ObjectRepository $ticketRepository; + private EntityRepository $ticketRepository; - private ObjectRepository $messageRepository; + private EntityRepository $messageRepository; /** * TicketManager constructor. @@ -58,7 +58,7 @@ public function setLogger(LoggerInterface $logger): self return $this; } - public function setObjectManager(ObjectManager $objectManager): self + public function setObjectManager(EntityManagerInterface $objectManager): self { $this->objectManager = $objectManager; @@ -274,11 +274,11 @@ public function getTicketStatus(string $statusStr): int|string|bool /** * Lookup priority code. * - * @param string $priorityStr + * @param string|null $priorityStr * * @return int|string|bool */ - public function getTicketPriority(string $priorityStr): int|string|bool + public function getTicketPriority(?string $priorityStr): int|string|bool { static $priorities = false; @@ -290,6 +290,6 @@ public function getTicketPriority(string $priorityStr): int|string|bool } } - return array_search($priorityStr, $priorities, true); + return array_search($priorityStr ?? '', $priorities, true); } } diff --git a/Tests/Manager/UserManagerTest.php b/Tests/Manager/UserManagerTest.php index dd99b20..7b03732 100644 --- a/Tests/Manager/UserManagerTest.php +++ b/Tests/Manager/UserManagerTest.php @@ -13,7 +13,6 @@ namespace Hackzilla\Bundle\TicketBundle\Tests\User; -use PHPUnit\Framework\MockObject\MockObject; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityRepository; use Doctrine\ORM\Mapping\ClassMetadata; @@ -56,7 +55,7 @@ private function getMockUserRepository(): EntityRepository return new EntityRepository($em, new ClassMetadata(User::class)); } - private function getAuthorizationChecker(): MockObject + private function getAuthorizationChecker(): AuthorizationChecker { return $this->createMock(AuthorizationChecker::class); } From f03044753d4ff51639ce76ac23ce9522ea56ef92 Mon Sep 17 00:00:00 2001 From: Regis Grison Date: Tue, 5 Nov 2024 12:20:00 +0100 Subject: [PATCH 10/18] add twig to controller using constructor --- Controller/TicketController.php | 48 ++++++++++++++++++++++++++------ Resources/config/controllers.php | 3 ++ 2 files changed, 42 insertions(+), 9 deletions(-) diff --git a/Controller/TicketController.php b/Controller/TicketController.php index 351aee0..22c762b 100644 --- a/Controller/TicketController.php +++ b/Controller/TicketController.php @@ -34,6 +34,10 @@ use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; use Symfony\Contracts\Translation\TranslatorInterface; +use Twig\Environment; +use Twig\Error\LoaderError; +use Twig\Error\RuntimeError; +use Twig\Error\SyntaxError; use function is_object; /** @@ -49,13 +53,21 @@ public function __construct( ParameterBagInterface $bag, private readonly TicketManager $ticketManager, private readonly TranslatorInterface $translator, - private readonly UserManagerInterface $userManager + private readonly UserManagerInterface $userManager, + private readonly Environment $twig ) { $this->templates = $bag->get('hackzilla_ticket.templates'); } /** * Lists all Ticket entities. + * + * @param Request $request + * + * @return Response + * @throws LoaderError + * @throws RuntimeError + * @throws SyntaxError */ public function index(Request $request): Response { @@ -75,7 +87,7 @@ public function index(Request $request): Response 10/* limit per page */ ); - return $this->render( + return new Response($this->twig->render( $this->templates['index'], [ 'pagination' => $pagination, @@ -83,11 +95,18 @@ public function index(Request $request): Response 'ticketPriority' => $ticketPriority, 'translationDomain' => 'HackzillaTicketBundle', ] - ); + )); } /** * Creates a new Ticket entity. + * + * @param Request $request + * + * @return RedirectResponse|Response + * @throws LoaderError + * @throws RuntimeError + * @throws SyntaxError */ public function create(Request $request): RedirectResponse|Response { @@ -110,18 +129,23 @@ public function create(Request $request): RedirectResponse|Response return $this->redirectToRoute('hackzilla_ticket_show', ['ticketId' => $ticket->getId()]); } - return $this->render( + return new Response($this->twig->render( $this->templates['new'], [ 'entity' => $ticket, 'form' => $form->createView(), 'translationDomain' => 'HackzillaTicketBundle', ] - ); + )); } /** * Displays a form to create a new Ticket entity. + * + * @return Response + * @throws LoaderError + * @throws RuntimeError + * @throws SyntaxError */ public function new(): Response { @@ -130,14 +154,14 @@ public function new(): Response $form = $this->createForm(TicketType::class, $entity); - return $this->render( + return new Response($this->twig->render( $this->templates['new'], [ 'entity' => $entity, 'form' => $form->createView(), 'translationDomain' => 'HackzillaTicketBundle', ] - ); + )); } /** @@ -146,6 +170,9 @@ public function new(): Response * @param int $ticketId * * @return RedirectResponse|Response + * @throws LoaderError + * @throws RuntimeError + * @throws SyntaxError */ public function show(int $ticketId): RedirectResponse|Response { @@ -174,7 +201,7 @@ public function show(int $ticketId): RedirectResponse|Response $data['delete_form'] = $this->createDeleteForm($ticket->getId())->createView(); } - return $this->render($this->templates['show'], $data); + return new Response($this->twig->render($this->templates['show'], $data)); } /** @@ -184,6 +211,9 @@ public function show(int $ticketId): RedirectResponse|Response * @param int $ticketId * * @return RedirectResponse|Response + * @throws LoaderError + * @throws RuntimeError + * @throws SyntaxError */ public function reply(Request $request, int $ticketId): RedirectResponse|Response { @@ -219,7 +249,7 @@ public function reply(Request $request, int $ticketId): RedirectResponse|Respons $data['delete_form'] = $this->createDeleteForm($ticket->getId())->createView(); } - return $this->render($this->templates['show'], $data); + return new Response($this->twig->render($this->templates['show'], $data)); } /** diff --git a/Resources/config/controllers.php b/Resources/config/controllers.php index 29487cd..5e0e5c8 100644 --- a/Resources/config/controllers.php +++ b/Resources/config/controllers.php @@ -10,6 +10,8 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ + +use Twig\Environment; use Vich\UploaderBundle\Handler\DownloadHandler; use Hackzilla\Bundle\TicketBundle\Controller\TicketAttachmentController; use Hackzilla\Bundle\TicketBundle\Controller\TicketController; @@ -46,6 +48,7 @@ new ReferenceConfigurator(TicketManagerInterface::class), new ReferenceConfigurator('translator'), new ReferenceConfigurator(UserManagerInterface::class), + new ReferenceConfigurator(Environment::class), ]) ->call('setContainer', [new ReferenceConfigurator('service_container')]) ->tag('controller.service_arguments') From 93034109587b958317e7faa76a1869141c5d05fb Mon Sep 17 00:00:00 2001 From: Regis Grison Date: Tue, 5 Nov 2024 12:22:48 +0100 Subject: [PATCH 11/18] update template name --- Resources/views/Ticket/index.html.twig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Resources/views/Ticket/index.html.twig b/Resources/views/Ticket/index.html.twig index 424231e..d533060 100644 --- a/Resources/views/Ticket/index.html.twig +++ b/Resources/views/Ticket/index.html.twig @@ -67,7 +67,7 @@ {% endblock %} From e690d136b7485741d5b1c3ca14ee262dd3cc71fa Mon Sep 17 00:00:00 2001 From: Regis Grison Date: Tue, 5 Nov 2024 12:36:29 +0100 Subject: [PATCH 12/18] fix fom.factory error --- Controller/TicketController.php | 6 ++++-- Resources/config/controllers.php | 2 ++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Controller/TicketController.php b/Controller/TicketController.php index 22c762b..4ac3c9f 100644 --- a/Controller/TicketController.php +++ b/Controller/TicketController.php @@ -13,6 +13,7 @@ namespace Hackzilla\Bundle\TicketBundle\Controller; +use Symfony\Component\Form\FormFactoryInterface; use Symfony\Component\HttpKernel\Exception\HttpException; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\RedirectResponse; @@ -54,7 +55,8 @@ public function __construct( private readonly TicketManager $ticketManager, private readonly TranslatorInterface $translator, private readonly UserManagerInterface $userManager, - private readonly Environment $twig + private readonly Environment $twig, + private readonly FormFactoryInterface $formFactory ) { $this->templates = $bag->get('hackzilla_ticket.templates'); } @@ -152,7 +154,7 @@ public function new(): Response $ticketManager = $this->ticketManager; $entity = $ticketManager->createTicket(); - $form = $this->createForm(TicketType::class, $entity); + $form = $this->formFactory->create(TicketType::class, $entity); return new Response($this->twig->render( $this->templates['new'], diff --git a/Resources/config/controllers.php b/Resources/config/controllers.php index 5e0e5c8..0fb7f1b 100644 --- a/Resources/config/controllers.php +++ b/Resources/config/controllers.php @@ -11,6 +11,7 @@ * file that was distributed with this source code. */ +use Symfony\Component\Form\FormFactoryInterface; use Twig\Environment; use Vich\UploaderBundle\Handler\DownloadHandler; use Hackzilla\Bundle\TicketBundle\Controller\TicketAttachmentController; @@ -49,6 +50,7 @@ new ReferenceConfigurator('translator'), new ReferenceConfigurator(UserManagerInterface::class), new ReferenceConfigurator(Environment::class), + new ReferenceConfigurator(FormFactoryInterface::class), ]) ->call('setContainer', [new ReferenceConfigurator('service_container')]) ->tag('controller.service_arguments') From 1842a53e9e49d41e0604b236dbc4b4b614651881 Mon Sep 17 00:00:00 2001 From: Regis Grison Date: Tue, 5 Nov 2024 14:02:06 +0100 Subject: [PATCH 13/18] fix twig global variable --- HackzillaTicketBundle.php | 15 +++++++++++++++ Resources/config/services.yaml | 5 +++++ 2 files changed, 20 insertions(+) create mode 100644 Resources/config/services.yaml diff --git a/HackzillaTicketBundle.php b/HackzillaTicketBundle.php index 4ea7d1a..bb7da53 100644 --- a/HackzillaTicketBundle.php +++ b/HackzillaTicketBundle.php @@ -13,8 +13,23 @@ namespace Hackzilla\Bundle\TicketBundle; +use Exception; +use Symfony\Component\Config\FileLocator; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; use Symfony\Component\HttpKernel\Bundle\Bundle; class HackzillaTicketBundle extends Bundle { + /** + * @throws Exception + */ + public function build(ContainerBuilder $container): void + { + parent::build($container); + + // Chargement du fichier de services + $loader = new YamlFileLoader($container, new FileLocator(__DIR__.'/Resources/config')); + $loader->load('services.yaml'); + } } diff --git a/Resources/config/services.yaml b/Resources/config/services.yaml new file mode 100644 index 0000000..b4b29db --- /dev/null +++ b/Resources/config/services.yaml @@ -0,0 +1,5 @@ +services: + Hackzilla\Bundle\TicketBundle\TwigExtension\TicketGlobalExtension: + arguments: + $templates: '%hackzilla_ticket.templates%' + tags: ['twig.extension'] From 854a30e30e425cccbb1c923b3f3be2aa90e14fb5 Mon Sep 17 00:00:00 2001 From: Regis Grison Date: Tue, 5 Nov 2024 14:06:49 +0100 Subject: [PATCH 14/18] fix others form.factory errors --- Controller/TicketController.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Controller/TicketController.php b/Controller/TicketController.php index 4ac3c9f..0890779 100644 --- a/Controller/TicketController.php +++ b/Controller/TicketController.php @@ -115,7 +115,7 @@ public function create(Request $request): RedirectResponse|Response $ticketManager = $this->ticketManager; $ticket = $ticketManager->createTicket(); - $form = $this->createForm(TicketType::class, $ticket); + $form = $this->formFactory->create(TicketType::class, $ticket); $form->handleRequest($request); if ($form->isValid()) { @@ -313,7 +313,7 @@ private function createDeleteForm(mixed $id): FormInterface private function createMessageForm(TicketMessageInterface $message): FormInterface { - return $this->createForm( + return $this->formFactory->create( TicketMessageType::class, $message, [ From 50d71ce2bf3740bb4a9910d720cdb43ca314353f Mon Sep 17 00:00:00 2001 From: Regis Grison Date: Tue, 5 Nov 2024 14:11:55 +0100 Subject: [PATCH 15/18] add second twig file --- Resources/config/services.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Resources/config/services.yaml b/Resources/config/services.yaml index b4b29db..d376ff6 100644 --- a/Resources/config/services.yaml +++ b/Resources/config/services.yaml @@ -3,3 +3,8 @@ services: arguments: $templates: '%hackzilla_ticket.templates%' tags: ['twig.extension'] + + Hackzilla\Bundle\TicketBundle\TwigExtension\TicketFeatureExtension: + arguments: + $ticketFeatures: '@hackzilla_ticket.features' # Injection de service existant (à adapter si différent) + tags: ['twig.extension'] From 016f32dbac0631fe5c0423dfb8f5b280ddac5bbe Mon Sep 17 00:00:00 2001 From: Regis Grison Date: Wed, 27 Nov 2024 17:44:38 +0100 Subject: [PATCH 16/18] fix local phpstan errors --- Maker/Util/ClassSourceManipulator.php | 198 +++++++++++++++----------- 1 file changed, 113 insertions(+), 85 deletions(-) diff --git a/Maker/Util/ClassSourceManipulator.php b/Maker/Util/ClassSourceManipulator.php index e6ad230..f393d5b 100644 --- a/Maker/Util/ClassSourceManipulator.php +++ b/Maker/Util/ClassSourceManipulator.php @@ -221,13 +221,16 @@ public function addInterface(string $interfaceName): void { $this->addUseStatementIfNecessary($interfaceName); - foreach ($this->getClassNode()->implements as $node) { - if (implode('\\', $node->getAttribute('resolvedName')->parts) === $interfaceName) { - return; + if (!empty($this->getClassNode()->implements)) { + foreach ($this->getClassNode()->implements as $node) { + if (implode('\\', $node->getAttribute('resolvedName')->parts) === $interfaceName) { + return; + } } + + $this->getClassNode()->implements[] = new Name(Str::getShortClassName($interfaceName)); } - $this->getClassNode()->implements[] = new Name(Str::getShortClassName($interfaceName)); $this->updateSourceCodeFromNewStmts(); } @@ -259,13 +262,15 @@ public function addTrait(string $trait): void // avoid all the use traits in class for unshift all the new UseTrait // in the right order. - foreach ($classNode->stmts as $key => $node) { - if ($node instanceof TraitUse) { - unset($classNode->stmts[$key]); + if (!empty($classNode->stmts)) { + foreach ($classNode->stmts as $key => $node) { + if ($node instanceof TraitUse) { + unset($classNode->stmts[$key]); + } } - } - array_unshift($classNode->stmts, ...$traitNodes); + array_unshift($classNode->stmts, ...$traitNodes); + } $this->updateSourceCodeFromNewStmts(); } @@ -442,64 +447,66 @@ public function addUseStatementIfNecessary(string $class): string $targetIndex = null; $addLineBreak = false; $lastUseStmtIndex = null; - foreach ($namespaceNode->stmts as $index => $stmt) { - if ($stmt instanceof Use_) { - // I believe this is an array to account for use statements with {} - foreach ($stmt->uses as $use) { - $alias = $use->alias ? $use->alias->name : $use->name->getLast(); - - // the use statement already exists? Don't add it again - if ($class === (string) $use->name) { - return $alias; + if (!empty($namespaceNode->stmts)) { + foreach ($namespaceNode->stmts as $index => $stmt) { + if ($stmt instanceof Use_) { + // I believe this is an array to account for use statements with {} + foreach ($stmt->uses as $use) { + $alias = $use->alias ? $use->alias->name : $use->name->getLast(); + + // the use statement already exists? Don't add it again + if ($class === (string)$use->name) { + return $alias; + } + + if ($alias === $shortClassName) { + // we have a conflicting alias! + // to be safe, use the fully-qualified class name + // everywhere and do not add another use statement + return '\\'.$class; + } } - if ($alias === $shortClassName) { - // we have a conflicting alias! - // to be safe, use the fully-qualified class name - // everywhere and do not add another use statement - return '\\'.$class; + // if $class is alphabetically before this use statement, place it before + // only set $targetIndex the first time you find it + if (null === $targetIndex && Str::areClassesAlphabetical($class, (string)$stmt->uses[0]->name)) { + $targetIndex = $index; } - } - // if $class is alphabetically before this use statement, place it before - // only set $targetIndex the first time you find it - if (null === $targetIndex && Str::areClassesAlphabetical($class, (string) $stmt->uses[0]->name)) { - $targetIndex = $index; - } + $lastUseStmtIndex = $index; + } elseif ($stmt instanceof Class_) { + if (null !== $targetIndex) { + // we already found where to place the use statement - $lastUseStmtIndex = $index; - } elseif ($stmt instanceof Class_) { - if (null !== $targetIndex) { - // we already found where to place the use statement + break; + } - break; - } + // we hit the class! If there were any use statements, + // then put this at the bottom of the use statement list + if (null !== $lastUseStmtIndex) { + $targetIndex = $lastUseStmtIndex + 1; + } else { + $targetIndex = $index; + $addLineBreak = true; + } - // we hit the class! If there were any use statements, - // then put this at the bottom of the use statement list - if (null !== $lastUseStmtIndex) { - $targetIndex = $lastUseStmtIndex + 1; - } else { - $targetIndex = $index; - $addLineBreak = true; + break; } + } - break; + if (null === $targetIndex) { + throw new Exception('Could not find a class!'); } - } - if (null === $targetIndex) { - throw new Exception('Could not find a class!'); + $newUseNode = (new Builder\Use_($class, Use_::TYPE_NORMAL))->getNode(); + array_splice( + $namespaceNode->stmts, + $targetIndex, + 0, + $addLineBreak ? [$newUseNode, $this->createBlankLineNode(self::CONTEXT_OUTSIDE_CLASS)] : [$newUseNode] + ); } - $newUseNode = (new Builder\Use_($class, Use_::TYPE_NORMAL))->getNode(); - array_splice( - $namespaceNode->stmts, - $targetIndex, - 0, - $addLineBreak ? [$newUseNode, $this->createBlankLineNode(self::CONTEXT_OUTSIDE_CLASS)] : [$newUseNode] - ); - $this->updateSourceCodeFromNewStmts(); return $shortClassName; @@ -708,9 +715,11 @@ private function addStatementToConstructor(Stmt $stmt): void */ private function getConstructorNode(): ?ClassMethod { - foreach ($this->getClassNode()->stmts as $classNode) { - if ($classNode instanceof ClassMethod && '__construct' == $classNode->name) { - return $classNode; + if (!empty($this->getClassNode()->stmts)) { + foreach ($this->getClassNode()->stmts as $classNode) { + if ($classNode instanceof ClassMethod && '__construct' == $classNode->name) { + return $classNode; + } } } @@ -751,7 +760,9 @@ private function setSourceCode(string $sourceCode): void { $this->sourceCode = $sourceCode; $this->oldStmts = $this->parser->parse($sourceCode); - $this->oldTokens = $this->lexer->getTokens(); + if (method_exists($this->lexer, 'getTokens')) { + $this->oldTokens = $this->lexer->getTokens(); + } $traverser = new NodeTraverser(); $traverser->addVisitor(new CloningVisitor()); @@ -908,17 +919,19 @@ private function addMethod(ClassMethod $methodNode): void $newStatements[] = $methodNode; - if (null === $existingIndex) { - // add them to the end! + if (!empty($classNode->stmts)) { + if (null === $existingIndex) { + // add them to the end! - $classNode->stmts = array_merge($classNode->stmts, $newStatements); - } else { - array_splice( - $classNode->stmts, - $existingIndex, - 1, - $newStatements - ); + $classNode->stmts = array_merge($classNode->stmts, $newStatements); + } else { + array_splice( + $classNode->stmts, + $existingIndex, + 1, + $newStatements + ); + } } $this->updateSourceCodeFromNewStmts(); @@ -946,7 +959,11 @@ private function isInSameNamespace(string $class): bool { $namespace = substr($class, 0, strrpos($class, '\\')); - return $this->getNamespaceNode()->name->toCodeString() === $namespace; + if (!empty($this->getNamespaceNode()->name)) { + return $this->getNamespaceNode()->name->toCodeString() === $namespace; + } + + return false; } /** @@ -954,7 +971,11 @@ private function isInSameNamespace(string $class): bool */ private function getThisFullClassName(): string { - return (string) $this->getClassNode()->namespacedName; + if (!empty($this->getClassNode()->namespacedName)) { + return (string)$this->getClassNode()->namespacedName; + } + + return ''; } /** @@ -982,14 +1003,16 @@ private function addNodeAfterProperties(Node $newNode): void // add the new property after this node if ($targetNode instanceof Node) { - $index = array_search($targetNode, $classNode->stmts, true); - - array_splice( - $classNode->stmts, - $index + 1, - 0, - [$this->createBlankLineNode(self::CONTEXT_CLASS), $newNode] - ); + if (!empty($classNode->stmts)) { + $index = array_search($targetNode, $classNode->stmts, true); + + array_splice( + $classNode->stmts, + $index + 1, + 0, + [$this->createBlankLineNode(self::CONTEXT_CLASS), $newNode] + ); + } $this->updateSourceCodeFromNewStmts(); @@ -1000,8 +1023,9 @@ private function addNodeAfterProperties(Node $newNode): void // add an empty line, unless the class is totally empty if (!empty($classNode->stmts)) { array_unshift($classNode->stmts, $this->createBlankLineNode(self::CONTEXT_CLASS)); + array_unshift($classNode->stmts, $newNode); } - array_unshift($classNode->stmts, $newNode); + $this->updateSourceCodeFromNewStmts(); } @@ -1018,9 +1042,11 @@ private function methodExists(string $methodName): bool */ private function getMethodIndex(string $methodName): bool|int|string { - foreach ($this->getClassNode()->stmts as $i => $node) { - if ($node instanceof ClassMethod && strtolower($node->name->toString()) === strtolower($methodName)) { - return $i; + if (!empty($this->getClassNode()->stmts)) { + foreach ($this->getClassNode()->stmts as $i => $node) { + if ($node instanceof ClassMethod && strtolower($node->name->toString()) === strtolower($methodName)) { + return $i; + } } } @@ -1032,9 +1058,11 @@ private function getMethodIndex(string $methodName): bool|int|string */ private function propertyExists(string $propertyName): bool { - foreach ($this->getClassNode()->stmts as $node) { - if ($node instanceof Node\Stmt\Property && $node->props[0]->name->toString() === $propertyName) { - return true; + if (!empty($this->getClassNode()->stmts)) { + foreach ($this->getClassNode()->stmts as $node) { + if ($node instanceof Node\Stmt\Property && $node->props[0]->name->toString() === $propertyName) { + return true; + } } } From 9c72be58e1096df2528e4b9752ec7debdedcc558 Mon Sep 17 00:00:00 2001 From: Regis Grison Date: Wed, 27 Nov 2024 17:45:27 +0100 Subject: [PATCH 17/18] fix phpstan errors for github PR --- Command/AutoClosingCommand.php | 9 +--- Controller/TicketController.php | 32 +++---------- .../HackzillaTicketExtension.php | 8 ++-- EventListener/FileSubscriber.php | 3 -- Form/DataTransformer/StatusTransformer.php | 8 ---- HackzillaTicketBundle.php | 3 +- Manager/PermissionManager.php | 12 ++--- Manager/PermissionManagerInterface.php | 3 -- Manager/TicketManager.php | 48 +++---------------- Manager/TicketManagerInterface.php | 13 ----- Manager/UserManager.php | 11 ++--- Model/MessageAttachmentInterface.php | 14 ------ Model/MessageAttachmentTrait.php | 2 - Model/TicketInterface.php | 11 ++--- Model/TicketMessageInterface.php | 11 +---- Model/TicketMessageTrait.php | 27 ++--------- Model/TicketTrait.php | 38 +++------------ Resources/config/controllers.php | 6 +-- Resources/config/maker.php | 3 +- Tests/Component/TicketFeaturesTest.php | 14 ++---- Tests/Fixtures/Entity/Ticket.php | 12 ++--- Tests/Fixtures/Entity/TicketMessage.php | 6 +-- .../Entity/TicketMessageWithAttachment.php | 6 +-- Tests/Form/Type/TicketMessageTypeTest.php | 2 +- Tests/Form/Type/TicketTypeTest.php | 2 +- Tests/Functional/Command/ApplicationTest.php | 5 +- Tests/Functional/FunctionalTest.php | 3 +- Tests/Functional/RoutingTest.php | 2 +- Tests/Functional/TestKernel.php | 7 --- TwigExtension/TicketFeatureExtension.php | 3 -- rector.php | 14 +++++- 31 files changed, 78 insertions(+), 260 deletions(-) diff --git a/Command/AutoClosingCommand.php b/Command/AutoClosingCommand.php index bf023f2..102feb7 100644 --- a/Command/AutoClosingCommand.php +++ b/Command/AutoClosingCommand.php @@ -13,8 +13,6 @@ namespace Hackzilla\Bundle\TicketBundle\Command; -use UnitEnum; -use InvalidArgumentException; use Hackzilla\Bundle\TicketBundle\Manager\TicketManagerInterface; use Hackzilla\Bundle\TicketBundle\Manager\UserManagerInterface; use Hackzilla\Bundle\TicketBundle\Model\TicketMessageInterface; @@ -31,13 +29,10 @@ final class AutoClosingCommand extends Command { protected static $defaultName = 'ticket:autoclosing'; - private bool|string|int|float|UnitEnum|array|null $locale = 'en'; + private bool|string|int|float|\UnitEnum|array|null $locale = 'en'; private string $translationDomain = 'HackzillaTicketBundle'; - /** - * @var TranslatorInterface - */ private readonly TranslatorInterface $translator; public function __construct(private readonly TicketManagerInterface $ticketManager, private readonly UserManagerInterface $userManager, LocaleAwareInterface $translator, ParameterBagInterface $parameterBag) @@ -45,7 +40,7 @@ public function __construct(private readonly TicketManagerInterface $ticketManag parent::__construct(); if (!$translator instanceof TranslatorInterface) { - throw new InvalidArgumentException($translator::class.' Must implement TranslatorInterface and LocaleAwareInterface'); + throw new \InvalidArgumentException($translator::class.' Must implement TranslatorInterface and LocaleAwareInterface'); } $this->translator = $translator; diff --git a/Controller/TicketController.php b/Controller/TicketController.php index 0890779..228e884 100644 --- a/Controller/TicketController.php +++ b/Controller/TicketController.php @@ -13,10 +13,6 @@ namespace Hackzilla\Bundle\TicketBundle\Controller; -use Symfony\Component\Form\FormFactoryInterface; -use Symfony\Component\HttpKernel\Exception\HttpException; -use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\HttpFoundation\RedirectResponse; use Hackzilla\Bundle\TicketBundle\Event\TicketEvent; use Hackzilla\Bundle\TicketBundle\Form\Type\TicketMessageType; use Hackzilla\Bundle\TicketBundle\Form\Type\TicketType; @@ -30,16 +26,19 @@ use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; use Symfony\Component\Form\Extension\Core\Type\HiddenType; +use Symfony\Component\Form\FormFactoryInterface; use Symfony\Component\Form\FormInterface; +use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; +use Symfony\Component\HttpKernel\Exception\HttpException; use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; use Symfony\Contracts\Translation\TranslatorInterface; use Twig\Environment; use Twig\Error\LoaderError; use Twig\Error\RuntimeError; use Twig\Error\SyntaxError; -use function is_object; /** * Ticket controller. @@ -64,9 +63,6 @@ public function __construct( /** * Lists all Ticket entities. * - * @param Request $request - * - * @return Response * @throws LoaderError * @throws RuntimeError * @throws SyntaxError @@ -85,7 +81,7 @@ public function index(Request $request): Response $pagination = $this->pagination->paginate( $query->getQuery(), - (int) ($request->query->get('page', 1))/* page number */, + (int) $request->query->get('page', 1)/* page number */, 10/* limit per page */ ); @@ -103,9 +99,6 @@ public function index(Request $request): Response /** * Creates a new Ticket entity. * - * @param Request $request - * - * @return RedirectResponse|Response * @throws LoaderError * @throws RuntimeError * @throws SyntaxError @@ -144,7 +137,6 @@ public function create(Request $request): RedirectResponse|Response /** * Displays a form to create a new Ticket entity. * - * @return Response * @throws LoaderError * @throws RuntimeError * @throws SyntaxError @@ -169,9 +161,6 @@ public function new(): Response /** * Finds and displays a TicketInterface entity. * - * @param int $ticketId - * - * @return RedirectResponse|Response * @throws LoaderError * @throws RuntimeError * @throws SyntaxError @@ -209,10 +198,6 @@ public function show(int $ticketId): RedirectResponse|Response /** * Finds and displays a TicketInterface entity. * - * @param Request $request - * @param int $ticketId - * - * @return RedirectResponse|Response * @throws LoaderError * @throws RuntimeError * @throws SyntaxError @@ -256,18 +241,13 @@ public function reply(Request $request, int $ticketId): RedirectResponse|Respons /** * Deletes a Ticket entity. - * - * @param Request $request - * @param int $ticketId - * - * @return RedirectResponse */ public function delete(Request $request, int $ticketId): RedirectResponse { $userManager = $this->userManager; $user = $userManager->getCurrentUser(); - if ( ! is_object($user) || !$userManager->hasRole($user, TicketRole::ADMIN)) { + if (!\is_object($user) || !$userManager->hasRole($user, TicketRole::ADMIN)) { throw new HttpException(403); } diff --git a/DependencyInjection/HackzillaTicketExtension.php b/DependencyInjection/HackzillaTicketExtension.php index 606e7c0..267fca0 100644 --- a/DependencyInjection/HackzillaTicketExtension.php +++ b/DependencyInjection/HackzillaTicketExtension.php @@ -13,11 +13,10 @@ namespace Hackzilla\Bundle\TicketBundle\DependencyInjection; -use Symfony\Component\DependencyInjection\Loader\PhpFileLoader; -use Exception; use Hackzilla\Bundle\TicketBundle\Manager\PermissionManager; use Symfony\Component\Config\FileLocator; use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Loader\PhpFileLoader; use Symfony\Component\HttpKernel\DependencyInjection\Extension; /** @@ -29,7 +28,8 @@ final class HackzillaTicketExtension extends Extension { /** * {@inheritdoc} - * @throws Exception + * + * @throws \Exception */ public function load(array $configs, ContainerBuilder $container): void { @@ -53,7 +53,7 @@ public function load(array $configs, ContainerBuilder $container): void $permissionClass = $config['permission_class'] ?? PermissionManager::class; if (!class_exists($permissionClass)) { - throw new Exception(sprintf('Permission manager does not exist: %s', $permissionClass)); + throw new \Exception(\sprintf('Permission manager does not exist: %s', $permissionClass)); } $container->setParameter('hackzilla_ticket.manager.permission.class', $permissionClass); diff --git a/EventListener/FileSubscriber.php b/EventListener/FileSubscriber.php index 7e0df77..a3b182b 100644 --- a/EventListener/FileSubscriber.php +++ b/EventListener/FileSubscriber.php @@ -24,9 +24,6 @@ */ final class FileSubscriber implements EventSubscriberInterface { - /** - * @return array - */ public static function getSubscribedEvents(): array { return [ diff --git a/Form/DataTransformer/StatusTransformer.php b/Form/DataTransformer/StatusTransformer.php index a5681b7..51610cc 100644 --- a/Form/DataTransformer/StatusTransformer.php +++ b/Form/DataTransformer/StatusTransformer.php @@ -25,10 +25,6 @@ public function __construct(private readonly TicketInterface $ticket) /** * Transforms checkbox value into Ticket Message Status Closed. - * - * @param $value - * - * @return bool|null */ public function transform($value): ?bool { @@ -41,10 +37,6 @@ public function transform($value): ?bool /** * Transforms Ticket Message Status Closed into checkbox value checked. - * - * @param $value - * - * @return int|null */ public function reverseTransform($value): ?int { diff --git a/HackzillaTicketBundle.php b/HackzillaTicketBundle.php index bb7da53..c45a8e0 100644 --- a/HackzillaTicketBundle.php +++ b/HackzillaTicketBundle.php @@ -13,7 +13,6 @@ namespace Hackzilla\Bundle\TicketBundle; -use Exception; use Symfony\Component\Config\FileLocator; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; @@ -22,7 +21,7 @@ class HackzillaTicketBundle extends Bundle { /** - * @throws Exception + * @throws \Exception */ public function build(ContainerBuilder $container): void { diff --git a/Manager/PermissionManager.php b/Manager/PermissionManager.php index d3e7c8e..cd90ce4 100644 --- a/Manager/PermissionManager.php +++ b/Manager/PermissionManager.php @@ -17,7 +17,6 @@ use Hackzilla\Bundle\TicketBundle\Model\UserInterface; use Hackzilla\Bundle\TicketBundle\TicketRole; use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; -use function is_object; class PermissionManager implements PermissionManagerInterface { @@ -25,15 +24,10 @@ class PermissionManager implements PermissionManagerInterface /** * used in TicketManager::getTicketListQuery(). - * - * @param object $query - * @param UserInterface|null $user - * - * @return object */ public function addUserPermissionsCondition(object $query, ?UserInterface $user): object { - if (is_object($user)) { + if (\is_object($user)) { if (!$this->getUserManager()->hasRole($user, TicketRole::ADMIN)) { $query ->andWhere('t.userCreated = :user') @@ -56,8 +50,8 @@ public function addUserPermissionsCondition(object $query, ?UserInterface $user) */ public function hasPermission(?UserInterface $user, TicketInterface $ticket): void { - if ( ! is_object($user) || ( !$this->getUserManager()->hasRole($user, TicketRole::ADMIN) && - (!$ticket->getUserCreated() instanceof UserInterface || $ticket->getUserCreated()->getId() != $user->getId())) + if (!\is_object($user) || (!$this->getUserManager()->hasRole($user, TicketRole::ADMIN) + && (!$ticket->getUserCreated() instanceof UserInterface || $ticket->getUserCreated()->getId() != $user->getId())) ) { throw new AccessDeniedHttpException(); } diff --git a/Manager/PermissionManagerInterface.php b/Manager/PermissionManagerInterface.php index 0983e63..9615684 100644 --- a/Manager/PermissionManagerInterface.php +++ b/Manager/PermissionManagerInterface.php @@ -20,9 +20,6 @@ interface PermissionManagerInterface { /** * used in TicketManager::getTicketListQuery(). - * - * @param object $query - * @param UserInterface $user */ public function addUserPermissionsCondition(object $query, UserInterface $user); diff --git a/Manager/TicketManager.php b/Manager/TicketManager.php index e384d20..cbb9830 100644 --- a/Manager/TicketManager.php +++ b/Manager/TicketManager.php @@ -13,9 +13,6 @@ namespace Hackzilla\Bundle\TicketBundle\Manager; -use DateMalformedIntervalStringException; -use DateTime; -use DateInterval; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityRepository; use Doctrine\ORM\QueryBuilder; @@ -49,10 +46,10 @@ public function __construct(private readonly string $ticketClass, private readon public function setLogger(LoggerInterface $logger): self { if (!class_exists($this->ticketClass)) { - $logger->error(sprintf('Ticket entity %s doesn\'t exist', $this->ticketClass)); + $logger->error(\sprintf('Ticket entity %s doesn\'t exist', $this->ticketClass)); } if (!class_exists($this->ticketMessageClass)) { - $logger->error(sprintf('Message entity %s doesn\'t exist', $this->ticketMessageClass)); + $logger->error(\sprintf('Message entity %s doesn\'t exist', $this->ticketMessageClass)); } return $this; @@ -62,11 +59,11 @@ public function setObjectManager(EntityManagerInterface $objectManager): self { $this->objectManager = $objectManager; - if ($this->ticketClass !== '' && $this->ticketClass !== '0') { + if ('' !== $this->ticketClass && '0' !== $this->ticketClass) { $this->ticketRepository = $objectManager->getRepository($this->ticketClass); } - if ($this->ticketMessageClass !== '' && $this->ticketMessageClass !== '0') { + if ('' !== $this->ticketMessageClass && '0' !== $this->ticketMessageClass) { $this->messageRepository = $objectManager->getRepository($this->ticketMessageClass); } @@ -85,8 +82,6 @@ public function setTranslator(TranslatorInterface $translator): self /** * Create a new instance of Ticket entity. - * - * @return TicketInterface */ public function createTicket(): TicketInterface { @@ -100,10 +95,6 @@ public function createTicket(): TicketInterface /** * Create a new instance of TicketMessage Entity. - * - * @param TicketInterface|null $ticket - * - * @return TicketMessageInterface */ public function createMessage(?TicketInterface $ticket = null): TicketMessageInterface { @@ -121,12 +112,6 @@ public function createMessage(?TicketInterface $ticket = null): TicketMessageInt return $message; } - /** - * @param TicketInterface $ticket - * @param TicketMessageInterface|null $message - * - * @return void - */ public function updateTicket(TicketInterface $ticket, ?TicketMessageInterface $message = null): void { if (null === $ticket->getId()) { @@ -173,8 +158,6 @@ public function getTicketById($ticketId): ?TicketInterface * Find message in the database. * * @param int $ticketMessageId - * - * @return TicketMessageInterface|null */ public function getMessageById($ticketMessageId): ?TicketMessageInterface { @@ -191,12 +174,6 @@ public function findTicketsBy(array $criteria): array return $this->ticketRepository->findBy($criteria); } - /** - * @param $ticketStatus - * @param $ticketPriority - * - * @return QueryBuilder - */ public function getTicketListQuery($ticketStatus, $ticketPriority = null): QueryBuilder { $query = $this->ticketRepository->createQueryBuilder('t') @@ -228,15 +205,12 @@ public function getTicketListQuery($ticketStatus, $ticketPriority = null): Query } /** - * @param int $days - * - * @return mixed - * @throws DateMalformedIntervalStringException + * @throws \DateMalformedIntervalStringException */ public function getResolvedTicketOlderThan(int $days): mixed { - $closeBeforeDate = new DateTime(); - $closeBeforeDate->sub(new DateInterval('P'.$days.'D')); + $closeBeforeDate = new \DateTime(); + $closeBeforeDate->sub(new \DateInterval('P'.$days.'D')); $query = $this->ticketRepository->createQueryBuilder('t') // ->select($this->ticketClass.' t') @@ -251,10 +225,6 @@ public function getResolvedTicketOlderThan(int $days): mixed /** * Lookup status code. - * - * @param string $statusStr - * - * @return int|string|bool */ public function getTicketStatus(string $statusStr): int|string|bool { @@ -273,10 +243,6 @@ public function getTicketStatus(string $statusStr): int|string|bool /** * Lookup priority code. - * - * @param string|null $priorityStr - * - * @return int|string|bool */ public function getTicketPriority(?string $priorityStr): int|string|bool { diff --git a/Manager/TicketManagerInterface.php b/Manager/TicketManagerInterface.php index af84e15..8ced27c 100644 --- a/Manager/TicketManagerInterface.php +++ b/Manager/TicketManagerInterface.php @@ -37,28 +37,15 @@ public function findTicketsBy(array $criteria); public function getTicketListQuery($ticketStatus, $ticketPriority = null): QueryBuilder; - /** - * @param int $days - * - * @return mixed - */ public function getResolvedTicketOlderThan(int $days): mixed; /** * Lookup status code. - * - * @param string $statusStr - * - * @return int|string|bool */ public function getTicketStatus(string $statusStr): int|string|bool; /** * Lookup priority code. - * - * @param string $priorityStr - * - * @return int|string|bool */ public function getTicketPriority(string $priorityStr): int|string|bool; } diff --git a/Manager/UserManager.php b/Manager/UserManager.php index 392b2e5..a54c924 100644 --- a/Manager/UserManager.php +++ b/Manager/UserManager.php @@ -13,14 +13,11 @@ namespace Hackzilla\Bundle\TicketBundle\Manager; -use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; -use InvalidArgumentException; -use LogicException; -use Exception; use Doctrine\Persistence\ObjectRepository; use Hackzilla\Bundle\TicketBundle\Model\TicketInterface; use Hackzilla\Bundle\TicketBundle\Model\UserInterface; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; +use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface; final class UserManager implements UserManagerInterface @@ -35,7 +32,7 @@ public function __construct( private readonly AuthorizationCheckerInterface $authorizationChecker, ) { if (!is_subclass_of($userRepository->getClassName(), UserInterface::class)) { - throw new InvalidArgumentException(sprintf('Argument 2 passed to "%s()" MUST be an object repository for a class implementing "%s".', __METHOD__, UserInterface::class)); + throw new \InvalidArgumentException(\sprintf('Argument 2 passed to "%s()" MUST be an object repository for a class implementing "%s".', __METHOD__, UserInterface::class)); } $this->userRepository = $userRepository; @@ -50,7 +47,7 @@ public function getCurrentUser(): ?UserInterface $user = $this->tokenStorage->getToken()->getUser(); if ($user instanceof \Symfony\Component\Security\Core\User\UserInterface && !$user instanceof UserInterface) { - throw new LogicException(sprintf('The object representing the authenticated user MUST implement "%s".', UserInterface::class)); + throw new \LogicException(\sprintf('The object representing the authenticated user MUST implement "%s".', UserInterface::class)); } return $user; @@ -80,7 +77,7 @@ public function hasPermission(?UserInterface $user, TicketInterface $ticket): bo { try { $this->getPermissionManager()->hasPermission($user, $ticket); - } catch (Exception) { + } catch (\Exception) { return false; } diff --git a/Model/MessageAttachmentInterface.php b/Model/MessageAttachmentInterface.php index eb3c80c..1e49476 100644 --- a/Model/MessageAttachmentInterface.php +++ b/Model/MessageAttachmentInterface.php @@ -18,15 +18,10 @@ interface MessageAttachmentInterface extends TicketMessageInterface { /** - * @param File|null $file - * * @return $this */ public function setAttachmentFile(?File $file = null): self; - /** - * @return File|null - */ public function getAttachmentFile(): ?File; /** @@ -34,9 +29,6 @@ public function getAttachmentFile(): ?File; */ public function setAttachmentName(string $name): self; - /** - * @return string|null - */ public function getAttachmentName(): ?string; /** @@ -46,9 +38,6 @@ public function getAttachmentName(): ?string; */ public function setAttachmentSize(int $size): self; - /** - * @return int|null - */ public function getAttachmentSize(): ?int; /** @@ -58,8 +47,5 @@ public function getAttachmentSize(): ?int; */ public function setAttachmentMimeType(string $mimeType): self; - /** - * @return string|null - */ public function getAttachmentMimeType(): ?string; } diff --git a/Model/MessageAttachmentTrait.php b/Model/MessageAttachmentTrait.php index b89ec52..0d32bb4 100644 --- a/Model/MessageAttachmentTrait.php +++ b/Model/MessageAttachmentTrait.php @@ -22,8 +22,6 @@ trait MessageAttachmentTrait * NOTE: This field is not persisted to database! * * @Vich\UploadableField(mapping="ticket_message_attachment", fileNameProperty="attachmentName", originalName="attachmentFile", size="attachmentSize") - * - * @var File|null */ protected ?File $attachmentFile; diff --git a/Model/TicketInterface.php b/Model/TicketInterface.php index 7465423..bdd0cc5 100644 --- a/Model/TicketInterface.php +++ b/Model/TicketInterface.php @@ -13,7 +13,6 @@ namespace Hackzilla\Bundle\TicketBundle\Model; -use DateTimeInterface; use Doctrine\Common\Collections\Collection; interface TicketInterface @@ -74,7 +73,6 @@ public function getPriorityString(): ?string; /** * Set userCreated. * - * * @return $this */ public function setUserCreated(?UserInterface $userCreated): self; @@ -87,7 +85,6 @@ public function getUserCreated(): ?UserInterface; /** * Set lastUser. * - * * @return $this */ public function setLastUser(?UserInterface $lastUser): self; @@ -102,24 +99,24 @@ public function getLastUser(): ?UserInterface; * * @return $this */ - public function setLastMessage(DateTimeInterface $lastMessage): self; + public function setLastMessage(\DateTimeInterface $lastMessage): self; /** * Get lastMessage. */ - public function getLastMessage(): ?DateTimeInterface; + public function getLastMessage(): ?\DateTimeInterface; /** * Set createdAt. * * @return $this */ - public function setCreatedAt(DateTimeInterface $createdAt): self; + public function setCreatedAt(\DateTimeInterface $createdAt): self; /** * Get createdAt. */ - public function getCreatedAt(): ?DateTimeInterface; + public function getCreatedAt(): ?\DateTimeInterface; /** * Set subject. diff --git a/Model/TicketMessageInterface.php b/Model/TicketMessageInterface.php index 95e5e7f..79a8b39 100644 --- a/Model/TicketMessageInterface.php +++ b/Model/TicketMessageInterface.php @@ -13,8 +13,6 @@ namespace Hackzilla\Bundle\TicketBundle\Model; -use DateTime; - interface TicketMessageInterface { public const STATUS_INVALID = 0; @@ -112,15 +110,12 @@ public function getPriorityString(): ?string; /** * Set user. * - * * @return $this */ public function setUser(?UserInterface $user): self; /** * Get user. - * - * @return ?UserInterface */ public function getUser(): ?UserInterface; @@ -141,14 +136,12 @@ public function getMessage(): ?string; * * @return $this */ - public function setCreatedAt(DateTime $createdAt): self; + public function setCreatedAt(\DateTime $createdAt): self; /** * Get createdAt. - * - * @return DateTime */ - public function getCreatedAt(): DateTime; + public function getCreatedAt(): \DateTime; /** * Set ticket. diff --git a/Model/TicketMessageTrait.php b/Model/TicketMessageTrait.php index 746a0fc..373aba6 100644 --- a/Model/TicketMessageTrait.php +++ b/Model/TicketMessageTrait.php @@ -13,7 +13,6 @@ namespace Hackzilla\Bundle\TicketBundle\Model; -use DateTime; use Hackzilla\Bundle\TicketBundle\Tests\Fixtures\Entity\TicketMessage; use Hackzilla\Bundle\TicketBundle\Tests\Fixtures\Entity\TicketMessageWithAttachment; @@ -25,8 +24,6 @@ trait TicketMessageTrait /** * Set status. * - * @param int $status - * * @return TicketMessage|TicketMessageTrait|TicketMessageWithAttachment */ public function setStatus(int $status): self @@ -39,8 +36,6 @@ public function setStatus(int $status): self /** * Set status string. * - * @param string $status - * * @return TicketMessage|TicketMessageTrait|TicketMessageWithAttachment */ public function setStatusString(string $status): self @@ -67,7 +62,7 @@ public function getStatus(): ?int */ public function getStatusString(): ?string { - if (isset(TicketMessageInterface::STATUSES[$this->status]) && (TicketMessageInterface::STATUSES[$this->status] !== '' && TicketMessageInterface::STATUSES[$this->status] !== '0')) { + if (isset(TicketMessageInterface::STATUSES[$this->status]) && ('' !== TicketMessageInterface::STATUSES[$this->status] && '0' !== TicketMessageInterface::STATUSES[$this->status])) { return TicketMessageInterface::STATUSES[$this->status]; } @@ -77,8 +72,6 @@ public function getStatusString(): ?string /** * Set priority. * - * @param int $priority - * * @return TicketMessage|TicketMessageTrait|TicketMessageWithAttachment */ public function setPriority(int $priority): self @@ -91,8 +84,6 @@ public function setPriority(int $priority): self /** * Set priority string. * - * @param string $priority - * * @return TicketMessage|TicketMessageTrait|TicketMessageWithAttachment */ public function setPriorityString(string $priority): self @@ -119,7 +110,7 @@ public function getPriority(): ?int */ public function getPriorityString(): ?string { - if (isset(TicketMessageInterface::PRIORITIES[$this->priority]) && (TicketMessageInterface::PRIORITIES[$this->priority] !== '' && TicketMessageInterface::PRIORITIES[$this->priority] !== '0')) { + if (isset(TicketMessageInterface::PRIORITIES[$this->priority]) && ('' !== TicketMessageInterface::PRIORITIES[$this->priority] && '0' !== TicketMessageInterface::PRIORITIES[$this->priority])) { return TicketMessageInterface::PRIORITIES[$this->priority]; } @@ -129,8 +120,6 @@ public function getPriorityString(): ?string /** * Set user. * - * @param ?UserInterface $user - * * @return TicketMessage|TicketMessageTrait|TicketMessageWithAttachment */ public function setUser(?UserInterface $user): self @@ -151,8 +140,6 @@ public function getUser(): ?UserInterface /** * Set message. * - * @param string $message - * * @return TicketMessage|TicketMessageTrait|TicketMessageWithAttachment */ public function setMessage(string $message): self @@ -173,11 +160,9 @@ public function getMessage(): ?string /** * Set createdAt. * - * @param DateTime $createdAt - * * @return TicketMessage|TicketMessageTrait|TicketMessageWithAttachment */ - public function setCreatedAt(DateTime $createdAt): self + public function setCreatedAt(\DateTime $createdAt): self { $this->createdAt = $createdAt; @@ -186,10 +171,8 @@ public function setCreatedAt(DateTime $createdAt): self /** * Get createdAt. - * - * @return DateTime */ - public function getCreatedAt(): DateTime + public function getCreatedAt(): \DateTime { return $this->createdAt; } @@ -197,8 +180,6 @@ public function getCreatedAt(): DateTime /** * Set ticket. * - * @param TicketInterface|null $ticket - * * @return TicketMessage|TicketMessageTrait|TicketMessageWithAttachment */ public function setTicket(?TicketInterface $ticket = null): self diff --git a/Model/TicketTrait.php b/Model/TicketTrait.php index c460022..28caf9a 100644 --- a/Model/TicketTrait.php +++ b/Model/TicketTrait.php @@ -13,10 +13,8 @@ namespace Hackzilla\Bundle\TicketBundle\Model; -use DateTimeInterface; use Doctrine\Common\Collections\Collection; use Hackzilla\Bundle\TicketBundle\Tests\Fixtures\Entity\Ticket; -use function array_key_exists; /** * Ticket Trait. @@ -26,8 +24,6 @@ trait TicketTrait /** * Set status. * - * @param int $status - * * @return Ticket|TicketTrait */ public function setStatus(int $status): self @@ -40,8 +36,6 @@ public function setStatus(int $status): self /** * Set status string. * - * @param string $status - * * @return Ticket|TicketTrait */ public function setStatusString(string $status): self @@ -68,7 +62,7 @@ public function getStatus(): ?int */ public function getStatusString(): ?string { - if (array_key_exists($this->status, TicketMessageInterface::STATUSES)) { + if (\array_key_exists($this->status, TicketMessageInterface::STATUSES)) { return TicketMessageInterface::STATUSES[$this->status]; } @@ -78,8 +72,6 @@ public function getStatusString(): ?string /** * Set priority. * - * @param int $priority - * * @return Ticket|TicketTrait */ public function setPriority(int $priority): self @@ -92,8 +84,6 @@ public function setPriority(int $priority): self /** * Set priority string. * - * @param string $priority - * * @return Ticket|TicketTrait */ public function setPriorityString(string $priority): self @@ -120,7 +110,7 @@ public function getPriority(): ?int */ public function getPriorityString(): ?string { - if (array_key_exists($this->priority, TicketMessageInterface::PRIORITIES)) { + if (\array_key_exists($this->priority, TicketMessageInterface::PRIORITIES)) { return TicketMessageInterface::PRIORITIES[$this->priority]; } @@ -130,9 +120,6 @@ public function getPriorityString(): ?string /** * Set userCreated. * - * - * @param UserInterface|null $userCreated - * * @return Ticket|TicketTrait */ public function setUserCreated(?UserInterface $userCreated): self @@ -153,9 +140,6 @@ public function getUserCreated(): ?UserInterface /** * Set lastUser. * - * - * @param UserInterface|null $lastUser - * * @return Ticket|TicketTrait */ public function setLastUser(?UserInterface $lastUser): self @@ -176,11 +160,9 @@ public function getLastUser(): ?UserInterface /** * Set lastMessage. * - * @param DateTimeInterface $lastMessage - * * @return Ticket|TicketTrait */ - public function setLastMessage(DateTimeInterface $lastMessage): self + public function setLastMessage(\DateTimeInterface $lastMessage): self { $this->lastMessage = $lastMessage; @@ -190,7 +172,7 @@ public function setLastMessage(DateTimeInterface $lastMessage): self /** * Get lastMessage. */ - public function getLastMessage(): ?DateTimeInterface + public function getLastMessage(): ?\DateTimeInterface { return $this->lastMessage; } @@ -198,11 +180,9 @@ public function getLastMessage(): ?DateTimeInterface /** * Set createdAt. * - * @param DateTimeInterface $createdAt - * * @return Ticket|TicketTrait */ - public function setCreatedAt(DateTimeInterface $createdAt): self + public function setCreatedAt(\DateTimeInterface $createdAt): self { $this->createdAt = $createdAt; @@ -212,7 +192,7 @@ public function setCreatedAt(DateTimeInterface $createdAt): self /** * Get createdAt. */ - public function getCreatedAt(): ?DateTimeInterface + public function getCreatedAt(): ?\DateTimeInterface { return $this->createdAt; } @@ -220,8 +200,6 @@ public function getCreatedAt(): ?DateTimeInterface /** * Set subject. * - * @param string $subject - * * @return Ticket|TicketTrait */ public function setSubject(string $subject): self @@ -242,8 +220,6 @@ public function getSubject(): ?string /** * Add message. * - * @param TicketMessageInterface $message - * * @return Ticket|TicketTrait */ public function addMessage(TicketMessageInterface $message): self @@ -256,8 +232,6 @@ public function addMessage(TicketMessageInterface $message): self /** * Remove message. * - * @param TicketMessageInterface $message - * * @return Ticket|TicketTrait */ public function removeMessage(TicketMessageInterface $message): self diff --git a/Resources/config/controllers.php b/Resources/config/controllers.php index 0fb7f1b..323a4e9 100644 --- a/Resources/config/controllers.php +++ b/Resources/config/controllers.php @@ -11,15 +11,15 @@ * file that was distributed with this source code. */ -use Symfony\Component\Form\FormFactoryInterface; -use Twig\Environment; -use Vich\UploaderBundle\Handler\DownloadHandler; use Hackzilla\Bundle\TicketBundle\Controller\TicketAttachmentController; use Hackzilla\Bundle\TicketBundle\Controller\TicketController; use Hackzilla\Bundle\TicketBundle\Manager\TicketManagerInterface; use Hackzilla\Bundle\TicketBundle\Manager\UserManagerInterface; use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; use Symfony\Component\DependencyInjection\Loader\Configurator\ReferenceConfigurator; +use Symfony\Component\Form\FormFactoryInterface; +use Twig\Environment; +use Vich\UploaderBundle\Handler\DownloadHandler; return static function (ContainerConfigurator $container): void { // Use "service" function for creating references to services when dropping support for Symfony 4.4 diff --git a/Resources/config/maker.php b/Resources/config/maker.php index 47abef1..1d7ef62 100644 --- a/Resources/config/maker.php +++ b/Resources/config/maker.php @@ -10,8 +10,9 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -use Hackzilla\Bundle\TicketBundle\Maker\TicketMaker; + use Hackzilla\Bundle\TicketBundle\Maker\MessageMaker; +use Hackzilla\Bundle\TicketBundle\Maker\TicketMaker; use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; use Symfony\Component\DependencyInjection\Loader\Configurator\ReferenceConfigurator; diff --git a/Tests/Component/TicketFeaturesTest.php b/Tests/Component/TicketFeaturesTest.php index 89b247f..65b30cb 100644 --- a/Tests/Component/TicketFeaturesTest.php +++ b/Tests/Component/TicketFeaturesTest.php @@ -13,8 +13,6 @@ namespace Hackzilla\Bundle\TicketBundle\Tests\Extension; -use Iterator; -use stdClass; use Hackzilla\Bundle\TicketBundle\Component\TicketFeatures; use Hackzilla\Bundle\TicketBundle\Tests\Fixtures\Entity\TicketMessage; use Hackzilla\Bundle\TicketBundle\Tests\Fixtures\Entity\TicketMessageWithAttachment; @@ -30,19 +28,13 @@ public function testConstruct(array $features, string $class): void $this->assertInstanceOf(TicketFeatures::class, new TicketFeatures($features, $class)); } - public function constructProvider(): Iterator + public function constructProvider(): \Iterator { - yield [[], stdClass::class]; + yield [[], \stdClass::class]; } /** * @dataProvider featureAttachmentProvider - * - * @param array $features - * @param string $class - * @param bool $compare - * - * @return void */ public function testFeatureAttachment(array $features, string $class, bool $compare): void { @@ -52,7 +44,7 @@ public function testFeatureAttachment(array $features, string $class, bool $comp $this->assertSame($obj->hasFeature('attachment'), $compare); } - public function featureAttachmentProvider(): Iterator + public function featureAttachmentProvider(): \Iterator { yield [[], TicketMessage::class, false]; yield [['attachment' => true], TicketMessage::class, false]; diff --git a/Tests/Fixtures/Entity/Ticket.php b/Tests/Fixtures/Entity/Ticket.php index f0e41eb..9ee17b8 100644 --- a/Tests/Fixtures/Entity/Ticket.php +++ b/Tests/Fixtures/Entity/Ticket.php @@ -13,11 +13,9 @@ namespace Hackzilla\Bundle\TicketBundle\Tests\Fixtures\Entity; -use Doctrine\DBAL\Types\Types; -use DateTimeInterface; -use Doctrine\Common\Collections\Collection; -use DateTime; use Doctrine\Common\Collections\ArrayCollection; +use Doctrine\Common\Collections\Collection; +use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping as ORM; use Hackzilla\Bundle\TicketBundle\Model\TicketInterface; use Hackzilla\Bundle\TicketBundle\Model\TicketTrait; @@ -37,7 +35,7 @@ class Ticket implements TicketInterface private ?int $id = null; #[ORM\Column(type: Types::DATETIME_MUTABLE, nullable: false)] - private DateTimeInterface $lastMessage; + private \DateTimeInterface $lastMessage; #[ORM\Column(type: Types::TEXT, nullable: false)] private string $subject; @@ -49,7 +47,7 @@ class Ticket implements TicketInterface private int $priority; #[ORM\Column(type: Types::DATETIME_MUTABLE, nullable: false)] - private DateTimeInterface $createdAt; + private \DateTimeInterface $createdAt; /** * @var Collection @@ -65,7 +63,7 @@ class Ticket implements TicketInterface public function __construct() { - $this->createdAt = new DateTime(); + $this->createdAt = new \DateTime(); $this->messages = new ArrayCollection(); } diff --git a/Tests/Fixtures/Entity/TicketMessage.php b/Tests/Fixtures/Entity/TicketMessage.php index 6864dc5..4ba2883 100644 --- a/Tests/Fixtures/Entity/TicketMessage.php +++ b/Tests/Fixtures/Entity/TicketMessage.php @@ -14,8 +14,6 @@ namespace Hackzilla\Bundle\TicketBundle\Tests\Fixtures\Entity; use Doctrine\DBAL\Types\Types; -use DateTimeInterface; -use DateTime; use Doctrine\ORM\Mapping as ORM; use Hackzilla\Bundle\TicketBundle\Model\TicketMessageInterface; use Hackzilla\Bundle\TicketBundle\Model\TicketMessageTrait; @@ -44,7 +42,7 @@ class TicketMessage implements TicketMessageInterface private int $priority; #[ORM\Column(type: Types::DATETIME_MUTABLE, nullable: false)] - private DateTimeInterface $createdAt; + private \DateTimeInterface $createdAt; #[ORM\ManyToOne(targetEntity: Ticket::class, inversedBy: 'messages')] #[ORM\JoinColumn(nullable: false)] @@ -55,7 +53,7 @@ class TicketMessage implements TicketMessageInterface public function __construct() { - $this->createdAt = new DateTime(); + $this->createdAt = new \DateTime(); } public function getId(): ?int diff --git a/Tests/Fixtures/Entity/TicketMessageWithAttachment.php b/Tests/Fixtures/Entity/TicketMessageWithAttachment.php index 16acf8d..82a1823 100644 --- a/Tests/Fixtures/Entity/TicketMessageWithAttachment.php +++ b/Tests/Fixtures/Entity/TicketMessageWithAttachment.php @@ -14,8 +14,6 @@ namespace Hackzilla\Bundle\TicketBundle\Tests\Fixtures\Entity; use Doctrine\DBAL\Types\Types; -use DateTimeInterface; -use DateTime; use Doctrine\ORM\Mapping as ORM; use Hackzilla\Bundle\TicketBundle\Model\MessageAttachmentInterface; use Hackzilla\Bundle\TicketBundle\Model\MessageAttachmentTrait; @@ -47,7 +45,7 @@ class TicketMessageWithAttachment implements TicketMessageInterface, MessageAtta private int $priority; #[ORM\Column(type: Types::DATETIME_MUTABLE, nullable: false)] - private DateTimeInterface $createdAt; + private \DateTimeInterface $createdAt; #[ORM\Column(type: Types::STRING, length: 255, nullable: true)] private ?string $attachmentName = null; @@ -67,7 +65,7 @@ class TicketMessageWithAttachment implements TicketMessageInterface, MessageAtta public function __construct() { - $this->createdAt = new DateTime(); + $this->createdAt = new \DateTime(); } public function getId(): ?int diff --git a/Tests/Form/Type/TicketMessageTypeTest.php b/Tests/Form/Type/TicketMessageTypeTest.php index 30ff271..3070720 100644 --- a/Tests/Form/Type/TicketMessageTypeTest.php +++ b/Tests/Form/Type/TicketMessageTypeTest.php @@ -13,12 +13,12 @@ namespace Hackzilla\Bundle\TicketBundle\Tests\Form\Type; -use PHPUnit\Framework\MockObject\MockObject; use Hackzilla\Bundle\TicketBundle\Component\TicketFeatures; use Hackzilla\Bundle\TicketBundle\Form\Type\TicketMessageType; use Hackzilla\Bundle\TicketBundle\Manager\UserManagerInterface; use Hackzilla\Bundle\TicketBundle\Model\TicketMessageInterface; use Hackzilla\Bundle\TicketBundle\Tests\Fixtures\Entity\TicketMessage; +use PHPUnit\Framework\MockObject\MockObject; use Symfony\Component\Form\PreloadedExtension; use Symfony\Component\Form\Test\TypeTestCase; diff --git a/Tests/Form/Type/TicketTypeTest.php b/Tests/Form/Type/TicketTypeTest.php index 572013b..958ea5a 100644 --- a/Tests/Form/Type/TicketTypeTest.php +++ b/Tests/Form/Type/TicketTypeTest.php @@ -13,13 +13,13 @@ namespace Hackzilla\Bundle\TicketBundle\Tests\Form\Type; -use PHPUnit\Framework\MockObject\MockObject; use Hackzilla\Bundle\TicketBundle\Component\TicketFeatures; use Hackzilla\Bundle\TicketBundle\Form\Type\TicketMessageType; use Hackzilla\Bundle\TicketBundle\Form\Type\TicketType; use Hackzilla\Bundle\TicketBundle\Manager\UserManagerInterface; use Hackzilla\Bundle\TicketBundle\Tests\Fixtures\Entity\Ticket; use Hackzilla\Bundle\TicketBundle\Tests\Fixtures\Entity\TicketMessage; +use PHPUnit\Framework\MockObject\MockObject; use Symfony\Component\Form\PreloadedExtension; use Symfony\Component\Form\Test\TypeTestCase; diff --git a/Tests/Functional/Command/ApplicationTest.php b/Tests/Functional/Command/ApplicationTest.php index c74b109..081d6f0 100644 --- a/Tests/Functional/Command/ApplicationTest.php +++ b/Tests/Functional/Command/ApplicationTest.php @@ -13,7 +13,6 @@ namespace Hackzilla\Bundle\TicketBundle\Tests\Functional\Command; -use Iterator; use Hackzilla\Bundle\TicketBundle\Command\AutoClosingCommand; use Hackzilla\Bundle\TicketBundle\Command\TicketManagerCommand; use Hackzilla\Bundle\TicketBundle\Tests\Functional\WebTestCase; @@ -29,12 +28,12 @@ final class ApplicationTest extends WebTestCase */ public function testCommandRegistration(string $expectedClass, string $commandName): void { - $application = new Application(ApplicationTest::$kernel); + $application = new Application(self::$kernel); $this->assertInstanceOf($expectedClass, $application->find($commandName)); } - public function getCommands(): Iterator + public function getCommands(): \Iterator { yield [AutoClosingCommand::class, 'ticket:autoclosing']; yield [TicketManagerCommand::class, 'ticket:create']; diff --git a/Tests/Functional/FunctionalTest.php b/Tests/Functional/FunctionalTest.php index a44ac8e..11046b1 100644 --- a/Tests/Functional/FunctionalTest.php +++ b/Tests/Functional/FunctionalTest.php @@ -13,7 +13,6 @@ namespace Hackzilla\Bundle\TicketBundle\Tests\Functional; -use Iterator; use Hackzilla\Bundle\TicketBundle\Manager\TicketManagerInterface; use Hackzilla\Bundle\TicketBundle\Tests\Fixtures\Entity\Ticket; use Hackzilla\Bundle\TicketBundle\Tests\Fixtures\Entity\TicketMessage; @@ -36,7 +35,7 @@ public function testConfiguredParameter(string $parameter, string|array $value): $this->assertSame($value, static::$kernel->getContainer()->getParameter($parameter)); } - public function getParameters(): Iterator + public function getParameters(): \Iterator { $messageCLass = class_exists(VichUploaderBundle::class) ? TicketMessageWithAttachment::class : TicketMessage::class; yield ['hackzilla_ticket.model.user.class', User::class]; diff --git a/Tests/Functional/RoutingTest.php b/Tests/Functional/RoutingTest.php index e7885f0..3a48326 100644 --- a/Tests/Functional/RoutingTest.php +++ b/Tests/Functional/RoutingTest.php @@ -25,7 +25,7 @@ final class RoutingTest extends WebTestCase */ public function testRoutes(string $name, string $path, array $methods): void { - $client = RoutingTest::createClient(); + $client = self::createClient(); $router = $client->getContainer()->get('router'); $route = $router->getRouteCollection()->get($name); diff --git a/Tests/Functional/TestKernel.php b/Tests/Functional/TestKernel.php index 1769df0..14ff7b3 100644 --- a/Tests/Functional/TestKernel.php +++ b/Tests/Functional/TestKernel.php @@ -28,7 +28,6 @@ use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\HttpKernel\Kernel; use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator; -use Symfony\Component\Routing\RouteCollectionBuilder; use Vich\UploaderBundle\VichUploaderBundle; trait ConfigureRoutes @@ -98,12 +97,6 @@ public function registerBundles(): array return $bundles; } - /** - * @param ContainerBuilder $container - * @param LoaderInterface $loader - * - * @return void - */ protected function configureContainer(ContainerBuilder $container, LoaderInterface $loader): void { // FrameworkBundle config diff --git a/TwigExtension/TicketFeatureExtension.php b/TwigExtension/TicketFeatureExtension.php index 6760043..57f903a 100644 --- a/TwigExtension/TicketFeatureExtension.php +++ b/TwigExtension/TicketFeatureExtension.php @@ -35,9 +35,6 @@ public function hasFeature(string $feature): ?bool return $this->ticketFeatures->hasFeature($feature); } - /** - * @return string - */ public function getName(): string { return 'ticketFeature'; diff --git a/rector.php b/rector.php index e09ff69..6cece1e 100644 --- a/rector.php +++ b/rector.php @@ -2,6 +2,15 @@ declare(strict_types=1); +/* + * This file is part of HackzillaTicketBundle package. + * + * (c) Daniel Platt + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + use Rector\Config\RectorConfig; use Rector\Doctrine\Set\DoctrineSetList; use Rector\PHPUnit\Set\PHPUnitSetList; @@ -11,7 +20,7 @@ return RectorConfig::configure() ->withPaths([__DIR__]) - ->withSkip([__DIR__ . '/vendor']) + ->withSkip([__DIR__.'/vendor']) // uncomment to reach your current PHP version // ->withTypeCoverageLevel(0) ->withPhpSets(php83: true) @@ -24,4 +33,5 @@ SymfonySetList::SYMFONY_CONSTRUCTOR_INJECTION, SetList::TYPE_DECLARATION, PHPUnitSetList::PHPUNIT_CODE_QUALITY, - ]); + ]) +; From b4910af0cca4b92ce078b425e3843a226ef98789 Mon Sep 17 00:00:00 2001 From: Regis Grison Date: Wed, 27 Nov 2024 17:49:10 +0100 Subject: [PATCH 18/18] another minor fix for github tests --- Controller/TicketController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Controller/TicketController.php b/Controller/TicketController.php index 228e884..7a02d19 100644 --- a/Controller/TicketController.php +++ b/Controller/TicketController.php @@ -55,7 +55,7 @@ public function __construct( private readonly TranslatorInterface $translator, private readonly UserManagerInterface $userManager, private readonly Environment $twig, - private readonly FormFactoryInterface $formFactory + private readonly FormFactoryInterface $formFactory, ) { $this->templates = $bag->get('hackzilla_ticket.templates'); }