mirror of
https://github.com/rectorphp/rector.git
synced 2025-04-24 17:36:02 +02:00
[Kdyby to Contributte] Add Subscriber migration
This commit is contained in:
parent
beeb9b3458
commit
387ded5ecc
@ -133,7 +133,8 @@
|
||||
"Rector\\Performance\\": "rules/performance/src",
|
||||
"Rector\\Naming\\": "rules/naming/src",
|
||||
"Rector\\Order\\": "rules/order/src",
|
||||
"Rector\\MockistaToMockery\\": "rules/mockista-to-mockery/src"
|
||||
"Rector\\MockistaToMockery\\": "rules/mockista-to-mockery/src",
|
||||
"Rector\\NetteKdyby\\": "rules/nette-kdyby/src"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
@ -204,7 +205,8 @@
|
||||
"Rector\\Naming\\Tests\\": "rules/naming/tests",
|
||||
"Rector\\Order\\Tests\\": "rules/order/tests",
|
||||
"Rector\\MockistaToMockery\\Tests\\": "rules/mockista-to-mockery/tests",
|
||||
"Rector\\Compiler\\Tests\\": "compiler/tests"
|
||||
"Rector\\Compiler\\Tests\\": "compiler/tests",
|
||||
"Rector\\NetteKdyby\\Tests\\": "rules/nette-kdyby/tests"
|
||||
},
|
||||
"classmap": [
|
||||
"rules/cakephp/tests/Rector/Name/ImplicitShortClassNameUseStatementRector/Source",
|
||||
|
@ -0,0 +1,8 @@
|
||||
# from: https://github.com/Kdyby/Events/
|
||||
# to: https://github.com/contributte/event-dispatcher/
|
||||
services:
|
||||
Rector\Renaming\Rector\Class_\RenameClassRector:
|
||||
$oldToNewClasses:
|
||||
Kdyby\Events\Subscriber: 'Symfony\Component\EventDispatcher\EventSubscriberInterface'
|
||||
|
||||
Rector\NetteKdyby\Rector\Class_\KdybyEventSubscriberToContributteEventSubscriberRector: null
|
@ -1,4 +1,4 @@
|
||||
# All 487 Rectors Overview
|
||||
# All 488 Rectors Overview
|
||||
|
||||
- [Projects](#projects)
|
||||
- [General](#general)
|
||||
@ -26,6 +26,7 @@
|
||||
- [MysqlToMysqli](#mysqltomysqli) (4)
|
||||
- [Naming](#naming) (1)
|
||||
- [Nette](#nette) (12)
|
||||
- [NetteKdyby](#nettekdyby) (1)
|
||||
- [NetteTesterToPHPUnit](#nettetestertophpunit) (3)
|
||||
- [NetteToSymfony](#nettetosymfony) (9)
|
||||
- [Order](#order) (3)
|
||||
@ -4580,6 +4581,49 @@ Change $this->templates->{magic} to $this->template->render(..., $values)
|
||||
|
||||
<br>
|
||||
|
||||
## NetteKdyby
|
||||
|
||||
### `KdybyEventSubscriberToContributteEventSubscriberRector`
|
||||
|
||||
- class: [`Rector\NetteKdyby\Rector\Class_\KdybyEventSubscriberToContributteEventSubscriberRector`](/../master/rules/nette-kdyby/src/Rector/Class_/KdybyEventSubscriberToContributteEventSubscriberRector.php)
|
||||
- [test fixtures](/../master/rules/nette-kdyby/tests/Rector/Class_/KdybyEventSubscriberToContributteEventSubscriberRector/Fixture)
|
||||
|
||||
Change EventSubscriber from Kdyby to Contributte
|
||||
|
||||
```diff
|
||||
+use Contributte\Events\Extra\Event\Application\ShutdownEvent;
|
||||
use Kdyby\Events\Subscriber;
|
||||
use Nette\Application\Application;
|
||||
-use Nette\Application\UI\Presenter;
|
||||
|
||||
class GetApplesSubscriber implements Subscriber
|
||||
{
|
||||
- public function getSubscribedEvents()
|
||||
+ public static function getSubscribedEvents()
|
||||
{
|
||||
return [
|
||||
- Application::class . '::onShutdown',
|
||||
+ ShutdownEvent::class => 'onShutdown',
|
||||
CustomService::class . '::onCopy' => 'onCustomCopy',
|
||||
];
|
||||
}
|
||||
|
||||
- public function onShutdown(Presenter $presenter)
|
||||
+ public function onShutdown(ShutdownEvent $shutdownEvent)
|
||||
{
|
||||
+ $presenter = $shutdownEvent->getPresenter();
|
||||
$presenterName = $presenter->getName();
|
||||
// ...
|
||||
}
|
||||
|
||||
public function onCustomCopy()
|
||||
{
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
## NetteTesterToPHPUnit
|
||||
|
||||
### `NetteAssertToPHPUnitAssertRector`
|
||||
|
@ -25,6 +25,15 @@ final class ClassNaming
|
||||
$this->nodeNameResolver = $nodeNameResolver;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|Name|Identifier $name
|
||||
*/
|
||||
public function getVariableName($name): string
|
||||
{
|
||||
$shortName = $this->getShortName($name);
|
||||
return lcfirst($shortName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|Name|Identifier $name
|
||||
*/
|
||||
|
9
rules/nette-kdyby/config/config.yaml
Normal file
9
rules/nette-kdyby/config/config.yaml
Normal file
@ -0,0 +1,9 @@
|
||||
services:
|
||||
_defaults:
|
||||
public: true
|
||||
autowire: true
|
||||
|
||||
Rector\NetteKdyby\:
|
||||
resource: '../src'
|
||||
exclude:
|
||||
- '../src/Rector/**/*Rector.php'
|
90
rules/nette-kdyby/src/ContributeEventClassResolver.php
Normal file
90
rules/nette-kdyby/src/ContributeEventClassResolver.php
Normal file
@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\NetteKdyby;
|
||||
|
||||
use PhpParser\Node\Param;
|
||||
use Rector\Core\Exception\NotImplementedException;
|
||||
use Rector\NodeNameResolver\NodeNameResolver;
|
||||
|
||||
final class ContributeEventClassResolver
|
||||
{
|
||||
/**
|
||||
* @var string[][]
|
||||
*/
|
||||
private const GETTER_METHODS_WITH_TYPE_BY_EVENT_CLASS = [
|
||||
// application
|
||||
'Contributte\Events\Extra\Event\Application\ShutdownEvent' => [
|
||||
'Nette\Application\Application' => 'getApplication',
|
||||
'Throwable' => 'getThrowable',
|
||||
],
|
||||
'Contributte\Events\Extra\Event\Application\StartupEvent' => [
|
||||
'Nette\Application\Application' => 'getApplication',
|
||||
],
|
||||
'Contributte\Events\Extra\Event\Application\ErrorEvent' => [
|
||||
'Nette\Application\Application' => 'getApplication',
|
||||
'Throwable' => 'getThrowable',
|
||||
],
|
||||
'Contributte\Events\Extra\Event\Application\PresenterEvent' => [
|
||||
'Nette\Application\Application' => 'getApplication',
|
||||
'Nette\Application\IPresenter' => 'getPresenter',
|
||||
],
|
||||
'Contributte\Events\Extra\Event\Application\RequestEvent' => [
|
||||
'Nette\Application\Application' => 'getApplication',
|
||||
'Nette\Application\Request' => 'getRequest',
|
||||
],
|
||||
'Contributte\Events\Extra\Event\Application\ResponseEvent' => [
|
||||
'Nette\Application\Application' => 'getApplication',
|
||||
'Nette\Application\IResponse' => 'getResponse',
|
||||
],
|
||||
// presenter
|
||||
'Contributte\Events\Extra\Event\Application\PresenterShutdownEvent' => [
|
||||
'Nette\Application\IPresenter' => 'getPresenter',
|
||||
'Nette\Application\IResponse' => 'getResponse',
|
||||
],
|
||||
'Contributte\Events\Extra\Event\Application\PresenterStartupEvent' => [
|
||||
'Nette\Application\UI\Presenter' => 'getPresenter',
|
||||
],
|
||||
// nette/security
|
||||
'Contributte\Events\Extra\Event\Security\LoggedInEvent' => [
|
||||
'Nette\Security\User' => 'getUser',
|
||||
],
|
||||
'Contributte\Events\Extra\Event\Security\LoggedOutEvent' => [
|
||||
'Nette\Security\User' => 'getUser',
|
||||
],
|
||||
// latte
|
||||
'Contributte\Events\Extra\Event\Latte\LatteCompileEvent' => [
|
||||
'Latte\Engine' => 'getEngine',
|
||||
],
|
||||
'Contributte\Events\Extra\Event\Latte\TemplateCreateEvent' => [
|
||||
'Nette\Bridges\ApplicationLatte\Template' => 'getTemplate',
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
* @var NodeNameResolver
|
||||
*/
|
||||
private $nodeNameResolver;
|
||||
|
||||
public function __construct(NodeNameResolver $nodeNameResolver)
|
||||
{
|
||||
$this->nodeNameResolver = $nodeNameResolver;
|
||||
}
|
||||
|
||||
public function resolveGetterMethodByEventClassAndParam(string $eventClass, Param $param): string
|
||||
{
|
||||
$getterMethodsWithType = self::GETTER_METHODS_WITH_TYPE_BY_EVENT_CLASS[$eventClass] ?? null;
|
||||
|
||||
if ($param->type === null) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
$type = $this->nodeNameResolver->getName($param->type);
|
||||
if (isset($getterMethodsWithType[$type])) {
|
||||
return $getterMethodsWithType[$type];
|
||||
}
|
||||
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\NetteKdyby\NodeManipulator;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr\Array_;
|
||||
use PhpParser\Node\Expr\ArrayItem;
|
||||
use PhpParser\Node\Expr\ClassConstFetch;
|
||||
use PhpParser\Node\Name\FullyQualified;
|
||||
use Rector\Core\PhpParser\Node\Value\ValueResolver;
|
||||
use Rector\Core\PhpParser\NodeTraverser\CallableNodeTraverser;
|
||||
use Rector\NetteKdyby\ValueObject\NetteEventToContributeEventClass;
|
||||
|
||||
final class GetSubscribedEventsArrayManipulator
|
||||
{
|
||||
/**
|
||||
* @var CallableNodeTraverser
|
||||
*/
|
||||
private $callableNodeTraverser;
|
||||
|
||||
/**
|
||||
* @var ValueResolver
|
||||
*/
|
||||
private $valueResolver;
|
||||
|
||||
public function __construct(CallableNodeTraverser $callableNodeTraverser, ValueResolver $valueResolver)
|
||||
{
|
||||
$this->callableNodeTraverser = $callableNodeTraverser;
|
||||
$this->valueResolver = $valueResolver;
|
||||
}
|
||||
|
||||
public function change(Array_ $array): void
|
||||
{
|
||||
$this->callableNodeTraverser->traverseNodesWithCallable($array->items, function (Node $node): ?Node {
|
||||
if (! $node instanceof ArrayItem) {
|
||||
return null;
|
||||
}
|
||||
|
||||
foreach (NetteEventToContributeEventClass::PROPERTY_TO_EVENT_CLASS as $netteEventProperty => $contributeEventClass) {
|
||||
if ($node->key === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (! $this->valueResolver->isValue($node->key, $netteEventProperty)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$node->key = new ClassConstFetch(new FullyQualified($contributeEventClass), 'class');
|
||||
}
|
||||
|
||||
return $node;
|
||||
});
|
||||
}
|
||||
}
|
@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\NetteKdyby\NodeManipulator;
|
||||
|
||||
use PhpParser\Node\Expr\Assign;
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PhpParser\Node\Expr\Variable;
|
||||
use PhpParser\Node\Name\FullyQualified;
|
||||
use PhpParser\Node\Param;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PhpParser\Node\Stmt\Expression;
|
||||
use Rector\CodingStyle\Naming\ClassNaming;
|
||||
use Rector\NetteKdyby\ContributeEventClassResolver;
|
||||
|
||||
final class SubscriberMethodArgumentToContributteEventObjectManipulator
|
||||
{
|
||||
/**
|
||||
* @var ClassNaming
|
||||
*/
|
||||
private $classNaming;
|
||||
|
||||
/**
|
||||
* @var ContributeEventClassResolver
|
||||
*/
|
||||
private $contributeEventClassResolver;
|
||||
|
||||
public function __construct(
|
||||
ClassNaming $classNaming,
|
||||
ContributeEventClassResolver $contributeEventClassResolver
|
||||
) {
|
||||
$this->classNaming = $classNaming;
|
||||
$this->contributeEventClassResolver = $contributeEventClassResolver;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, ClassMethod> $classMethodsByEventClass
|
||||
*/
|
||||
public function change(array $classMethodsByEventClass): void
|
||||
{
|
||||
foreach ($classMethodsByEventClass as $eventClass => $classMethod) {
|
||||
$oldParams = $classMethod->params;
|
||||
|
||||
$this->changeClassParamToEventClass($eventClass, $classMethod);
|
||||
|
||||
// move params
|
||||
foreach ($oldParams as $oldParam) {
|
||||
$eventGetterToVariableAssign = $this->createEventGetterToVariableMethodCall($eventClass, $oldParam);
|
||||
$expression = new Expression($eventGetterToVariableAssign);
|
||||
|
||||
$classMethod->stmts = array_merge([$expression], (array) $classMethod->stmts);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function changeClassParamToEventClass(string $eventClass, ClassMethod $classMethod): void
|
||||
{
|
||||
/** @var ClassMethod $classMethod */
|
||||
$paramName = $this->classNaming->getVariableName($eventClass);
|
||||
$eventVariable = new Variable($paramName);
|
||||
|
||||
$param = new Param($eventVariable, null, new FullyQualified($eventClass));
|
||||
$classMethod->params = [$param];
|
||||
}
|
||||
|
||||
private function createEventGetterToVariableMethodCall(string $eventClass, Param $param): Assign
|
||||
{
|
||||
$paramName = $this->classNaming->getVariableName($eventClass);
|
||||
$eventVariable = new Variable($paramName);
|
||||
|
||||
$getterMethod = $this->contributeEventClassResolver->resolveGetterMethodByEventClassAndParam(
|
||||
$eventClass,
|
||||
$param
|
||||
);
|
||||
|
||||
$methodCall = new MethodCall($eventVariable, $getterMethod);
|
||||
|
||||
return new Assign($param->var, $methodCall);
|
||||
}
|
||||
}
|
@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\NetteKdyby\NodeResolver;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr\ArrayItem;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use Rector\Core\PhpParser\Node\Value\ValueResolver;
|
||||
use Rector\Core\PhpParser\NodeTraverser\CallableNodeTraverser;
|
||||
use Rector\NetteKdyby\ValueObject\NetteEventToContributeEventClass;
|
||||
|
||||
final class ListeningMethodsCollector
|
||||
{
|
||||
/**
|
||||
* @var CallableNodeTraverser
|
||||
*/
|
||||
private $callableNodeTraverser;
|
||||
|
||||
/**
|
||||
* @var ValueResolver
|
||||
*/
|
||||
private $valueResolver;
|
||||
|
||||
public function __construct(CallableNodeTraverser $callableNodeTraverser, ValueResolver $valueResolver)
|
||||
{
|
||||
$this->callableNodeTraverser = $callableNodeTraverser;
|
||||
$this->valueResolver = $valueResolver;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, ClassMethod>
|
||||
*/
|
||||
public function collectFromClassAndGetSubscribedEventClassMethod(Class_ $class, ClassMethod $classMethod): array
|
||||
{
|
||||
$classMethodsByEventClass = [];
|
||||
|
||||
$this->callableNodeTraverser->traverseNodesWithCallable((array) $classMethod->stmts, function (Node $node) use (
|
||||
$class,
|
||||
&$classMethodsByEventClass
|
||||
) {
|
||||
if (! $node instanceof ArrayItem) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$possibleMethodName = $this->valueResolver->getValue($node->value);
|
||||
if (! is_string($possibleMethodName)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$classMethod = $class->getMethod($possibleMethodName);
|
||||
if ($classMethod === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($node->key === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$eventClass = $this->valueResolver->getValue($node->key);
|
||||
|
||||
$contributeEventClasses = NetteEventToContributeEventClass::PROPERTY_TO_EVENT_CLASS;
|
||||
if (! in_array($eventClass, $contributeEventClasses, true)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$classMethodsByEventClass[$eventClass] = $classMethod;
|
||||
});
|
||||
|
||||
return $classMethodsByEventClass;
|
||||
}
|
||||
}
|
@ -0,0 +1,211 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\NetteKdyby\Rector\Class_;
|
||||
|
||||
use Kdyby\Events\Subscriber;
|
||||
use Nette\Utils\Strings;
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr;
|
||||
use PhpParser\Node\Expr\Array_;
|
||||
use PhpParser\Node\Scalar\String_;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PhpParser\Node\Stmt\Return_;
|
||||
use Rector\Core\Exception\NotImplementedException;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Core\RectorDefinition\CodeSample;
|
||||
use Rector\Core\RectorDefinition\RectorDefinition;
|
||||
use Rector\NetteKdyby\NodeManipulator\GetSubscribedEventsArrayManipulator;
|
||||
use Rector\NetteKdyby\NodeManipulator\SubscriberMethodArgumentToContributteEventObjectManipulator;
|
||||
use Rector\NetteKdyby\NodeResolver\ListeningMethodsCollector;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
|
||||
/**
|
||||
* @see \Rector\NetteKdyby\Tests\Rector\Class_\KdybyEventSubscriberToContributteEventSubscriberRector\KdybyEventSubscriberToContributteEventSubscriberRectorTest
|
||||
*/
|
||||
final class KdybyEventSubscriberToContributteEventSubscriberRector extends AbstractRector
|
||||
{
|
||||
/**
|
||||
* @var GetSubscribedEventsArrayManipulator
|
||||
*/
|
||||
private $getSubscribedEventsArrayManipulator;
|
||||
|
||||
/**
|
||||
* @var SubscriberMethodArgumentToContributteEventObjectManipulator
|
||||
*/
|
||||
private $subscriberMethodArgumentToContributteEventObjectManipulator;
|
||||
|
||||
/**
|
||||
* @var ListeningMethodsCollector
|
||||
*/
|
||||
private $listeningMethodsCollector;
|
||||
|
||||
public function __construct(
|
||||
GetSubscribedEventsArrayManipulator $getSubscribedEventsArrayManipulator,
|
||||
SubscriberMethodArgumentToContributteEventObjectManipulator $subscriberMethodArgumentToContributteEventObjectManipulator,
|
||||
ListeningMethodsCollector $listeningMethodsCollector
|
||||
) {
|
||||
$this->getSubscribedEventsArrayManipulator = $getSubscribedEventsArrayManipulator;
|
||||
$this->subscriberMethodArgumentToContributteEventObjectManipulator = $subscriberMethodArgumentToContributteEventObjectManipulator;
|
||||
$this->listeningMethodsCollector = $listeningMethodsCollector;
|
||||
}
|
||||
|
||||
public function getDefinition(): RectorDefinition
|
||||
{
|
||||
return new RectorDefinition('Change EventSubscriber from Kdyby to Contributte', [
|
||||
new CodeSample(
|
||||
<<<'PHP'
|
||||
use Kdyby\Events\Subscriber;
|
||||
use Nette\Application\Application;
|
||||
use Nette\Application\UI\Presenter;
|
||||
|
||||
class GetApplesSubscriber implements Subscriber
|
||||
{
|
||||
public function getSubscribedEvents()
|
||||
{
|
||||
return [
|
||||
Application::class . '::onShutdown',
|
||||
CustomService::class . '::onCopy' => 'onCustomCopy',
|
||||
];
|
||||
}
|
||||
|
||||
public function onShutdown(Presenter $presenter)
|
||||
{
|
||||
$presenterName = $presenter->getName();
|
||||
// ...
|
||||
}
|
||||
|
||||
public function onCustomCopy()
|
||||
{
|
||||
}
|
||||
}
|
||||
PHP
|
||||
,
|
||||
<<<'PHP'
|
||||
use Contributte\Events\Extra\Event\Application\ShutdownEvent;
|
||||
use Kdyby\Events\Subscriber;
|
||||
use Nette\Application\Application;
|
||||
|
||||
class GetApplesSubscriber implements Subscriber
|
||||
{
|
||||
public static function getSubscribedEvents()
|
||||
{
|
||||
return [
|
||||
ShutdownEvent::class => 'onShutdown',
|
||||
CustomService::class . '::onCopy' => 'onCustomCopy',
|
||||
];
|
||||
}
|
||||
|
||||
public function onShutdown(ShutdownEvent $shutdownEvent)
|
||||
{
|
||||
$presenter = $shutdownEvent->getPresenter();
|
||||
$presenterName = $presenter->getName();
|
||||
// ...
|
||||
}
|
||||
|
||||
public function onCustomCopy()
|
||||
{
|
||||
}
|
||||
}
|
||||
PHP
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getNodeTypes(): array
|
||||
{
|
||||
return [ClassMethod::class];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ClassMethod $node
|
||||
*/
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
if ($this->shouldSkipClassMethod($node)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$class = $node->getAttribute(AttributeKey::CLASS_NODE);
|
||||
if (! $class instanceof Class_) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$this->makeStatic($node);
|
||||
|
||||
$this->refactorEventNames($node);
|
||||
|
||||
$listeningClassMethods = $this->listeningMethodsCollector->collectFromClassAndGetSubscribedEventClassMethod(
|
||||
$class,
|
||||
$node
|
||||
);
|
||||
|
||||
$this->subscriberMethodArgumentToContributteEventObjectManipulator->change($listeningClassMethods);
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
||||
private function resolveMethodNameFromKdybyEventName(Expr $expr): string
|
||||
{
|
||||
$kdybyEventName = $this->getValue($expr);
|
||||
if (Strings::contains($kdybyEventName, '::')) {
|
||||
return (string) Strings::after($kdybyEventName, '::', - 1);
|
||||
}
|
||||
|
||||
throw new NotImplementedException($kdybyEventName);
|
||||
}
|
||||
|
||||
private function shouldSkipClassMethod($node): bool
|
||||
{
|
||||
$class = $node->getAttribute(AttributeKey::CLASS_NODE);
|
||||
if ($class === null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (! $this->isObjectType($class, Subscriber::class)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return ! $this->isName($node, 'getSubscribedEvents');
|
||||
}
|
||||
|
||||
private function refactorArrayWithEventTable(Array_ $array): void
|
||||
{
|
||||
foreach ($array->items as $arrayItem) {
|
||||
if ($arrayItem->key !== null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$methodName = $this->resolveMethodNameFromKdybyEventName($arrayItem->value);
|
||||
$arrayItem->key = $arrayItem->value;
|
||||
$arrayItem->value = new String_($methodName);
|
||||
}
|
||||
}
|
||||
|
||||
private function refactorEventNames(ClassMethod $classMethod): void
|
||||
{
|
||||
$this->traverseNodesWithCallable((array) $classMethod->stmts, function (Node $node) {
|
||||
if (! $node instanceof Return_) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($node->expr === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$returnedExpr = $node->expr;
|
||||
if (! $returnedExpr instanceof Array_) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$this->refactorArrayWithEventTable($returnedExpr);
|
||||
|
||||
$this->getSubscribedEventsArrayManipulator->change($returnedExpr);
|
||||
});
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\NetteKdyby\ValueObject;
|
||||
|
||||
final class NetteEventToContributeEventClass
|
||||
{
|
||||
/**
|
||||
* @var string[]
|
||||
* @see https://github.com/contributte/event-dispatcher-extra/tree/master/src/Event
|
||||
*/
|
||||
public const PROPERTY_TO_EVENT_CLASS = [
|
||||
// application
|
||||
'Nette\Application\Application::onShutdown' => 'Contributte\Events\Extra\Event\Application\ShutdownEvent',
|
||||
'Nette\Application\Application::onStartup' => 'Contributte\Events\Extra\Event\Application\StartupEvent',
|
||||
'Nette\Application\Application::onError' => 'Contributte\Events\Extra\Event\Application\ErrorEvent',
|
||||
'Nette\Application\Application::onPresenter' => 'Contributte\Events\Extra\Event\Application\PresenterEvent',
|
||||
'Nette\Application\Application::onRequest' => 'Contributte\Events\Extra\Event\Application\RequestEvent',
|
||||
'Nette\Application\Application::onResponse' => 'Contributte\Events\Extra\Event\Application\ResponseEvent',
|
||||
// presenter
|
||||
'Nette\Application\UI\Presenter::onStartup' => 'Contributte\Events\Extra\Event\Application\PresenterShutdownEvent',
|
||||
'Nette\Application\UI\Presenter::onShutdown' => 'Contributte\Events\Extra\Event\Application\PresenterStartupEvent',
|
||||
// nette/security
|
||||
'Nette\Security\User::onLoggedIn' => 'Contributte\Events\Extra\Event\Security\LoggedInEvent',
|
||||
'Nette\Security\User::onLoggedOut' => 'Contributte\Events\Extra\Event\Security\LoggedOutEvent',
|
||||
// latte
|
||||
'Latte\Engine::onCompile' => 'Contributte\Events\Extra\Event\Latte\LatteCompileEvent',
|
||||
'Nette\Bridges\ApplicationLatte\TemplateFactory::onCreate' => 'Contributte\Events\Extra\Event\Latte\TemplateCreateEvent',
|
||||
];
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
namespace Rector\NetteKdyby\Tests\Rector\Class_\KdybyEventSubscriberToContributteEventSubscriberRector\Fixture;
|
||||
|
||||
use Kdyby\Events\Subscriber;
|
||||
use Nette\Application\Application;
|
||||
|
||||
class GetApplesSubscriber implements Subscriber
|
||||
{
|
||||
public function getSubscribedEvents()
|
||||
{
|
||||
return [
|
||||
Application::class . '::onShutdown',
|
||||
CustomService::class . '::onCopy' => 'onCustomCopy',
|
||||
];
|
||||
}
|
||||
|
||||
public function onShutdown(Application $application): void
|
||||
{
|
||||
$presenter = $application->getPresenter();
|
||||
}
|
||||
|
||||
public function onCustomCopy()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\NetteKdyby\Tests\Rector\Class_\KdybyEventSubscriberToContributteEventSubscriberRector\Fixture;
|
||||
|
||||
use Kdyby\Events\Subscriber;
|
||||
use Nette\Application\Application;
|
||||
|
||||
class GetApplesSubscriber implements Subscriber
|
||||
{
|
||||
public static function getSubscribedEvents()
|
||||
{
|
||||
return [
|
||||
\Contributte\Events\Extra\Event\Application\ShutdownEvent::class => 'onShutdown',
|
||||
CustomService::class . '::onCopy' => 'onCustomCopy',
|
||||
];
|
||||
}
|
||||
|
||||
public function onShutdown(\Contributte\Events\Extra\Event\Application\ShutdownEvent $shutdownEvent): void
|
||||
{
|
||||
$application = $shutdownEvent->getApplication();
|
||||
$presenter = $application->getPresenter();
|
||||
}
|
||||
|
||||
public function onCustomCopy()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\NetteKdyby\Tests\Rector\Class_\KdybyEventSubscriberToContributteEventSubscriberRector;
|
||||
|
||||
use Iterator;
|
||||
use Rector\Core\Testing\PHPUnit\AbstractRectorTestCase;
|
||||
use Rector\NetteKdyby\Rector\Class_\KdybyEventSubscriberToContributteEventSubscriberRector;
|
||||
|
||||
final class KdybyEventSubscriberToContributteEventSubscriberRectorTest extends AbstractRectorTestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideData()
|
||||
*/
|
||||
public function test(string $file): void
|
||||
{
|
||||
$this->doTestFile($file);
|
||||
}
|
||||
|
||||
public function provideData(): Iterator
|
||||
{
|
||||
return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture');
|
||||
}
|
||||
|
||||
protected function getRectorClass(): string
|
||||
{
|
||||
return KdybyEventSubscriberToContributteEventSubscriberRector::class;
|
||||
}
|
||||
}
|
14
stubs/Kdyby/Events/Subscriber.php
Normal file
14
stubs/Kdyby/Events/Subscriber.php
Normal file
@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Kdyby\Events;
|
||||
|
||||
if (interface_exists('Kdyby\Events\Subscriber')) {
|
||||
return;
|
||||
}
|
||||
|
||||
interface Subscriber
|
||||
{
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user