mirror of
https://github.com/rectorphp/rector.git
synced 2025-02-21 01:41:00 +01:00
[Symfony] Add MergeMethodAnnotationToRouteAnnotationRector (#2020)
[Symfony] Add MergeMethodAnnotationToRouteAnnotationRector
This commit is contained in:
commit
ce9f0b75de
@ -6,3 +6,4 @@ services:
|
||||
|
||||
# add Uuid type declarations
|
||||
Rector\TypeDeclaration\Rector\ClassMethod\AddMethodCallBasedParamTypeRector: ~
|
||||
Rector\TypeDeclaration\Rector\ClassMethod\AddArrayReturnDocTypeRector: ~
|
||||
|
@ -4,3 +4,4 @@ services:
|
||||
parse:
|
||||
2:
|
||||
- 'Symfony\Component\Yaml\Yaml::PARSE_KEYS_AS_STRINGS'
|
||||
Rector\Symfony\Rector\ClassMethod\MergeMethodAnnotationToRouteAnnotationRector: ~
|
||||
|
@ -31,7 +31,7 @@ abstract class AbstractTagValueNode implements AttributeAwareNodeInterface, PhpD
|
||||
/**
|
||||
* @param mixed[] $item
|
||||
*/
|
||||
protected function printArrayItem(array $item, string $key): string
|
||||
protected function printArrayItem(array $item, ?string $key = null): string
|
||||
{
|
||||
$json = Json::encode($item);
|
||||
$json = Strings::replace($json, '#,#', ', ');
|
||||
@ -40,7 +40,11 @@ abstract class AbstractTagValueNode implements AttributeAwareNodeInterface, PhpD
|
||||
// cleanup json encoded extra slashes
|
||||
$json = Strings::replace($json, '#\\\\\\\\#', '\\');
|
||||
|
||||
return sprintf('%s=%s', $key, $json);
|
||||
if ($key) {
|
||||
return sprintf('%s=%s', $key, $json);
|
||||
}
|
||||
|
||||
return $json;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -0,0 +1,45 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Rector\NetteToSymfony\PhpDocParser\Ast\PhpDoc;
|
||||
|
||||
use Rector\BetterPhpDocParser\PhpDocParser\Ast\PhpDoc\AbstractTagValueNode;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
|
||||
|
||||
final class SymfonyMethodTagValueNode extends AbstractTagValueNode
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public const SHORT_NAME = '@Method';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public const CLASS_NAME = Method::class;
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
private $methods = [];
|
||||
|
||||
/**
|
||||
* @param string[] $methods
|
||||
*/
|
||||
public function __construct(array $methods = [])
|
||||
{
|
||||
$this->methods = $methods;
|
||||
}
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return '(' . $this->printArrayItem($this->methods) . ')';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getMethods(): array
|
||||
{
|
||||
return $this->methods;
|
||||
}
|
||||
}
|
@ -5,7 +5,7 @@ namespace Rector\NetteToSymfony\PhpDocParser\Ast\PhpDoc;
|
||||
use Rector\BetterPhpDocParser\PhpDocParser\Ast\PhpDoc\AbstractTagValueNode;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
|
||||
final class SymfonyRoutePhpDocTagValueNode extends AbstractTagValueNode
|
||||
final class SymfonyRouteTagValueNode extends AbstractTagValueNode
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
@ -47,6 +47,11 @@ final class SymfonyRoutePhpDocTagValueNode extends AbstractTagValueNode
|
||||
|
||||
if ($originalContent !== null) {
|
||||
$this->resolveOriginalContentSpacingAndOrder($originalContent);
|
||||
|
||||
// default value without key
|
||||
if ($this->path && ! in_array('path', (array) $this->orderedVisibleItems, true)) {
|
||||
$this->orderedVisibleItems[] = 'path';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -66,4 +71,13 @@ final class SymfonyRoutePhpDocTagValueNode extends AbstractTagValueNode
|
||||
|
||||
return $this->printContentItems($contentItems);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed[] $methods
|
||||
*/
|
||||
public function changeMethods(array $methods): void
|
||||
{
|
||||
$this->orderedVisibleItems[] = 'methods';
|
||||
$this->methods = $methods;
|
||||
}
|
||||
}
|
@ -11,7 +11,7 @@ use PhpParser\Node\Stmt\Class_;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use Rector\BetterPhpDocParser\Attributes\Ast\PhpDoc\SpacelessPhpDocTagNode;
|
||||
use Rector\NetteToSymfony\PhpDocParser\Ast\PhpDoc\SymfonyRoutePhpDocTagValueNode;
|
||||
use Rector\NetteToSymfony\PhpDocParser\Ast\PhpDoc\SymfonyRouteTagValueNode;
|
||||
use Rector\NetteToSymfony\Route\RouteInfo;
|
||||
use Rector\NetteToSymfony\Route\RouteInfoFactory;
|
||||
use Rector\NodeContainer\ParsedNodesByType;
|
||||
@ -256,7 +256,7 @@ PHP
|
||||
}
|
||||
|
||||
$path = $this->resolvePathFromClassAndMethodNodes($presenterClass, $classMethod);
|
||||
$symfonyRoutePhpDocTagValueNode = new SymfonyRoutePhpDocTagValueNode($path);
|
||||
$symfonyRoutePhpDocTagValueNode = new SymfonyRouteTagValueNode($path);
|
||||
|
||||
$this->addSymfonyRouteShortTagNodeWithUse($symfonyRoutePhpDocTagValueNode, $classMethod);
|
||||
}
|
||||
@ -319,7 +319,7 @@ PHP
|
||||
return false;
|
||||
}
|
||||
|
||||
return (bool) $phpDocInfo->getByType(SymfonyRoutePhpDocTagValueNode::class);
|
||||
return (bool) $phpDocInfo->getByType(SymfonyRouteTagValueNode::class);
|
||||
}
|
||||
|
||||
private function resolvePathFromClassAndMethodNodes(Class_ $classNode, ClassMethod $classMethod): string
|
||||
@ -338,23 +338,23 @@ PHP
|
||||
return $presenterPart . '/' . $actionPart;
|
||||
}
|
||||
|
||||
private function createSymfonyRoutePhpDocTagValueNode(RouteInfo $routeInfo): SymfonyRoutePhpDocTagValueNode
|
||||
private function createSymfonyRoutePhpDocTagValueNode(RouteInfo $routeInfo): SymfonyRouteTagValueNode
|
||||
{
|
||||
return new SymfonyRoutePhpDocTagValueNode($routeInfo->getPath(), null, $routeInfo->getHttpMethods());
|
||||
return new SymfonyRouteTagValueNode($routeInfo->getPath(), null, $routeInfo->getHttpMethods());
|
||||
}
|
||||
|
||||
private function addSymfonyRouteShortTagNodeWithUse(
|
||||
SymfonyRoutePhpDocTagValueNode $symfonyRoutePhpDocTagValueNode,
|
||||
SymfonyRouteTagValueNode $symfonyRouteTagValueNode,
|
||||
ClassMethod $classMethod
|
||||
): void {
|
||||
$symfonyRoutePhpDocTagNode = new SpacelessPhpDocTagNode(
|
||||
SymfonyRoutePhpDocTagValueNode::SHORT_NAME,
|
||||
$symfonyRoutePhpDocTagValueNode
|
||||
SymfonyRouteTagValueNode::SHORT_NAME,
|
||||
$symfonyRouteTagValueNode
|
||||
);
|
||||
|
||||
$this->docBlockManipulator->addTag($classMethod, $symfonyRoutePhpDocTagNode);
|
||||
|
||||
$symfonyRouteUseObjectType = new FullyQualifiedObjectType(SymfonyRoutePhpDocTagValueNode::CLASS_NAME);
|
||||
$symfonyRouteUseObjectType = new FullyQualifiedObjectType(SymfonyRouteTagValueNode::CLASS_NAME);
|
||||
$this->addUseType($symfonyRouteUseObjectType, $classMethod);
|
||||
|
||||
// remove
|
||||
|
@ -22,7 +22,7 @@ final class SymfonyPhpDocParserExtension implements PhpDocParserExtensionInterfa
|
||||
|
||||
public function matchTag(string $tag): bool
|
||||
{
|
||||
return (bool) Strings::match($tag, '#^@(Route|((Assert|Serializer)\\\\[\w]+))$#');
|
||||
return (bool) Strings::match($tag, '#^@(Route|Method|((Assert|Serializer)\\\\[\w]+))$#');
|
||||
}
|
||||
|
||||
public function parse(TokenIterator $tokenIterator, string $tag): ?PhpDocTagValueNode
|
||||
|
@ -8,10 +8,12 @@ use PhpParser\Node\Stmt\Property;
|
||||
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagValueNode;
|
||||
use PHPStan\PhpDocParser\Parser\TokenIterator;
|
||||
use Rector\BetterPhpDocParser\PhpDocParser\AbstractPhpDocParser;
|
||||
use Rector\NetteToSymfony\PhpDocParser\Ast\PhpDoc\SymfonyRoutePhpDocTagValueNode;
|
||||
use Rector\NetteToSymfony\PhpDocParser\Ast\PhpDoc\SymfonyMethodTagValueNode;
|
||||
use Rector\NetteToSymfony\PhpDocParser\Ast\PhpDoc\SymfonyRouteTagValueNode;
|
||||
use Rector\Symfony\PhpDocParser\Ast\PhpDoc\AssertChoiceTagValueNode;
|
||||
use Rector\Symfony\PhpDocParser\Ast\PhpDoc\AssertTypeTagValueNode;
|
||||
use Rector\Symfony\PhpDocParser\Ast\PhpDoc\SerializerTypeTagValueNode;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
use Symfony\Component\Validator\Constraints\Choice;
|
||||
use Symfony\Component\Validator\Constraints\Type as ValidatorType;
|
||||
@ -25,9 +27,13 @@ final class SymfonyPhpDocTagParser extends AbstractPhpDocParser
|
||||
// this is needed to append tokens to the end of annotation, even if not used
|
||||
$annotationContent = $this->resolveAnnotationContent($tokenIterator);
|
||||
if ($currentPhpNode instanceof ClassMethod) {
|
||||
if ($tag === SymfonyRoutePhpDocTagValueNode::SHORT_NAME) {
|
||||
if ($tag === SymfonyRouteTagValueNode::SHORT_NAME) {
|
||||
return $this->createSymfonyRouteTagValueNode($currentPhpNode, $annotationContent);
|
||||
}
|
||||
|
||||
if ($tag === SymfonyMethodTagValueNode::SHORT_NAME) {
|
||||
return $this->createSymfonyMethodTagValueNode($currentPhpNode);
|
||||
}
|
||||
}
|
||||
|
||||
if ($currentPhpNode instanceof Property) {
|
||||
@ -63,15 +69,15 @@ final class SymfonyPhpDocTagParser extends AbstractPhpDocParser
|
||||
private function createSymfonyRouteTagValueNode(
|
||||
ClassMethod $classMethod,
|
||||
string $annotationContent
|
||||
): SymfonyRoutePhpDocTagValueNode {
|
||||
): SymfonyRouteTagValueNode {
|
||||
/** @var Route $routeAnnotation */
|
||||
$routeAnnotation = $this->nodeAnnotationReader->readMethodAnnotation(
|
||||
$classMethod,
|
||||
SymfonyRoutePhpDocTagValueNode::CLASS_NAME
|
||||
SymfonyRouteTagValueNode::CLASS_NAME
|
||||
);
|
||||
|
||||
// @todo possibly extends with all Symfony Route attributes
|
||||
return new SymfonyRoutePhpDocTagValueNode(
|
||||
return new SymfonyRouteTagValueNode(
|
||||
$routeAnnotation->getPath(),
|
||||
$routeAnnotation->getName(),
|
||||
$routeAnnotation->getMethods(),
|
||||
@ -79,6 +85,17 @@ final class SymfonyPhpDocTagParser extends AbstractPhpDocParser
|
||||
);
|
||||
}
|
||||
|
||||
private function createSymfonyMethodTagValueNode(ClassMethod $classMethod): SymfonyMethodTagValueNode
|
||||
{
|
||||
/** @var Method $methodAnnotation */
|
||||
$methodAnnotation = $this->nodeAnnotationReader->readMethodAnnotation(
|
||||
$classMethod,
|
||||
SymfonyMethodTagValueNode::CLASS_NAME
|
||||
);
|
||||
|
||||
return new SymfonyMethodTagValueNode($methodAnnotation->getMethods());
|
||||
}
|
||||
|
||||
private function createSerializerTypeTagValueNode(
|
||||
Property $property,
|
||||
string $annotationContent
|
||||
|
@ -0,0 +1,107 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Rector\Symfony\Rector\ClassMethod;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use Rector\NetteToSymfony\PhpDocParser\Ast\PhpDoc\SymfonyMethodTagValueNode;
|
||||
use Rector\NetteToSymfony\PhpDocParser\Ast\PhpDoc\SymfonyRouteTagValueNode;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Rector\Rector\AbstractRector;
|
||||
use Rector\RectorDefinition\CodeSample;
|
||||
use Rector\RectorDefinition\RectorDefinition;
|
||||
|
||||
/**
|
||||
* @see https://symfony.com/doc/current/bundles/SensioFrameworkExtraBundle/annotations/routing.html#method-annotation
|
||||
* @see https://stackoverflow.com/questions/51171934/how-to-fix-symfony-3-4-route-and-method-deprecation
|
||||
*
|
||||
* @see \Rector\Symfony\Tests\Rector\ClassMethod\MergeMethodAnnotationToRouteAnnotationRector\MergeMethodAnnotationToRouteAnnotationRectorTest
|
||||
*/
|
||||
final class MergeMethodAnnotationToRouteAnnotationRector extends AbstractRector
|
||||
{
|
||||
public function getDefinition(): RectorDefinition
|
||||
{
|
||||
return new RectorDefinition('Merge removed @Method annotation to @Route one', [
|
||||
new CodeSample(
|
||||
<<<'PHP'
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
|
||||
class DefaultController extends Controller
|
||||
{
|
||||
/**
|
||||
* @Route("/show/{id}")
|
||||
* @Method({"GET", "HEAD"})
|
||||
*/
|
||||
public function show($id)
|
||||
{
|
||||
}
|
||||
}
|
||||
PHP
|
||||
,
|
||||
<<<'PHP'
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
|
||||
class DefaultController extends Controller
|
||||
{
|
||||
/**
|
||||
* @Route("/show/{id}", methods={"GET","HEAD"})
|
||||
*/
|
||||
public function show($id)
|
||||
{
|
||||
}
|
||||
}
|
||||
PHP
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getNodeTypes(): array
|
||||
{
|
||||
return [ClassMethod::class];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ClassMethod $node
|
||||
*/
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
$classNode = $node->getAttribute(AttributeKey::CLASS_NODE);
|
||||
if ($classNode === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (! $this->isObjectType($classNode, '*Controller')) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (! $node->isPublic()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$phpDocInfo = $this->getPhpDocInfo($node);
|
||||
if ($phpDocInfo === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$symfonyMethodPhpDocTagValueNode = $phpDocInfo->getByType(SymfonyMethodTagValueNode::class);
|
||||
if ($symfonyMethodPhpDocTagValueNode === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$methods = $symfonyMethodPhpDocTagValueNode->getMethods();
|
||||
|
||||
/** @var SymfonyRouteTagValueNode $symfonyRoutePhpDocTagValueNode */
|
||||
$symfonyRoutePhpDocTagValueNode = $phpDocInfo->getByType(SymfonyRouteTagValueNode::class);
|
||||
$symfonyRoutePhpDocTagValueNode->changeMethods($methods);
|
||||
|
||||
$phpDocInfo->removeTagValueNodeFromNode($symfonyMethodPhpDocTagValueNode);
|
||||
|
||||
$this->docBlockManipulator->updateNodeWithPhpDocInfo($node, $phpDocInfo);
|
||||
|
||||
return $node;
|
||||
}
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace Rector\Symfony\Tests\Rector\ClassMethod\MergeMethodAnnotationToRouteAnnotationRector\Fixture;
|
||||
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
|
||||
class DefaultController
|
||||
{
|
||||
/**
|
||||
* @Route("/show/{id}")
|
||||
* @Method({"GET", "HEAD"})
|
||||
*/
|
||||
public function show($id)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Symfony\Tests\Rector\ClassMethod\MergeMethodAnnotationToRouteAnnotationRector\Fixture;
|
||||
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
|
||||
class DefaultController
|
||||
{
|
||||
/**
|
||||
* @Route(path="/show/{id}", methods={"GET", "HEAD"})
|
||||
*/
|
||||
public function show($id)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
@ -0,0 +1,30 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Rector\Symfony\Tests\Rector\ClassMethod\MergeMethodAnnotationToRouteAnnotationRector;
|
||||
|
||||
use Rector\Symfony\Rector\ClassMethod\MergeMethodAnnotationToRouteAnnotationRector;
|
||||
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
|
||||
|
||||
final class MergeMethodAnnotationToRouteAnnotationRectorTest extends AbstractRectorTestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideDataForTest()
|
||||
*/
|
||||
public function test(string $file): void
|
||||
{
|
||||
$this->doTestFile($file);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function provideDataForTest(): iterable
|
||||
{
|
||||
yield [__DIR__ . '/Fixture/fixture.php.inc'];
|
||||
}
|
||||
|
||||
protected function getRectorClass(): string
|
||||
{
|
||||
return MergeMethodAnnotationToRouteAnnotationRector::class;
|
||||
}
|
||||
}
|
@ -28,6 +28,9 @@ final class AddArrayReturnDocTypeRectorTest extends AbstractRectorTestCase
|
||||
yield [__DIR__ . '/Fixture/yield_strings.php.inc'];
|
||||
yield [__DIR__ . '/Fixture/add_without_return_type_declaration.php.inc'];
|
||||
yield [__DIR__ . '/Fixture/fix_incorrect_array.php.inc'];
|
||||
yield [__DIR__ . '/Fixture/return_uuid.php.inc'];
|
||||
|
||||
// skip
|
||||
yield [__DIR__ . '/Fixture/skip_shorten_class_name.php.inc'];
|
||||
yield [__DIR__ . '/Fixture/skip_constructor.php.inc'];
|
||||
yield [__DIR__ . '/Fixture/skip_inner_function_return.php.inc'];
|
||||
|
@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
namespace Rector\TypeDeclaration\Tests\Rector\ClassMethod\AddArrayReturnDocTypeRector\Fixture;
|
||||
|
||||
use Rector\TypeDeclaration\Tests\Rector\ClassMethod\AddArrayReturnDocTypeRector\Source\EntityReturningUuid;
|
||||
|
||||
final class ReturnUuid
|
||||
{
|
||||
/**
|
||||
* @var EntityReturningUuid[]
|
||||
*/
|
||||
private $amenityBuildings = [];
|
||||
|
||||
/**
|
||||
* @return int[]
|
||||
*/
|
||||
public function getBuildingIds(): array
|
||||
{
|
||||
$buildingIds = [];
|
||||
foreach ($this->amenityBuildings as $amenityBuilding) {
|
||||
$buildingIds[] = $amenityBuilding->getId();
|
||||
}
|
||||
|
||||
return $buildingIds;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\TypeDeclaration\Tests\Rector\ClassMethod\AddArrayReturnDocTypeRector\Fixture;
|
||||
|
||||
use Rector\TypeDeclaration\Tests\Rector\ClassMethod\AddArrayReturnDocTypeRector\Source\EntityReturningUuid;
|
||||
|
||||
final class ReturnUuid
|
||||
{
|
||||
/**
|
||||
* @var EntityReturningUuid[]
|
||||
*/
|
||||
private $amenityBuildings = [];
|
||||
|
||||
/**
|
||||
* @return \Ramsey\Uuid\UuidInterface[]
|
||||
*/
|
||||
public function getBuildingIds(): array
|
||||
{
|
||||
$buildingIds = [];
|
||||
foreach ($this->amenityBuildings as $amenityBuilding) {
|
||||
$buildingIds[] = $amenityBuilding->getId();
|
||||
}
|
||||
|
||||
return $buildingIds;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
@ -0,0 +1,14 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Rector\TypeDeclaration\Tests\Rector\ClassMethod\AddArrayReturnDocTypeRector\Source;
|
||||
|
||||
use Ramsey\Uuid\Uuid;
|
||||
use Ramsey\Uuid\UuidInterface;
|
||||
|
||||
final class EntityReturningUuid
|
||||
{
|
||||
public function getId(): UuidInterface
|
||||
{
|
||||
return Uuid::uuid4();
|
||||
}
|
||||
}
|
@ -11,7 +11,7 @@ use PhpParser\Node\Name\FullyQualified;
|
||||
use PhpParser\Node\Param;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use Rector\BetterPhpDocParser\Attributes\Ast\PhpDoc\SpacelessPhpDocTagNode;
|
||||
use Rector\NetteToSymfony\PhpDocParser\Ast\PhpDoc\SymfonyRoutePhpDocTagValueNode;
|
||||
use Rector\NetteToSymfony\PhpDocParser\Ast\PhpDoc\SymfonyRouteTagValueNode;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Rector\NodeTypeResolver\PhpDoc\NodeAnalyzer\DocBlockManipulator;
|
||||
use Rector\PHPStan\Type\FullyQualifiedObjectType;
|
||||
@ -141,13 +141,13 @@ PHP
|
||||
{
|
||||
$symfonyRoutePhpDocTagNode = $routeValueObject->getSymfonyRoutePhpDocTagNode();
|
||||
$symfonyRoutePhpDocNode = new SpacelessPhpDocTagNode(
|
||||
SymfonyRoutePhpDocTagValueNode::SHORT_NAME,
|
||||
SymfonyRouteTagValueNode::SHORT_NAME,
|
||||
$symfonyRoutePhpDocTagNode
|
||||
);
|
||||
|
||||
$this->docBlockManipulator->addTag($classMethod, $symfonyRoutePhpDocNode);
|
||||
|
||||
$this->addUseType(new FullyQualifiedObjectType(SymfonyRoutePhpDocTagValueNode::CLASS_NAME), $classMethod);
|
||||
$this->addUseType(new FullyQualifiedObjectType(SymfonyRouteTagValueNode::CLASS_NAME), $classMethod);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3,7 +3,7 @@
|
||||
namespace Rector\ZendToSymfony\ValueObject;
|
||||
|
||||
use Nette\Utils\Strings;
|
||||
use Rector\NetteToSymfony\PhpDocParser\Ast\PhpDoc\SymfonyRoutePhpDocTagValueNode;
|
||||
use Rector\NetteToSymfony\PhpDocParser\Ast\PhpDoc\SymfonyRouteTagValueNode;
|
||||
use Rector\Util\RectorStrings;
|
||||
|
||||
final class RouteValueObject
|
||||
@ -51,9 +51,9 @@ final class RouteValueObject
|
||||
return $this->params;
|
||||
}
|
||||
|
||||
public function getSymfonyRoutePhpDocTagNode(): SymfonyRoutePhpDocTagValueNode
|
||||
public function getSymfonyRoutePhpDocTagNode(): SymfonyRouteTagValueNode
|
||||
{
|
||||
return new SymfonyRoutePhpDocTagValueNode($this->getPath());
|
||||
return new SymfonyRouteTagValueNode($this->getPath());
|
||||
}
|
||||
|
||||
private function getPath(): string
|
||||
|
@ -0,0 +1,16 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Sensio\Bundle\FrameworkExtraBundle\Configuration;
|
||||
|
||||
abstract class ConfigurationAnnotation
|
||||
{
|
||||
public function __construct(array $values)
|
||||
{
|
||||
foreach ($values as $k => $v) {
|
||||
if (!method_exists($this, $name = 'set'.$k)) {
|
||||
throw new \RuntimeException(sprintf('Unknown key "%s" for annotation "@%s".', $k, \get_class($this)));
|
||||
}
|
||||
$this->$name($v);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,69 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace Sensio\Bundle\FrameworkExtraBundle\Configuration;
|
||||
|
||||
if (class_exists('Sensio\Bundle\FrameworkExtraBundle\Configuration\Method')) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @Annotation
|
||||
*/
|
||||
class Method extends ConfigurationAnnotation
|
||||
{
|
||||
/**
|
||||
* An array of restricted HTTP methods.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $methods = [];
|
||||
/**
|
||||
* Returns the array of HTTP methods.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getMethods()
|
||||
{
|
||||
return $this->methods;
|
||||
}
|
||||
/**
|
||||
* Sets the HTTP methods.
|
||||
*
|
||||
* @param array|string $methods An HTTP method or an array of HTTP methods
|
||||
*/
|
||||
public function setMethods($methods)
|
||||
{
|
||||
$this->methods = \is_array($methods) ? $methods : [$methods];
|
||||
}
|
||||
/**
|
||||
* Sets the HTTP methods.
|
||||
*
|
||||
* @param array|string $methods An HTTP method or an array of HTTP methods
|
||||
*/
|
||||
public function setValue($methods)
|
||||
{
|
||||
$this->setMethods($methods);
|
||||
}
|
||||
/**
|
||||
* Returns the annotation alias name.
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @see ConfigurationInterface
|
||||
*/
|
||||
public function getAliasName()
|
||||
{
|
||||
return 'method';
|
||||
}
|
||||
/**
|
||||
* Only one method directive is allowed.
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @see ConfigurationInterface
|
||||
*/
|
||||
public function allowArray()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user