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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ services:
Kdyby\Events\Subscriber: 'Symfony\Component\EventDispatcher\EventSubscriberInterface'

Rector\NetteKdyby\Rector\Class_\KdybyEventSubscriberToContributteEventSubscriberRector: null
Rector\NetteKdyby\Rector\MethodCall\ReplaceMagicPropertyEventWithEventClassRector: null
46 changes: 43 additions & 3 deletions docs/rector_rules_overview.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# All 488 Rectors Overview
# All 490 Rectors Overview

- [Projects](#projects)
- [General](#general)
Expand Down Expand Up @@ -26,7 +26,7 @@
- [MysqlToMysqli](#mysqltomysqli) (4)
- [Naming](#naming) (1)
- [Nette](#nette) (12)
- [NetteKdyby](#nettekdyby) (1)
- [NetteKdyby](#nettekdyby) (2)
- [NetteTesterToPHPUnit](#nettetestertophpunit) (3)
- [NetteToSymfony](#nettetosymfony) (9)
- [Order](#order) (3)
Expand All @@ -51,7 +51,7 @@
- [PhpDeglobalize](#phpdeglobalize) (1)
- [PhpSpecToPHPUnit](#phpspectophpunit) (7)
- [Polyfill](#polyfill) (2)
- [Privatization](#privatization) (5)
- [Privatization](#privatization) (6)
- [Refactoring](#refactoring) (2)
- [RemovingStatic](#removingstatic) (4)
- [Renaming](#renaming) (10)
Expand Down Expand Up @@ -4626,6 +4626,29 @@ Change EventSubscriber from Kdyby to Contributte

<br>

### `ReplaceMagicPropertyEventWithEventClassRector`

- class: [`Rector\NetteKdyby\Rector\MethodCall\ReplaceMagicPropertyEventWithEventClassRector`](/../master/rules/nette-kdyby/src/Rector/MethodCall/ReplaceMagicPropertyEventWithEventClassRector.php)
- [test fixtures](/../master/rules/nette-kdyby/tests/Rector/MethodCall/ReplaceMagicPropertyEventWithEventClassRector/Fixture)

Change $onProperty magic call with event disptacher and class dispatch

```diff
final class FileManager
{
- public $onUpload;
-
public function run(User $user)
{
- $this->onUpload($user);
+ $onFileManagerUploadEvent = new FileManagerUploadEvent($user);
+ $this->eventDispatcher->dispatch($onFileManagerUploadEvent);
}
}
```

<br>

## NetteTesterToPHPUnit

### `NetteAssertToPHPUnitAssertRector`
Expand Down Expand Up @@ -8322,6 +8345,23 @@ Change local property used in single method to local variable

<br>

### `PrivatizeFinalClassPropertyRector`

- class: [`Rector\Privatization\Rector\Property\PrivatizeFinalClassPropertyRector`](/../master/rules/privatization/src/Rector/Property/PrivatizeFinalClassPropertyRector.php)
- [test fixtures](/../master/rules/privatization/tests/Rector/Property/PrivatizeFinalClassPropertyRector/Fixture)

Change property to private if possible

```diff
final class SomeClass
{
- protected $value;
+ private $value;
}
```

<br>

### `PrivatizeLocalClassConstantRector`

- class: [`Rector\Privatization\Rector\ClassConst\PrivatizeLocalClassConstantRector`](/../master/rules/privatization/src/Rector/ClassConst/PrivatizeLocalClassConstantRector.php)
Expand Down
57 changes: 57 additions & 0 deletions rules/nette-kdyby/src/Naming/EventClassNaming.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?php

declare(strict_types=1);

namespace Rector\NetteKdyby\Naming;

use Nette\Utils\Strings;
use PhpParser\Node\Expr\MethodCall;
use Rector\CodingStyle\Naming\ClassNaming;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Symplify\SmartFileSystem\SmartFileInfo;

final class EventClassNaming
{
/**
* @var NodeNameResolver
*/
private $nodeNameResolver;

/**
* @var ClassNaming
*/
private $classNaming;

public function __construct(NodeNameResolver $nodeNameResolver, ClassNaming $classNaming)
{
$this->nodeNameResolver = $nodeNameResolver;
$this->classNaming = $classNaming;
}

public function getShortEventClassName(MethodCall $methodCall): string
{
/** @var string $methodName */
$methodName = $this->nodeNameResolver->getName($methodCall->name);

/** @var string $className */
$className = $methodCall->getAttribute(AttributeKey::CLASS_NAME);

$shortClassName = $this->classNaming->getShortName($className);

// "onMagic" => "Magic"
$shortPropertyName = Strings::substring($methodName, strlen('on'));

return $shortClassName . $shortPropertyName . 'Event';
}

public function resolveEventFileLocation(MethodCall $methodCall): string
{
$shortEventClassName = $this->getShortEventClassName($methodCall);

/** @var SmartFileInfo $fileInfo */
$fileInfo = $methodCall->getAttribute(AttributeKey::FILE_INFO);

return $fileInfo->getPath() . DIRECTORY_SEPARATOR . 'Event' . DIRECTORY_SEPARATOR . $shortEventClassName . '.php';
}
}
139 changes: 139 additions & 0 deletions rules/nette-kdyby/src/NodeFactory/CustomEventFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
<?php

declare(strict_types=1);

namespace Rector\NetteKdyby\NodeFactory;

use Nette\Utils\Strings;
use PhpParser\Builder\Class_;
use PhpParser\Builder\Method;
use PhpParser\Builder\Namespace_ as NamespaceBuilder;
use PhpParser\Builder\Property as PropertyBuilder;
use PhpParser\Node\Arg;
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\PropertyFetch;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Name\FullyQualified;
use PhpParser\Node\Param;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Namespace_;
use PhpParser\Node\Stmt\Property;
use PhpParser\Node\Stmt\Return_;
use Rector\CodingStyle\Naming\ClassNaming;
use Rector\Core\Exception\NotImplementedException;
use Rector\NodeNameResolver\NodeNameResolver;

final class CustomEventFactory
{
/**
* @var ClassNaming
*/
private $classNaming;

/**
* @var NodeNameResolver
*/
private $nodeNameResolver;

public function __construct(ClassNaming $classNaming, NodeNameResolver $nodeNameResolver)
{
$this->classNaming = $classNaming;
$this->nodeNameResolver = $nodeNameResolver;
}

/**
* @param Arg[] $args
*/
public function create(string $className, array $args): Namespace_
{
$namespace = Strings::before($className, '\\', -1);
$namespaceBuilder = new NamespaceBuilder($namespace);

$shortClassName = $this->classNaming->getShortName($className);
$classBuilder = new Class_($shortClassName);
$classBuilder->makeFinal();
$classBuilder->extend(new FullyQualified('Symfony\Contracts\EventDispatcher\Event'));

// 1. add __construct if args?
// 2. add getters
// 3. add property

if (count($args) > 0) {
$methodBuilder = $this->createConstructClassMethod($args);
$classBuilder->addStmt($methodBuilder);

// add properties
foreach ($args as $arg) {
$property = $this->createProperty($arg);
$classBuilder->addStmt($property);
}

// add getters
foreach ($args as $arg) {
$getterClassMethod = $this->createGetterClassMethod($arg);
$classBuilder->addStmt($getterClassMethod);
}
}

$class = $classBuilder->getNode();
$namespaceBuilder->addStmt($class);

return $namespaceBuilder->getNode();
}

/**
* @param Arg[] $args
*/
private function createConstructClassMethod(array $args): ClassMethod
{
$methodBuilder = new Method('__construct');
$methodBuilder->makePublic();

foreach ($args as $arg) {
$paramName = $this->nodeNameResolver->getName($arg->value);
if ($paramName === null) {
// @todo
throw new NotImplementedException();
}

$param = new Param(new Variable($paramName));
$methodBuilder->addParam($param);

$assign = new Assign(new PropertyFetch(new Variable('this'), $paramName), new Variable($paramName));
$methodBuilder->addStmt($assign);
}

return $methodBuilder->getNode();
}

private function createProperty(Arg $arg): Property
{
$paramName = $this->nodeNameResolver->getName($arg->value);
if ($paramName === null) {
// @todo
throw new NotImplementedException();
}

$propertyBuilder = new PropertyBuilder($paramName);
$propertyBuilder->makePrivate();

return $propertyBuilder->getNode();
}

private function createGetterClassMethod(Arg $arg): ClassMethod
{
$paramName = $this->nodeNameResolver->getName($arg->value);
if ($paramName === null) {
// @todo
throw new NotImplementedException();
}

$methodBuilder = new Method($paramName);

$return = new Return_(new PropertyFetch(new Variable('this'), $paramName));
$methodBuilder->addStmt($return);
$methodBuilder->makePublic();

return $methodBuilder->getNode();
}
}
Loading