[NetteToSymfony] Decouple to own package (#6360)

This commit is contained in:
Tomas Votruba 2021-05-05 23:15:26 +02:00 committed by GitHub
parent 147973bcb2
commit 29e3bc9372
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
95 changed files with 38 additions and 6255 deletions

View File

@ -44,6 +44,7 @@
"rector/rector-installer": "^0.10.1",
"rector/rector-laravel": "^0.10.2",
"rector/rector-nette": "^0.10.9",
"rector/rector-nette-to-symfony": "^0.10.0",
"rector/rector-phpunit": "^0.10.8",
"rector/rector-symfony": "^0.10.5",
"sebastian/diff": "^4.0.4",

View File

@ -1,11 +0,0 @@
<?php
declare(strict_types=1);
use Rector\NetteToSymfony\Rector\Class_\NetteControlToSymfonyControllerRector;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
return static function (ContainerConfigurator $containerConfigurator): void {
$services = $containerConfigurator->services();
$services->set(NetteControlToSymfonyControllerRector::class);
};

View File

@ -1,11 +0,0 @@
<?php
declare(strict_types=1);
use Rector\NetteToSymfony\Rector\MethodCall\NetteFormToSymfonyFormRector;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
return static function (ContainerConfigurator $containerConfigurator): void {
$services = $containerConfigurator->services();
$services->set(NetteFormToSymfonyFormRector::class);
};

View File

@ -1,15 +0,0 @@
<?php
declare(strict_types=1);
use Rector\NetteTesterToPHPUnit\Rector\Class_\NetteTesterClassToPHPUnitClassRector;
use Rector\NetteTesterToPHPUnit\Rector\Class_\RenameTesterTestToPHPUnitToTestFileRector;
use Rector\NetteTesterToPHPUnit\Rector\StaticCall\NetteAssertToPHPUnitAssertRector;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
return static function (ContainerConfigurator $containerConfigurator): void {
$services = $containerConfigurator->services();
$services->set(NetteTesterClassToPHPUnitClassRector::class);
$services->set(NetteAssertToPHPUnitAssertRector::class);
$services->set(RenameTesterTestToPHPUnitToTestFileRector::class);
};

View File

@ -1,16 +0,0 @@
<?php
declare(strict_types=1);
use Rector\Renaming\Rector\Name\RenameClassRector;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
return static function (ContainerConfigurator $containerConfigurator): void {
$services = $containerConfigurator->services();
$services->set(RenameClassRector::class)
->call('configure', [[
RenameClassRector::OLD_TO_NEW_CLASSES => [
'Doctrine\Common\DataFixtures\AbstractFixture' => 'Doctrine\Bundle\FixturesBundle\Fixture',
],
]]);
};

View File

@ -1,481 +0,0 @@
<?php
declare(strict_types=1);
use PHPStan\Type\ObjectType;
use Rector\NetteToSymfony\Rector\Class_\FormControlToControllerAndFormTypeRector;
use Rector\NetteToSymfony\Rector\ClassMethod\RouterListToControllerAnnotationsRector;
use Rector\NetteToSymfony\Rector\Interface_\DeleteFactoryInterfaceRector;
use Rector\NetteToSymfony\Rector\MethodCall\FromHttpRequestGetHeaderToHeadersGetRector;
use Rector\NetteToSymfony\Rector\MethodCall\FromRequestGetParameterToAttributesGetRector;
use Rector\Removing\Rector\Class_\RemoveInterfacesRector;
use Rector\Renaming\Rector\ClassConstFetch\RenameClassConstFetchRector;
use Rector\Renaming\Rector\MethodCall\RenameMethodRector;
use Rector\Renaming\Rector\Name\RenameClassRector;
use Rector\Renaming\ValueObject\MethodCallRename;
use Rector\Renaming\ValueObject\RenameClassAndConstFetch;
use Rector\TypeDeclaration\Rector\ClassMethod\AddReturnTypeDeclarationRector;
use Rector\TypeDeclaration\ValueObject\AddReturnTypeDeclaration;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
use Symplify\SymfonyPhpConfig\ValueObjectInliner;
return static function (ContainerConfigurator $containerConfigurator): void {
$containerConfigurator->import(__DIR__ . '/nette-to-symfony-doctrine.php');
$containerConfigurator->import(__DIR__ . '/nette-control-to-symfony-controller.php');
$containerConfigurator->import(__DIR__ . '/nette-tester-to-phpunit.php');
$containerConfigurator->import(__DIR__ . '/kdyby-to-symfony.php');
$services = $containerConfigurator->services();
$services->set(DeleteFactoryInterfaceRector::class);
$services->set(FromHttpRequestGetHeaderToHeadersGetRector::class);
$services->set(FromRequestGetParameterToAttributesGetRector::class);
$services->set(RouterListToControllerAnnotationsRector::class);
$services->set(AddReturnTypeDeclarationRector::class)
->call('configure', [[
AddReturnTypeDeclarationRector::METHOD_RETURN_TYPES => ValueObjectInliner::inline([
new AddReturnTypeDeclaration(
'Nette\Application\IPresenter',
'run',
new ObjectType('Symfony\Component\HttpFoundation\Response')
),
]),
]]);
$services->set(RenameClassRector::class)
->call('configure', [[
RenameClassRector::OLD_TO_NEW_CLASSES => [
'Nette\Application\Request' => 'Symfony\Component\HttpFoundation\Request',
'Nette\Http\Request' => 'Symfony\Component\HttpFoundation\Request',
'Nette\Http\IRequest' => 'Symfony\Component\HttpFoundation\Request',
'Nette\Application\UI\Presenter' => 'Symfony\Bundle\FrameworkBundle\Controller\AbstractController',
'Nette\Application\IResponse' => 'Symfony\Component\HttpFoundation\Response',
],
]]);
$services->set(RenameMethodRector::class)
->call('configure', [[
RenameMethodRector::METHOD_CALL_RENAMES => ValueObjectInliner::inline([
new MethodCallRename('Nette\Application\IPresenter', 'run', '__invoke'),
new MethodCallRename('Nette\DI\Container', 'getByType', 'get'),
new MethodCallRename('Nette\Configurator', 'addConfig', 'load'),
new MethodCallRename('Symfony\Component\Config\Loader\LoaderInterface', 'addConfig', 'load'),
]),
]]);
$services->set(RemoveInterfacesRector::class)
->call('configure', [[
RemoveInterfacesRector::INTERFACES_TO_REMOVE => ['Nette\Application\IPresenter'],
]]);
$services->set(RenameClassConstFetchRector::class)
->call('configure', [[
RenameClassConstFetchRector::CLASS_CONSTANT_RENAME => ValueObjectInliner::inline([
new RenameClassAndConstFetch(
'Nette\Http\*Response',
'S100_CONTINUE',
'Symfony\Component\HttpFoundation\Response',
'HTTP_CONTINUE'
),
new RenameClassAndConstFetch(
'Nette\Http\*Response',
'S101_SWITCHING_PROTOCOLS',
'Symfony\Component\HttpFoundation\Response',
'HTTP_SWITCHING_PROTOCOLS'
),
new RenameClassAndConstFetch(
'Nette\Http\*Response',
'S102_PROCESSING',
'Symfony\Component\HttpFoundation\Response',
'HTTP_PROCESSING'
),
new RenameClassAndConstFetch(
'Nette\Http\*Response',
'S200_OK',
'Symfony\Component\HttpFoundation\Response',
'HTTP_OK'
),
new RenameClassAndConstFetch(
'Nette\Http\*Response',
'S201_CREATED',
'Symfony\Component\HttpFoundation\Response',
'HTTP_CREATED'
),
new RenameClassAndConstFetch(
'Nette\Http\*Response',
'S202_ACCEPTED',
'Symfony\Component\HttpFoundation\Response',
'HTTP_ACCEPTED'
),
new RenameClassAndConstFetch(
'Nette\Http\*Response',
'S203_NON_AUTHORITATIVE_INFORMATION',
'Symfony\Component\HttpFoundation\Response',
'HTTP_NON_AUTHORITATIVE_INFORMATION'
),
new RenameClassAndConstFetch(
'Nette\Http\*Response',
'S204_NO_CONTENT',
'Symfony\Component\HttpFoundation\Response',
'HTTP_NO_CONTENT'
),
new RenameClassAndConstFetch(
'Nette\Http\*Response',
'S205_RESET_CONTENT',
'Symfony\Component\HttpFoundation\Response',
'HTTP_RESET_CONTENT'
),
new RenameClassAndConstFetch(
'Nette\Http\*Response',
'S206_PARTIAL_CONTENT',
'Symfony\Component\HttpFoundation\Response',
'HTTP_PARTIAL_CONTENT'
),
new RenameClassAndConstFetch(
'Nette\Http\*Response',
'S207_MULTI_STATUS',
'Symfony\Component\HttpFoundation\Response',
'HTTP_MULTI_STATUS'
),
new RenameClassAndConstFetch(
'Nette\Http\*Response',
'S208_ALREADY_REPORTED',
'Symfony\Component\HttpFoundation\Response',
'HTTP_ALREADY_REPORTED'
),
new RenameClassAndConstFetch(
'Nette\Http\*Response',
'S226_IM_USED',
'Symfony\Component\HttpFoundation\Response',
'HTTP_IM_USED'
),
new RenameClassAndConstFetch(
'Nette\Http\*Response',
'S300_MULTIPLE_CHOICES',
'Symfony\Component\HttpFoundation\Response',
'HTTP_MULTIPLE_CHOICES'
),
new RenameClassAndConstFetch(
'Nette\Http\*Response',
'S301_MOVED_PERMANENTLY',
'Symfony\Component\HttpFoundation\Response',
'HTTP_MOVED_PERMANENTLY'
),
new RenameClassAndConstFetch(
'Nette\Http\*Response',
'S302_FOUND',
'Symfony\Component\HttpFoundation\Response',
'HTTP_FOUND'
),
new RenameClassAndConstFetch(
'Nette\Http\*Response',
'S303_SEE_OTHER',
'Symfony\Component\HttpFoundation\Response',
'HTTP_SEE_OTHER'
),
new RenameClassAndConstFetch(
'Nette\Http\*Response',
'S303_POST_GET',
'Symfony\Component\HttpFoundation\Response',
'HTTP_SEE_OTHER'
),
new RenameClassAndConstFetch(
'Nette\Http\*Response',
'S304_NOT_MODIFIED',
'Symfony\Component\HttpFoundation\Response',
'HTTP_NOT_MODIFIED'
),
new RenameClassAndConstFetch(
'Nette\Http\*Response',
'S305_USE_PROXY',
'Symfony\Component\HttpFoundation\Response',
'HTTP_USE_PROXY'
),
new RenameClassAndConstFetch(
'Nette\Http\*Response',
'S307_TEMPORARY_REDIRECT',
'Symfony\Component\HttpFoundation\Response',
'HTTP_TEMPORARY_REDIRECT'
),
new RenameClassAndConstFetch(
'Nette\Http\*Response',
'S308_PERMANENT_REDIRECT',
'Symfony\Component\HttpFoundation\Response',
'HTTP_PERMANENTLY_REDIRECT'
),
new RenameClassAndConstFetch(
'Nette\Http\*Response',
'S400_BAD_REQUEST',
'Symfony\Component\HttpFoundation\Response',
'HTTP_BAD_REQUEST'
),
new RenameClassAndConstFetch(
'Nette\Http\*Response',
'S401_UNAUTHORIZED',
'Symfony\Component\HttpFoundation\Response',
'HTTP_UNAUTHORIZED'
),
new RenameClassAndConstFetch(
'Nette\Http\*Response',
'S402_PAYMENT_REQUIRED',
'Symfony\Component\HttpFoundation\Response',
'HTTP_PAYMENT_REQUIRED'
),
new RenameClassAndConstFetch(
'Nette\Http\*Response',
'S403_FORBIDDEN',
'Symfony\Component\HttpFoundation\Response',
'HTTP_FORBIDDEN'
),
new RenameClassAndConstFetch(
'Nette\Http\*Response',
'S404_NOT_FOUND',
'Symfony\Component\HttpFoundation\Response',
'HTTP_NOT_FOUND'
),
new RenameClassAndConstFetch(
'Nette\Http\*Response',
'S405_METHOD_NOT_ALLOWED',
'Symfony\Component\HttpFoundation\Response',
'HTTP_METHOD_NOT_ALLOWED'
),
new RenameClassAndConstFetch(
'Nette\Http\*Response',
'S406_NOT_ACCEPTABLE',
'Symfony\Component\HttpFoundation\Response',
'HTTP_NOT_ACCEPTABLE'
),
new RenameClassAndConstFetch(
'Nette\Http\*Response',
'S407_PROXY_AUTHENTICATION_REQUIRED',
'Symfony\Component\HttpFoundation\Response',
'HTTP_PROXY_AUTHENTICATION_REQUIRED'
),
new RenameClassAndConstFetch(
'Nette\Http\*Response',
'S408_REQUEST_TIMEOUT',
'Symfony\Component\HttpFoundation\Response',
'HTTP_REQUEST_TIMEOUT'
),
new RenameClassAndConstFetch(
'Nette\Http\*Response',
'S409_CONFLICT',
'Symfony\Component\HttpFoundation\Response',
'HTTP_CONFLICT'
),
new RenameClassAndConstFetch(
'Nette\Http\*Response',
'S410_GONE',
'Symfony\Component\HttpFoundation\Response',
'HTTP_GONE'
),
new RenameClassAndConstFetch(
'Nette\Http\*Response',
'S411_LENGTH_REQUIRED',
'Symfony\Component\HttpFoundation\Response',
'HTTP_LENGTH_REQUIRED'
),
new RenameClassAndConstFetch(
'Nette\Http\*Response',
'S412_PRECONDITION_FAILED',
'Symfony\Component\HttpFoundation\Response',
'HTTP_PRECONDITION_FAILED'
),
new RenameClassAndConstFetch(
'Nette\Http\*Response',
'S413_REQUEST_ENTITY_TOO_LARGE',
'Symfony\Component\HttpFoundation\Response',
'HTTP_REQUEST_ENTITY_TOO_LARGE'
),
new RenameClassAndConstFetch(
'Nette\Http\*Response',
'S414_REQUEST_URI_TOO_LONG',
'Symfony\Component\HttpFoundation\Response',
'HTTP_REQUEST_URI_TOO_LONG'
),
new RenameClassAndConstFetch(
'Nette\Http\*Response',
'S415_UNSUPPORTED_MEDIA_TYPE',
'Symfony\Component\HttpFoundation\Response',
'HTTP_UNSUPPORTED_MEDIA_TYPE'
),
new RenameClassAndConstFetch(
'Nette\Http\*Response',
'S416_REQUESTED_RANGE_NOT_SATISFIABLE',
'Symfony\Component\HttpFoundation\Response',
'HTTP_REQUESTED_RANGE_NOT_SATISFIABLE'
),
new RenameClassAndConstFetch(
'Nette\Http\*Response',
'S417_EXPECTATION_FAILED',
'Symfony\Component\HttpFoundation\Response',
'HTTP_EXPECTATION_FAILED'
),
new RenameClassAndConstFetch(
'Nette\Http\*Response',
'S421_MISDIRECTED_REQUEST',
'Symfony\Component\HttpFoundation\Response',
'HTTP_MISDIRECTED_REQUEST'
),
new RenameClassAndConstFetch(
'Nette\Http\*Response',
'S422_UNPROCESSABLE_ENTITY',
'Symfony\Component\HttpFoundation\Response',
'HTTP_UNPROCESSABLE_ENTITY'
),
new RenameClassAndConstFetch(
'Nette\Http\*Response',
'S423_LOCKED',
'Symfony\Component\HttpFoundation\Response',
'HTTP_LOCKED'
),
new RenameClassAndConstFetch(
'Nette\Http\*Response',
'S424_FAILED_DEPENDENCY',
'Symfony\Component\HttpFoundation\Response',
'HTTP_FAILED_DEPENDENCY'
),
new RenameClassAndConstFetch(
'Nette\Http\*Response',
'S426_UPGRADE_REQUIRED',
'Symfony\Component\HttpFoundation\Response',
'HTTP_UPGRADE_REQUIRED'
),
new RenameClassAndConstFetch(
'Nette\Http\*Response',
'S428_PRECONDITION_REQUIRED',
'Symfony\Component\HttpFoundation\Response',
'HTTP_PRECONDITION_REQUIRED'
),
new RenameClassAndConstFetch(
'Nette\Http\*Response',
'S429_TOO_MANY_REQUESTS',
'Symfony\Component\HttpFoundation\Response',
'HTTP_TOO_MANY_REQUESTS'
),
new RenameClassAndConstFetch(
'Nette\Http\*Response',
'S431_REQUEST_HEADER_FIELDS_TOO_LARGE',
'Symfony\Component\HttpFoundation\Response',
'HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE'
),
new RenameClassAndConstFetch(
'Nette\Http\*Response',
'S451_UNAVAILABLE_FOR_LEGAL_REASONS',
'Symfony\Component\HttpFoundation\Response',
'HTTP_UNAVAILABLE_FOR_LEGAL_REASONS'
),
new RenameClassAndConstFetch(
'Nette\Http\*Response',
'S500_INTERNAL_SERVER_ERROR',
'Symfony\Component\HttpFoundation\Response',
'HTTP_INTERNAL_SERVER_ERROR'
),
new RenameClassAndConstFetch(
'Nette\Http\*Response',
'S501_NOT_IMPLEMENTED',
'Symfony\Component\HttpFoundation\Response',
'HTTP_NOT_IMPLEMENTED'
),
new RenameClassAndConstFetch(
'Nette\Http\*Response',
'S502_BAD_GATEWAY',
'Symfony\Component\HttpFoundation\Response',
'HTTP_BAD_GATEWAY'
),
new RenameClassAndConstFetch(
'Nette\Http\*Response',
'S503_SERVICE_UNAVAILABLE',
'Symfony\Component\HttpFoundation\Response',
'HTTP_SERVICE_UNAVAILABLE'
),
new RenameClassAndConstFetch(
'Nette\Http\*Response',
'S504_GATEWAY_TIMEOUT',
'Symfony\Component\HttpFoundation\Response',
'HTTP_GATEWAY_TIMEOUT'
),
new RenameClassAndConstFetch(
'Nette\Http\*Response',
'S505_HTTP_VERSION_NOT_SUPPORTED',
'Symfony\Component\HttpFoundation\Response',
'HTTP_VERSION_NOT_SUPPORTED'
),
new RenameClassAndConstFetch(
'Nette\Http\*Response',
'S506_VARIANT_ALSO_NEGOTIATES',
'Symfony\Component\HttpFoundation\Response',
'HTTP_VARIANT_ALSO_NEGOTIATES_EXPERIMENTAL'
),
new RenameClassAndConstFetch(
'Nette\Http\*Response',
'S507_INSUFFICIENT_STORAGE',
'Symfony\Component\HttpFoundation\Response',
'HTTP_INSUFFICIENT_STORAGE'
),
new RenameClassAndConstFetch(
'Nette\Http\*Response',
'S508_LOOP_DETECTED',
'Symfony\Component\HttpFoundation\Response',
'HTTP_LOOP_DETECTED'
),
new RenameClassAndConstFetch(
'Nette\Http\*Response',
'S510_NOT_EXTENDED',
'Symfony\Component\HttpFoundation\Response',
'HTTP_NOT_EXTENDED'
),
new RenameClassAndConstFetch(
'Nette\Http\*Response',
'S511_NETWORK_AUTHENTICATION_REQUIRED',
'Symfony\Component\HttpFoundation\Response',
'HTTP_NETWORK_AUTHENTICATION_REQUIRED'
),
new RenameClassAndConstFetch(
'Nette\Http\*Request',
'GET',
'Symfony\Component\HttpFoundation\Request',
'METHOD_GET'
),
new RenameClassAndConstFetch(
'Nette\Http\*Request',
'POST',
'Symfony\Component\HttpFoundation\Request',
'METHOD_POST'
),
new RenameClassAndConstFetch(
'Nette\Http\*Request',
'HEAD',
'Symfony\Component\HttpFoundation\Request',
'METHOD_HEAD'
),
new RenameClassAndConstFetch(
'Nette\Http\*Request',
'PUT',
'Symfony\Component\HttpFoundation\Request',
'METHOD_PUT'
),
new RenameClassAndConstFetch(
'Nette\Http\*Request',
'DELETE',
'Symfony\Component\HttpFoundation\Request',
'METHOD_DELETE'
),
new RenameClassAndConstFetch(
'Nette\Http\*Request',
'PATCH',
'Symfony\Component\HttpFoundation\Request',
'METHOD_PATCH'
),
new RenameClassAndConstFetch(
'Nette\Http\*Request',
'OPTIONS',
'Symfony\Component\HttpFoundation\Request',
'METHOD_OPTIONS'
),
]),
]]);
$services->set(FormControlToControllerAndFormTypeRector::class);
};

View File

@ -370,26 +370,6 @@ final class SetList implements SetListInterface
*/
public const NETTE_UTILS_CODE_QUALITY = NetteSetList::NETTE_UTILS_CODE_QUALITY;
/**
* @var string
*/
public const NETTE_CONTROL_TO_SYMFONY_CONTROLLER = __DIR__ . '/../../../config/set/nette-control-to-symfony-controller.php';
/**
* @var string
*/
public const NETTE_FORMS_TO_SYMFONY = __DIR__ . '/../../../config/set/nette-forms-to-symfony.php';
/**
* @var string
*/
public const NETTE_TESTER_TO_PHPUNIT = __DIR__ . '/../../../config/set/nette-tester-to-phpunit.php';
/**
* @var string
*/
public const NETTE_TO_SYMFONY = __DIR__ . '/../../../config/set/nette-to-symfony.php';
/**
* @var string
*/

View File

@ -1,25 +0,0 @@
<?php
namespace Rector\Tests\NetteTesterToPHPUnit\Rector\Class_\NetteTesterClassToPHPUnitClassRector\Fixture;
use Tester\Assert;
function someStaticFunctions()
{
Assert::true(10 == 5);
}
?>
-----
<?php
namespace Rector\Tests\NetteTesterToPHPUnit\Rector\Class_\NetteTesterClassToPHPUnitClassRector\Fixture;
use Tester\Assert;
function someStaticFunctions()
{
\PHPUnit\Framework\Assert::assertTrue(10 == 5);
}
?>

View File

@ -1,61 +0,0 @@
<?php
namespace Rector\Tests\NetteTesterToPHPUnit\Rector\Class_\NetteTesterClassToPHPUnitClassRector\Fixture;
use Tester\Assert;
use Tester\TestCase;
class AssertTypeTest extends TestCase
{
public function testFunctionality()
{
$value = 'SomeValue';
Assert::type('list', $value);
Assert::type('array', $value);
Assert::type('bool', $value);
Assert::type('callable', $value);
Assert::type('float', $value);
Assert::type('int', $value);
Assert::type('integer', $value);
Assert::type('null', $value);
Assert::type('object', $value);
Assert::type('resource', $value);
Assert::type('scalar', $value);
Assert::type('string', $value);
Assert::type(\stdClass::class, $value);
}
}
?>
-----
<?php
namespace Rector\Tests\NetteTesterToPHPUnit\Rector\Class_\NetteTesterClassToPHPUnitClassRector\Fixture;
use Tester\Assert;
use Tester\TestCase;
class AssertTypeTest extends \PHPUnit\Framework\TestCase
{
public function testFunctionality()
{
$value = 'SomeValue';
$this->assertIsArray($value);
$this->assertIsArray($value);
$this->assertIsBool($value);
$this->assertIsCallable($value);
$this->assertIsFloat($value);
$this->assertIsInt($value);
$this->assertIsInt($value);
$this->assertNull($value);
$this->assertIsObject($value);
$this->assertIsResource($value);
$this->assertIsScalar($value);
$this->assertIsString($value);
$this->assertInstanceOf(\stdClass::class, $value);
}
}
?>

View File

@ -1,107 +0,0 @@
<?php
namespace Rector\Tests\NetteTesterToPHPUnit\Rector\Class_\NetteTesterClassToPHPUnitClassRector\Fixture;
use Tester\Assert;
use Tester\TestCase;
class DataProviderTest extends TestCase
{
/**
* @dataProvider dataMySqlExceptions
*
* @param \Exception $exception
* @param string $class
* @param array $props
*/
public function testDriverExceptions_MySQL($exception, $class, array $props)
{
$conn = new ConnectionMock([], new MysqlDriverMock());
$conn->setDatabasePlatform(new Doctrine\DBAL\Platforms\MySqlPlatform());
$conn->throwOldKdybyExceptions = TRUE;
$resolved = $conn->resolveException($exception);
Assert::true($resolved instanceof $class);
foreach ($props as $prop => $val) {
Assert::same($val, $resolved->{$prop});
}
}
/**
* @return array
*/
public function dataMySqlExceptions()
{
$e = new \PDOException('SQLSTATE[23000]: Integrity constraint violation: 1048 Column \'name\' cannot be null', '23000');
$e->errorInfo = ['23000', 1048, 'Column \'name\' cannot be null'];
$emptyPdo = new PDOException($e);
$driver = new MysqlDriverMock();
$empty = Doctrine\DBAL\DBALException::driverExceptionDuringQuery(
$driver, $emptyPdo, "INSERT INTO `test_empty` (`name`) VALUES (NULL)", []
);
$e = new \PDOException('SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry \'filip-prochazka\' for key \'uniq_name_surname\'', '23000');
$e->errorInfo = ['23000', 1062, 'Duplicate entry \'filip-prochazka\' for key \'uniq_name_surname\''];
$uniquePdo = new PDOException($e);
$unique = Doctrine\DBAL\DBALException::driverExceptionDuringQuery(
$driver, $uniquePdo, "INSERT INTO `test_empty` (`name`, `surname`) VALUES ('filip', 'prochazka')", []
);
return [
[$empty, \Kdyby\Doctrine\EmptyValueException::class, ['column' => 'name']],
[$unique, \Kdyby\Doctrine\DuplicateEntryException::class, ['columns' => ['uniq_name_surname' => ['name', 'surname']]]],
];
}
}
?>
-----
<?php
namespace Rector\Tests\NetteTesterToPHPUnit\Rector\Class_\NetteTesterClassToPHPUnitClassRector\Fixture;
use Tester\Assert;
use Tester\TestCase;
class DataProviderTest extends \PHPUnit\Framework\TestCase
{
/**
* @dataProvider dataMySqlExceptions
*
* @param \Exception $exception
* @param string $class
* @param array $props
*/
public function testDriverExceptions_MySQL($exception, $class, array $props)
{
$conn = new ConnectionMock([], new MysqlDriverMock());
$conn->setDatabasePlatform(new Doctrine\DBAL\Platforms\MySqlPlatform());
$conn->throwOldKdybyExceptions = TRUE;
$resolved = $conn->resolveException($exception);
$this->assertTrue($resolved instanceof $class);
foreach ($props as $prop => $val) {
$this->assertSame($val, $resolved->{$prop});
}
}
/**
* @return array
*/
public function dataMySqlExceptions()
{
$e = new \PDOException('SQLSTATE[23000]: Integrity constraint violation: 1048 Column \'name\' cannot be null', '23000');
$e->errorInfo = ['23000', 1048, 'Column \'name\' cannot be null'];
$emptyPdo = new PDOException($e);
$driver = new MysqlDriverMock();
$empty = Doctrine\DBAL\DBALException::driverExceptionDuringQuery(
$driver, $emptyPdo, "INSERT INTO `test_empty` (`name`) VALUES (NULL)", []
);
$e = new \PDOException('SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry \'filip-prochazka\' for key \'uniq_name_surname\'', '23000');
$e->errorInfo = ['23000', 1062, 'Duplicate entry \'filip-prochazka\' for key \'uniq_name_surname\''];
$uniquePdo = new PDOException($e);
$unique = Doctrine\DBAL\DBALException::driverExceptionDuringQuery(
$driver, $uniquePdo, "INSERT INTO `test_empty` (`name`, `surname`) VALUES ('filip', 'prochazka')", []
);
return [
[$empty, \Kdyby\Doctrine\EmptyValueException::class, ['column' => 'name']],
[$unique, \Kdyby\Doctrine\DuplicateEntryException::class, ['columns' => ['uniq_name_surname' => ['name', 'surname']]]],
];
}
}
?>

View File

@ -1,337 +0,0 @@
<?php
namespace Rector\Tests\NetteTesterToPHPUnit\Rector\Class_\NetteTesterClassToPHPUnitClassRector\Fixture;
use Rector\Tests\NetteTesterToPHPUnit\Rector\Class_\NetteTesterClassToPHPUnitClassRector\Source\ORMTestCase;
use Tester\Assert;
class EventsCompatibilityTest extends ORMTestCase
{
/**
* @var Kdyby\Doctrine\EntityManager
*/
private $em;
protected function setUp()
{
$this->em = $this->createMemoryManagerWithSchema([
__DIR__ . '/config/events.neon',
]);
}
public function testOuterRegister_new()
{
Assert::type(\Kdyby\Events\NamespacedEventManager::class, $this->em->getEventManager());
$outerEvm = $this->em->getEventManager();
Assert::false($outerEvm->hasListeners(Doctrine\ORM\Events::onFlush));
Assert::false($outerEvm->hasListeners(Kdyby\Doctrine\Events::onFlush));
$outerEvm->addEventSubscriber($new = new NewListener());
Assert::true($outerEvm->hasListeners(Doctrine\ORM\Events::onFlush));
Assert::true($outerEvm->hasListeners(Kdyby\Doctrine\Events::onFlush));
$outerEvm->dispatchEvent(Doctrine\ORM\Events::onFlush, $args = new OnFlushEventArgs($this->em));
Assert::same([[$args]], $new->calls);
}
public function testOuterRegister_old()
{
Assert::type(\Kdyby\Events\NamespacedEventManager::class, $this->em->getEventManager());
$outerEvm = $this->em->getEventManager();
Assert::false($outerEvm->hasListeners(Doctrine\ORM\Events::onFlush));
Assert::false($outerEvm->hasListeners(Kdyby\Doctrine\Events::onFlush));
$outerEvm->addEventSubscriber($old = new OldListener());
Assert::true($outerEvm->hasListeners(Doctrine\ORM\Events::onFlush));
Assert::true($outerEvm->hasListeners(Kdyby\Doctrine\Events::onFlush));
$outerEvm->dispatchEvent(Doctrine\ORM\Events::onFlush, $args = new OnFlushEventArgs($this->em));
Assert::same([[$args]], $old->calls);
}
public function testOuterRegister_combined()
{
Assert::type(\Kdyby\Events\NamespacedEventManager::class, $this->em->getEventManager());
$outerEvm = $this->em->getEventManager();
Assert::false($outerEvm->hasListeners(Doctrine\ORM\Events::onFlush));
Assert::false($outerEvm->hasListeners(Kdyby\Doctrine\Events::onFlush));
$outerEvm->addEventSubscriber($old = new OldListener());
$outerEvm->addEventSubscriber($new = new NewListener());
Assert::true($outerEvm->hasListeners(Doctrine\ORM\Events::onFlush));
Assert::true($outerEvm->hasListeners(Kdyby\Doctrine\Events::onFlush));
$outerEvm->dispatchEvent(Doctrine\ORM\Events::onFlush, $args = new OnFlushEventArgs($this->em));
Assert::same([[$args]], $old->calls);
Assert::same([[$args]], $new->calls);
}
public function testInnerRegister_new()
{
Assert::type(\Kdyby\Events\NamespacedEventManager::class, $this->em->getEventManager());
/** @var Kdyby\Events\EventManager $innerEvm */
$innerEvm = $this->serviceLocator->getByType(\Kdyby\Events\EventManager::class);
Assert::false($innerEvm->hasListeners(Doctrine\ORM\Events::onFlush));
Assert::false($innerEvm->hasListeners(Kdyby\Doctrine\Events::onFlush));
$outerEvm = $this->em->getEventManager();
Assert::false($outerEvm->hasListeners(Doctrine\ORM\Events::onFlush));
Assert::false($outerEvm->hasListeners(Kdyby\Doctrine\Events::onFlush));
$innerEvm->addEventSubscriber($new = new NewListener());
Assert::false($innerEvm->hasListeners(Doctrine\ORM\Events::onFlush));
Assert::true($innerEvm->hasListeners(Kdyby\Doctrine\Events::onFlush));
Assert::true($outerEvm->hasListeners(Doctrine\ORM\Events::onFlush));
Assert::true($outerEvm->hasListeners(Kdyby\Doctrine\Events::onFlush));
$outerEvm->dispatchEvent(Doctrine\ORM\Events::onFlush, $args = new OnFlushEventArgs($this->em));
Assert::same([[$args]], $new->calls);
}
public function testInnerRegister_old()
{
Assert::type(\Kdyby\Events\NamespacedEventManager::class, $this->em->getEventManager());
/** @var Kdyby\Events\EventManager $innerEvm */
$innerEvm = $this->serviceLocator->getByType(\Kdyby\Events\EventManager::class);
Assert::false($innerEvm->hasListeners(Doctrine\ORM\Events::onFlush));
Assert::false($innerEvm->hasListeners(Kdyby\Doctrine\Events::onFlush));
$outerEvm = $this->em->getEventManager();
Assert::false($outerEvm->hasListeners(Doctrine\ORM\Events::onFlush));
Assert::false($outerEvm->hasListeners(Kdyby\Doctrine\Events::onFlush));
$innerEvm->addEventSubscriber($old = new OldListener());
Assert::true($innerEvm->hasListeners(Doctrine\ORM\Events::onFlush));
Assert::false($innerEvm->hasListeners(Kdyby\Doctrine\Events::onFlush));
Assert::true($outerEvm->hasListeners(Doctrine\ORM\Events::onFlush));
Assert::true($outerEvm->hasListeners(Kdyby\Doctrine\Events::onFlush));
$outerEvm->dispatchEvent(Doctrine\ORM\Events::onFlush, $args = new OnFlushEventArgs($this->em));
Assert::same([[$args]], $old->calls);
}
public function testInnerRegister_combined()
{
Assert::type(\Kdyby\Events\NamespacedEventManager::class, $this->em->getEventManager());
/** @var Kdyby\Events\EventManager $innerEvm */
$innerEvm = $this->serviceLocator->getByType(\Kdyby\Events\EventManager::class);
Assert::false($innerEvm->hasListeners(Doctrine\ORM\Events::onFlush));
Assert::false($innerEvm->hasListeners(Kdyby\Doctrine\Events::onFlush));
$outerEvm = $this->em->getEventManager();
Assert::false($outerEvm->hasListeners(Doctrine\ORM\Events::onFlush));
Assert::false($outerEvm->hasListeners(Kdyby\Doctrine\Events::onFlush));
$innerEvm->addEventSubscriber($old = new OldListener());
$innerEvm->addEventSubscriber($new = new NewListener());
Assert::true($innerEvm->hasListeners(Doctrine\ORM\Events::onFlush));
Assert::true($innerEvm->hasListeners(Kdyby\Doctrine\Events::onFlush));
Assert::true($outerEvm->hasListeners(Doctrine\ORM\Events::onFlush));
Assert::true($outerEvm->hasListeners(Kdyby\Doctrine\Events::onFlush));
$outerEvm->dispatchEvent(Doctrine\ORM\Events::onFlush, $args = new OnFlushEventArgs($this->em));
Assert::same([[$args]], $old->calls);
Assert::same([[$args]], $new->calls);
}
}
(new EventsCompatibilityTest())->run();
?>
-----
<?php
namespace Rector\Tests\NetteTesterToPHPUnit\Rector\Class_\NetteTesterClassToPHPUnitClassRector\Fixture;
use Rector\Tests\NetteTesterToPHPUnit\Rector\Class_\NetteTesterClassToPHPUnitClassRector\Source\ORMTestCase;
use Tester\Assert;
class EventsCompatibilityTest extends \PHPUnit\Framework\TestCase
{
/**
* @var Kdyby\Doctrine\EntityManager
*/
private $em;
protected function setUp()
{
$this->em = $this->createMemoryManagerWithSchema([
__DIR__ . '/config/events.neon',
]);
}
public function testOuterRegister_new()
{
$this->assertInstanceOf(\Kdyby\Events\NamespacedEventManager::class, $this->em->getEventManager());
$outerEvm = $this->em->getEventManager();
$this->assertFalse($outerEvm->hasListeners(Doctrine\ORM\Events::onFlush));
$this->assertFalse($outerEvm->hasListeners(Kdyby\Doctrine\Events::onFlush));
$outerEvm->addEventSubscriber($new = new NewListener());
$this->assertTrue($outerEvm->hasListeners(Doctrine\ORM\Events::onFlush));
$this->assertTrue($outerEvm->hasListeners(Kdyby\Doctrine\Events::onFlush));
$outerEvm->dispatchEvent(Doctrine\ORM\Events::onFlush, $args = new OnFlushEventArgs($this->em));
$this->assertSame([[$args]], $new->calls);
}
public function testOuterRegister_old()
{
$this->assertInstanceOf(\Kdyby\Events\NamespacedEventManager::class, $this->em->getEventManager());
$outerEvm = $this->em->getEventManager();
$this->assertFalse($outerEvm->hasListeners(Doctrine\ORM\Events::onFlush));
$this->assertFalse($outerEvm->hasListeners(Kdyby\Doctrine\Events::onFlush));
$outerEvm->addEventSubscriber($old = new OldListener());
$this->assertTrue($outerEvm->hasListeners(Doctrine\ORM\Events::onFlush));
$this->assertTrue($outerEvm->hasListeners(Kdyby\Doctrine\Events::onFlush));
$outerEvm->dispatchEvent(Doctrine\ORM\Events::onFlush, $args = new OnFlushEventArgs($this->em));
$this->assertSame([[$args]], $old->calls);
}
public function testOuterRegister_combined()
{
$this->assertInstanceOf(\Kdyby\Events\NamespacedEventManager::class, $this->em->getEventManager());
$outerEvm = $this->em->getEventManager();
$this->assertFalse($outerEvm->hasListeners(Doctrine\ORM\Events::onFlush));
$this->assertFalse($outerEvm->hasListeners(Kdyby\Doctrine\Events::onFlush));
$outerEvm->addEventSubscriber($old = new OldListener());
$outerEvm->addEventSubscriber($new = new NewListener());
$this->assertTrue($outerEvm->hasListeners(Doctrine\ORM\Events::onFlush));
$this->assertTrue($outerEvm->hasListeners(Kdyby\Doctrine\Events::onFlush));
$outerEvm->dispatchEvent(Doctrine\ORM\Events::onFlush, $args = new OnFlushEventArgs($this->em));
$this->assertSame([[$args]], $old->calls);
$this->assertSame([[$args]], $new->calls);
}
public function testInnerRegister_new()
{
$this->assertInstanceOf(\Kdyby\Events\NamespacedEventManager::class, $this->em->getEventManager());
/** @var Kdyby\Events\EventManager $innerEvm */
$innerEvm = $this->serviceLocator->getByType(\Kdyby\Events\EventManager::class);
$this->assertFalse($innerEvm->hasListeners(Doctrine\ORM\Events::onFlush));
$this->assertFalse($innerEvm->hasListeners(Kdyby\Doctrine\Events::onFlush));
$outerEvm = $this->em->getEventManager();
$this->assertFalse($outerEvm->hasListeners(Doctrine\ORM\Events::onFlush));
$this->assertFalse($outerEvm->hasListeners(Kdyby\Doctrine\Events::onFlush));
$innerEvm->addEventSubscriber($new = new NewListener());
$this->assertFalse($innerEvm->hasListeners(Doctrine\ORM\Events::onFlush));
$this->assertTrue($innerEvm->hasListeners(Kdyby\Doctrine\Events::onFlush));
$this->assertTrue($outerEvm->hasListeners(Doctrine\ORM\Events::onFlush));
$this->assertTrue($outerEvm->hasListeners(Kdyby\Doctrine\Events::onFlush));
$outerEvm->dispatchEvent(Doctrine\ORM\Events::onFlush, $args = new OnFlushEventArgs($this->em));
$this->assertSame([[$args]], $new->calls);
}
public function testInnerRegister_old()
{
$this->assertInstanceOf(\Kdyby\Events\NamespacedEventManager::class, $this->em->getEventManager());
/** @var Kdyby\Events\EventManager $innerEvm */
$innerEvm = $this->serviceLocator->getByType(\Kdyby\Events\EventManager::class);
$this->assertFalse($innerEvm->hasListeners(Doctrine\ORM\Events::onFlush));
$this->assertFalse($innerEvm->hasListeners(Kdyby\Doctrine\Events::onFlush));
$outerEvm = $this->em->getEventManager();
$this->assertFalse($outerEvm->hasListeners(Doctrine\ORM\Events::onFlush));
$this->assertFalse($outerEvm->hasListeners(Kdyby\Doctrine\Events::onFlush));
$innerEvm->addEventSubscriber($old = new OldListener());
$this->assertTrue($innerEvm->hasListeners(Doctrine\ORM\Events::onFlush));
$this->assertFalse($innerEvm->hasListeners(Kdyby\Doctrine\Events::onFlush));
$this->assertTrue($outerEvm->hasListeners(Doctrine\ORM\Events::onFlush));
$this->assertTrue($outerEvm->hasListeners(Kdyby\Doctrine\Events::onFlush));
$outerEvm->dispatchEvent(Doctrine\ORM\Events::onFlush, $args = new OnFlushEventArgs($this->em));
$this->assertSame([[$args]], $old->calls);
}
public function testInnerRegister_combined()
{
$this->assertInstanceOf(\Kdyby\Events\NamespacedEventManager::class, $this->em->getEventManager());
/** @var Kdyby\Events\EventManager $innerEvm */
$innerEvm = $this->serviceLocator->getByType(\Kdyby\Events\EventManager::class);
$this->assertFalse($innerEvm->hasListeners(Doctrine\ORM\Events::onFlush));
$this->assertFalse($innerEvm->hasListeners(Kdyby\Doctrine\Events::onFlush));
$outerEvm = $this->em->getEventManager();
$this->assertFalse($outerEvm->hasListeners(Doctrine\ORM\Events::onFlush));
$this->assertFalse($outerEvm->hasListeners(Kdyby\Doctrine\Events::onFlush));
$innerEvm->addEventSubscriber($old = new OldListener());
$innerEvm->addEventSubscriber($new = new NewListener());
$this->assertTrue($innerEvm->hasListeners(Doctrine\ORM\Events::onFlush));
$this->assertTrue($innerEvm->hasListeners(Kdyby\Doctrine\Events::onFlush));
$this->assertTrue($outerEvm->hasListeners(Doctrine\ORM\Events::onFlush));
$this->assertTrue($outerEvm->hasListeners(Kdyby\Doctrine\Events::onFlush));
$outerEvm->dispatchEvent(Doctrine\ORM\Events::onFlush, $args = new OnFlushEventArgs($this->em));
$this->assertSame([[$args]], $old->calls);
$this->assertSame([[$args]], $new->calls);
}
}
?>

View File

@ -1,61 +0,0 @@
<?php
namespace Rector\Tests\NetteTesterToPHPUnit\Rector\Class_\NetteTesterClassToPHPUnitClassRector\Fixture;
use Tester\Assert;
use Tester\TestCase;
class ExtensionTest extends TestCase
{
public function setUp()
{
}
public function testFunctionality()
{
$value = 'SomeValue';
Assert::false(5);
}
public function testException()
{
$o = 1;
Assert::exception(function () use ($o) {
$o->say('');
}, InvalidArgumentException::class, 'Invalid name');
}
}
(new ExtensionTest())->run();
?>
-----
<?php
namespace Rector\Tests\NetteTesterToPHPUnit\Rector\Class_\NetteTesterClassToPHPUnitClassRector\Fixture;
use Tester\Assert;
use Tester\TestCase;
class ExtensionTest extends \PHPUnit\Framework\TestCase
{
protected function setUp()
{
}
public function testFunctionality()
{
$value = 'SomeValue';
$this->assertFalse(5);
}
public function testException()
{
$o = 1;
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage('Invalid name');
$o->say('');
}
}
?>

View File

@ -1,101 +0,0 @@
<?php
namespace Rector\Tests\NetteTesterToPHPUnit\Rector\Class_\NetteTesterClassToPHPUnitClassRector\Fixture;
use Tester\Assert;
use Tester\TestCase;
class VariousAssertsTest extends TestCase
{
public function testFunctionality()
{
$value = 'SomeValue';
Assert::type(\Kdyby\Doctrine\EntityManager::class, $value);
Assert::false(5);
Assert::same('ExpectedValue', $value);
}
public function testExceptions()
{
Assert::exception(function () {
$builder = new DI\ContainerBuilder;
$builder->run();
}, 'ExceptionClass', "Service 'one': Class or interface 'X' not found.", 200);
}
public function testNoError()
{
Assert::noError(function () {
$value = 1;
});
}
public function testY()
{
Assert::falsey('value', 'some messsage');
// keep my comments
Assert::truthy(true);
}
public function testContains()
{
$value = 'some messsage';
Assert::contains('value', $value);
$values = [];
Assert::contains('value', $values);
}
}
?>
-----
<?php
namespace Rector\Tests\NetteTesterToPHPUnit\Rector\Class_\NetteTesterClassToPHPUnitClassRector\Fixture;
use Tester\Assert;
use Tester\TestCase;
class VariousAssertsTest extends \PHPUnit\Framework\TestCase
{
public function testFunctionality()
{
$value = 'SomeValue';
$this->assertInstanceOf(\Kdyby\Doctrine\EntityManager::class, $value);
$this->assertFalse(5);
$this->assertSame('ExpectedValue', $value);
}
public function testExceptions()
{
$this->expectException('ExceptionClass');
$this->expectExceptionMessage("Service 'one': Class or interface 'X' not found.");
$this->expectExceptionCode(200);
$builder = new DI\ContainerBuilder;
$builder->run();
}
/**
* @doesNotPerformAssertions
*/
public function testNoError()
{
$value = 1;
}
public function testY()
{
$this->assertFalse((bool) 'value', 'some messsage');
// keep my comments
$this->assertTrue(true);
}
public function testContains()
{
$value = 'some messsage';
$this->assertStringContainsString('value', $value);
$values = [];
$this->assertContains('value', $values);
}
}
?>

View File

@ -1,33 +0,0 @@
<?php
declare(strict_types=1);
namespace Rector\Tests\NetteTesterToPHPUnit\Rector\Class_\NetteTesterClassToPHPUnitClassRector;
use Iterator;
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
use Symplify\SmartFileSystem\SmartFileInfo;
final class NetteTesterClassToPHPUnitClassRectorTest extends AbstractRectorTestCase
{
/**
* @dataProvider provideData()
*/
public function test(SmartFileInfo $fileInfo): void
{
$this->doTestFileInfo($fileInfo);
}
/**
* @return Iterator<SmartFileInfo>
*/
public function provideData(): Iterator
{
return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture');
}
public function provideConfigFilePath(): string
{
return __DIR__ . '/config/configured_rule.php';
}
}

View File

@ -1,11 +0,0 @@
<?php
declare(strict_types=1);
namespace Rector\Tests\NetteTesterToPHPUnit\Rector\Class_\NetteTesterClassToPHPUnitClassRector\Source;
use Tester\TestCase;
abstract class ORMTestCase extends TestCase
{
}

View File

@ -1,11 +0,0 @@
<?php
use Rector\NetteTesterToPHPUnit\Rector\Class_\NetteTesterClassToPHPUnitClassRector;
use Rector\NetteTesterToPHPUnit\Rector\StaticCall\NetteAssertToPHPUnitAssertRector;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
return static function (ContainerConfigurator $containerConfigurator): void {
$services = $containerConfigurator->services();
$services->set(NetteAssertToPHPUnitAssertRector::class);
$services->set(NetteTesterClassToPHPUnitClassRector::class);
};

View File

@ -1,44 +0,0 @@
<?php
declare(strict_types=1);
namespace Rector\Tests\NetteTesterToPHPUnit\Rector\Class_\RenameTesterTestToPHPUnitToTestFileRector;
use Iterator;
use Rector\FileSystemRector\ValueObject\AddedFileWithContent;
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
use Symplify\SmartFileSystem\SmartFileInfo;
use Symplify\SmartFileSystem\SmartFileSystem;
final class RenameTesterTestToPHPUnitToTestFileRectorTest extends AbstractRectorTestCase
{
/**
* @dataProvider provideData()
*/
public function test(SmartFileInfo $fixtureFileInfo, AddedFileWithContent $expectedAddedFileWithContent): void
{
$this->doTestFileInfo($fixtureFileInfo);
$this->assertFileWasAdded($expectedAddedFileWithContent);
}
/**
* @return Iterator<AddedFileWithContent[]|SmartFileInfo[]>
*/
public function provideData(): Iterator
{
$smartFileSystem = new SmartFileSystem();
yield [
new SmartFileInfo(__DIR__ . '/Source/SomeCase.phpt'),
new AddedFileWithContent(
$this->getFixtureTempDirectory() . '/SomeCaseTest.php',
$smartFileSystem->readFile(__DIR__ . '/Source/SomeCase.phpt')
),
];
}
public function provideConfigFilePath(): string
{
return __DIR__ . '/config/configured_rule.php';
}
}

View File

@ -1,12 +0,0 @@
<?php
declare(strict_types=1);
namespace Rector\Tests\NetteTesterToPHPUnit\Rector\RenameTesterTestToPHPUnitToTestFileRector\Source;
final class SomeCase
{
public function testThis()
{
}
}

View File

@ -1,15 +0,0 @@
<?php
declare(strict_types=1);
use Rector\Core\Configuration\Option;
use Rector\NetteTesterToPHPUnit\Rector\Class_\RenameTesterTestToPHPUnitToTestFileRector;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
return static function (ContainerConfigurator $containerConfigurator): void {
$parameters = $containerConfigurator->parameters();
$parameters->set(Option::FILE_EXTENSIONS, ['php', 'phpt']);
$services = $containerConfigurator->services();
$services->set(RenameTesterTestToPHPUnitToTestFileRector::class);
};

View File

@ -1,43 +0,0 @@
<?php
namespace Rector\Tests\NetteToSymfony\Rector\ClassMethod\RenameEventNamesInEventSubscriberRector\Fixture;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
final class EventClass implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
return [
'nette.application.startup' => 'someMethod',
];
}
public function someMethod(OldEvent $event)
{
}
}
?>
-----
<?php
namespace Rector\Tests\NetteToSymfony\Rector\ClassMethod\RenameEventNamesInEventSubscriberRector\Fixture;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
final class EventClass implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
return [
\Symfony\Component\HttpKernel\KernelEvents::REQUEST => 'someMethod',
];
}
public function someMethod(\Symfony\Component\HttpKernel\Event\GetResponseEvent $event)
{
}
}
?>

View File

@ -1,39 +0,0 @@
<?php
namespace Rector\Tests\NetteToSymfony\Rector\ClassMethod\RenameEventNamesInEventSubscriberRector\Fixture;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Contributte\Events\Extra\Event\Application\PresenterStartupEvent;
final class SomeClass implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
return [
'nette.application.startup' => 'someMethod',
\Contributte\Events\Extra\Event\Application\StartupEvent::NAME => 'someMethod',
];
}
}
?>
-----
<?php
namespace Rector\Tests\NetteToSymfony\Rector\ClassMethod\RenameEventNamesInEventSubscriberRector\Fixture;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Contributte\Events\Extra\Event\Application\PresenterStartupEvent;
final class SomeClass implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
return [
\Symfony\Component\HttpKernel\KernelEvents::REQUEST => 'someMethod',
\Symfony\Component\HttpKernel\KernelEvents::REQUEST => 'someMethod',
];
}
}
?>

View File

@ -1,37 +0,0 @@
<?php
namespace Rector\Tests\NetteToSymfony\Rector\ClassMethod\RenameEventNamesInEventSubscriberRector\Fixture;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Contributte\Events\Extra\Event\Application\PresenterStartupEvent;
final class PresenterStartup implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
return [
PresenterStartupEvent::NAME => 'someMethod',
];
}
}
?>
-----
<?php
namespace Rector\Tests\NetteToSymfony\Rector\ClassMethod\RenameEventNamesInEventSubscriberRector\Fixture;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Contributte\Events\Extra\Event\Application\PresenterStartupEvent;
final class PresenterStartup implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
return [
\Symfony\Component\HttpKernel\KernelEvents::CONTROLLER => 'someMethod',
];
}
}
?>

View File

@ -1,33 +0,0 @@
<?php
declare(strict_types=1);
namespace Rector\Tests\NetteToSymfony\Rector\ClassMethod\RenameEventNamesInEventSubscriberRector;
use Iterator;
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
use Symplify\SmartFileSystem\SmartFileInfo;
final class RenameEventNamesInEventSubscriberRectorTest extends AbstractRectorTestCase
{
/**
* @dataProvider provideData()
*/
public function test(SmartFileInfo $fileInfo): void
{
$this->doTestFileInfo($fileInfo);
}
/**
* @return Iterator<SmartFileInfo>
*/
public function provideData(): Iterator
{
return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture');
}
public function provideConfigFilePath(): string
{
return __DIR__ . '/config/configured_rule.php';
}
}

View File

@ -1,11 +0,0 @@
<?php
declare(strict_types=1);
use Rector\NetteToSymfony\Rector\ClassMethod\RenameEventNamesInEventSubscriberRector;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
return static function (ContainerConfigurator $containerConfigurator): void {
$services = $containerConfigurator->services();
$services->set(RenameEventNamesInEventSubscriberRector::class);
};

View File

@ -1,61 +0,0 @@
<?php
namespace Rector\Tests\NetteToSymfony\Rector\ClassMethod\RouterListToControllerAnnotationsRector\Fixture;
use Nette\Application\Routers\Route;
use Nette\Application\Routers\RouteList;
final class ConstantReferenceRouterFactory
{
const SOME_PATH = '/some-path';
public function create(): RouteList
{
$routeList = new RouteList();
// case of single action controller, usually get() or __invoke() method
$routeList[] = new Route(self::SOME_PATH, ConstantReferenceSomePresenter::class);
return $routeList;
}
}
final class ConstantReferenceSomePresenter
{
public function run()
{
}
}
?>
-----
<?php
namespace Rector\Tests\NetteToSymfony\Rector\ClassMethod\RouterListToControllerAnnotationsRector\Fixture;
use Nette\Application\Routers\Route;
use Nette\Application\Routers\RouteList;
final class ConstantReferenceRouterFactory
{
const SOME_PATH = '/some-path';
public function create(): RouteList
{
$routeList = new RouteList();
return $routeList;
}
}
final class ConstantReferenceSomePresenter
{
/**
* @\Symfony\Component\Routing\Annotation\Route(path="/some-path")
*/
public function run()
{
}
}
?>

View File

@ -1,66 +0,0 @@
<?php
namespace Rector\Tests\NetteToSymfony\Rector\ClassMethod\RouterListToControllerAnnotationsRector\Fixture;
use Nette\Application\Routers\Route;
use Nette\Application\Routers\RouteList;
final class GeneralMethodNamedRoutesRouterFactory
{
public function create(): RouteList
{
$routeList = new RouteList();
$routeList[] = new Route('<presenter>/<action>', 'Homepage:default');
return $routeList;
}
}
final class GeneralMethodNamedRoutesSomePresenter
{
public function actionFirst()
{
}
public function actionSecond()
{
}
}
?>
-----
<?php
namespace Rector\Tests\NetteToSymfony\Rector\ClassMethod\RouterListToControllerAnnotationsRector\Fixture;
use Nette\Application\Routers\Route;
use Nette\Application\Routers\RouteList;
final class GeneralMethodNamedRoutesRouterFactory
{
public function create(): RouteList
{
$routeList = new RouteList();
return $routeList;
}
}
final class GeneralMethodNamedRoutesSomePresenter
{
/**
* @\Symfony\Component\Routing\Annotation\Route(path="general-method-named-routes-some/first")
*/
public function actionFirst()
{
}
/**
* @\Symfony\Component\Routing\Annotation\Route(path="general-method-named-routes-some/second")
*/
public function actionSecond()
{
}
}
?>

View File

@ -1,68 +0,0 @@
<?php
namespace Rector\Tests\NetteToSymfony\Rector\ClassMethod\RouterListToControllerAnnotationsRector\Fixture;
use Nette\Application\Routers\Route;
use Nette\Application\Routers\RouteList;
final class MethodNamedRoutesRouterFactory
{
public function create(): RouteList
{
$routeList = new RouteList();
$routeList[] = new Route('hi', 'MethodNamedRoutesSome:first');
$routeList[] = new Route('hello', 'MethodNamedRoutesSome:second');
$routeList[] = new Route('<presenter>/<action>', 'Homepage:default');
return $routeList;
}
}
final class MethodNamedRoutesSomePresenter
{
public function actionFirst()
{
}
public function actionSecond()
{
}
}
?>
-----
<?php
namespace Rector\Tests\NetteToSymfony\Rector\ClassMethod\RouterListToControllerAnnotationsRector\Fixture;
use Nette\Application\Routers\Route;
use Nette\Application\Routers\RouteList;
final class MethodNamedRoutesRouterFactory
{
public function create(): RouteList
{
$routeList = new RouteList();
return $routeList;
}
}
final class MethodNamedRoutesSomePresenter
{
/**
* @\Symfony\Component\Routing\Annotation\Route(path="hi")
*/
public function actionFirst()
{
}
/**
* @\Symfony\Component\Routing\Annotation\Route(path="hello")
*/
public function actionSecond()
{
}
}
?>

View File

@ -1,57 +0,0 @@
<?php
namespace Rector\Tests\NetteToSymfony\Rector\ClassMethod\RouterListToControllerAnnotationsRector\Fixture;
use Nette\Application\Routers\Route;
use Nette\Application\Routers\RouteList;
final class NewRouterFactory
{
public function create(): RouteList
{
$routeList = new RouteList();
// case of single action controller, usually get() or __invoke() method
$routeList[] = new Route('some-path', NewSomePresenter::class);
return $routeList;
}
}
final class NewSomePresenter
{
public function run()
{
}
}
?>
-----
<?php
namespace Rector\Tests\NetteToSymfony\Rector\ClassMethod\RouterListToControllerAnnotationsRector\Fixture;
use Nette\Application\Routers\Route;
use Nette\Application\Routers\RouteList;
final class NewRouterFactory
{
public function create(): RouteList
{
$routeList = new RouteList();
return $routeList;
}
}
final class NewSomePresenter
{
/**
* @\Symfony\Component\Routing\Annotation\Route(path="some-path")
*/
public function run()
{
}
}
?>

View File

@ -1,57 +0,0 @@
<?php
namespace Rector\Tests\NetteToSymfony\Rector\ClassMethod\RouterListToControllerAnnotationsRector\Fixture;
use Nette\Application\Routers\RouteList;
use Rector\Tests\NetteToSymfony\Rector\ClassMethod\RouterListToControllerAnnotationsRector\Source\RouteFactory;
final class StaticRouterFactory
{
public function create(): RouteList
{
$routeList = new RouteList();
// case of single action controller, usually get() or __invoke() method
$routeList[] = RouteFactory::get('some-path', StaticSomePresenter::class);
return $routeList;
}
}
final class StaticSomePresenter
{
public function run()
{
}
}
?>
-----
<?php
namespace Rector\Tests\NetteToSymfony\Rector\ClassMethod\RouterListToControllerAnnotationsRector\Fixture;
use Nette\Application\Routers\RouteList;
use Rector\Tests\NetteToSymfony\Rector\ClassMethod\RouterListToControllerAnnotationsRector\Source\RouteFactory;
final class StaticRouterFactory
{
public function create(): RouteList
{
$routeList = new RouteList();
return $routeList;
}
}
final class StaticSomePresenter
{
/**
* @\Symfony\Component\Routing\Annotation\Route(path="some-path", methods={"GET"})
*/
public function run()
{
}
}
?>

View File

@ -1,64 +0,0 @@
<?php
namespace Rector\Tests\NetteToSymfony\Rector\ClassMethod\RouterListToControllerAnnotationsRector\Fixture;
use Nette\Application\IPresenter;
use Nette\Application\IResponse;
use Nette\Application\Routers\Route;
use Nette\Application\Routers\RouteList;
final class WithParameterRouterFactory
{
public function create(): RouteList
{
$routeList = new RouteList();
$routeList[] = new Route('some-path/<id>', WithParameterSomePresenter::class);
return $routeList;
}
}
final class WithParameterSomePresenter implements IPresenter
{
/**
* @doto
*/
public function run(\Nette\Application\Request $request): IResponse
{
}
}
?>
-----
<?php
namespace Rector\Tests\NetteToSymfony\Rector\ClassMethod\RouterListToControllerAnnotationsRector\Fixture;
use Nette\Application\IPresenter;
use Nette\Application\IResponse;
use Nette\Application\Routers\Route;
use Nette\Application\Routers\RouteList;
final class WithParameterRouterFactory
{
public function create(): RouteList
{
$routeList = new RouteList();
return $routeList;
}
}
final class WithParameterSomePresenter implements IPresenter
{
/**
* @doto
* @\Symfony\Component\Routing\Annotation\Route(path="some-path/{id}")
*/
public function run(\Nette\Application\Request $request): IResponse
{
}
}
?>

View File

@ -1,33 +0,0 @@
<?php
declare(strict_types=1);
namespace Rector\Tests\NetteToSymfony\Rector\ClassMethod\RouterListToControllerAnnotationsRector;
use Iterator;
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
use Symplify\SmartFileSystem\SmartFileInfo;
final class RouterListToControllerAnnotationsRectorTest extends AbstractRectorTestCase
{
/**
* @dataProvider provideData()
*/
public function test(SmartFileInfo $fileInfo): void
{
$this->doTestFileInfo($fileInfo);
}
/**
* @return Iterator<SmartFileInfo>
*/
public function provideData(): Iterator
{
return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture');
}
public function provideConfigFilePath(): string
{
return __DIR__ . '/config/configured_rule.php';
}
}

View File

@ -1,12 +0,0 @@
<?php
declare(strict_types=1);
namespace Rector\Tests\NetteToSymfony\Rector\ClassMethod\RouterListToControllerAnnotationsRector\Source;
final class Route
{
public function __construct(string $path, string $target)
{
}
}

View File

@ -1,15 +0,0 @@
<?php
declare(strict_types=1);
namespace Rector\Tests\NetteToSymfony\Rector\ClassMethod\RouterListToControllerAnnotationsRector\Source;
use Nette\Application\Routers\Route;
final class RouteFactory
{
public static function get(string $path, string $presenterClass): Route
{
return new Route($path, $presenterClass);
}
}

View File

@ -1,11 +0,0 @@
<?php
declare(strict_types=1);
use Rector\NetteToSymfony\Rector\ClassMethod\RouterListToControllerAnnotationsRector;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
return static function (ContainerConfigurator $containerConfigurator): void {
$services = $containerConfigurator->services();
$services->set(RouterListToControllerAnnotationsRector::class);
};

View File

@ -1,41 +0,0 @@
<?php
namespace Rector\Tests\NetteToSymfony\Rector\Class_\FormControlToControllerAndFormTypeRector\Fixture;
use Nette\Application\UI\Form;
use Nette\Application\UI\Control;
class SomeForm extends Control
{
public function createComponentForm()
{
$form = new Form();
$form->addText('name', 'Your name');
$form->onSuccess[] = [$this, 'processForm'];
}
public function processForm(Form $form)
{
// process me
}
}
?>
-----
<?php
namespace Rector\Tests\NetteToSymfony\Rector\Class_\FormControlToControllerAndFormTypeRector\Fixture;
use Nette\Application\UI\Form;
use Nette\Application\UI\Control;
class SomeFormType extends \Symfony\Component\Form\AbstractType
{
public function buildForm(\Symfony\Component\Form\FormBuilderInterface $formBuilder, array $options)
{
$formBuilder->add('name', \Symfony\Component\Form\Extension\Core\Type\TextType::class, ['label' => 'Your name']);
}
}
?>

View File

@ -1,42 +0,0 @@
<?php
declare(strict_types=1);
namespace Rector\Tests\NetteToSymfony\Rector\Class_\FormControlToControllerAndFormTypeRector;
use Iterator;
use Nette\Utils\FileSystem;
use Rector\FileSystemRector\ValueObject\AddedFileWithContent;
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
use Symplify\SmartFileSystem\SmartFileInfo;
final class FormControlToControllerAndFormTypeRectorTest extends AbstractRectorTestCase
{
/**
* @dataProvider provideData()
*/
public function test(SmartFileInfo $fileInfo, AddedFileWithContent $expectedAddedFileWithContent): void
{
$this->doTestFileInfo($fileInfo);
$this->assertFileWasAdded($expectedAddedFileWithContent);
}
/**
* @return Iterator<string[]|SmartFileInfo[]>
*/
public function provideData(): Iterator
{
yield [
new SmartFileInfo(__DIR__ . '/Fixture/fixture.php.inc'),
new AddedFileWithContent(
'src/Controller/SomeFormController.php',
FileSystem::read(__DIR__ . '/Source/extra_file.php')
),
];
}
public function provideConfigFilePath(): string
{
return __DIR__ . '/config/configured_rule.php';
}
}

View File

@ -1,14 +0,0 @@
<?php
namespace Rector\Tests\NetteToSymfony\Rector\Class_\FormControlToControllerAndFormTypeRector\Fixture;
class SomeFormController extends \Symfony\Bundle\FrameworkBundle\Controller\AbstractController
{
public function actionSomeForm(\Symfony\Component\HttpFoundation\Request $request): \Symfony\Component\HttpFoundation\Response
{
$form = $this->createForm(\Rector\Tests\NetteToSymfony\Rector\Class_\FormControlToControllerAndFormTypeRector\Fixture\SomeFormType::class);
$form->handleRequest($request);
if ($form->isSuccess() && $form->isValid()) {
}
}
}

View File

@ -1,11 +0,0 @@
<?php
declare(strict_types=1);
use Rector\NetteToSymfony\Rector\Class_\FormControlToControllerAndFormTypeRector;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
return static function (ContainerConfigurator $containerConfigurator): void {
$services = $containerConfigurator->services();
$services->set(FormControlToControllerAndFormTypeRector::class);
};

View File

@ -1,32 +0,0 @@
<?php
namespace Rector\Tests\NetteToSymfony\Rector\Class_\NetteControlToSymfonyControllerRector\Fixture;
use Nette\Application\UI\Control;
class SomeControl extends Control
{
public function render()
{
$this->template->param = 'some value';
$this->template->render(__DIR__ . '/poll.latte');
}
}
?>
-----
<?php
namespace Rector\Tests\NetteToSymfony\Rector\Class_\NetteControlToSymfonyControllerRector\Fixture;
use Nette\Application\UI\Control;
class SomeController extends \Symfony\Bundle\FrameworkBundle\Controller\AbstractController
{
public function action(): \Symfony\Component\HttpFoundation\Response
{
return $this->render(__DIR__ . '/poll.latte', ['param' => 'some value']);
}
}
?>

View File

@ -1,42 +0,0 @@
<?php
declare(strict_types=1);
namespace Rector\Tests\NetteToSymfony\Rector\Class_\NetteControlToSymfonyControllerRector\Fixture;
use Nette\Application\UI\Control;
class GetPresenterSession extends Control
{
public function render(): void
{
$someSessionSection = $this->getPresenter()->getSession('some_name');
$this->render();
}
}
?>
-----
<?php
declare(strict_types=1);
namespace Rector\Tests\NetteToSymfony\Rector\Class_\NetteControlToSymfonyControllerRector\Fixture;
use Nette\Application\UI\Control;
class GetPresenterSessionController extends \Symfony\Bundle\FrameworkBundle\Controller\AbstractController
{
public function __construct(private \Nette\Http\Session $session)
{
}
public function action(): \Symfony\Component\HttpFoundation\Response
{
$someSessionSection = $this->session->getSession('some_name');
return $this->render();
}
}
?>

View File

@ -1,14 +0,0 @@
<?php
namespace Rector\Tests\NetteToSymfony\Rector\Class_\NetteControlToSymfonyControllerRector\Fixture;
use Nette\Application\UI\Presenter;
class SkipPresenter extends Presenter
{
public function render()
{
$this->template->param = 'some value';
$this->template->render(__DIR__ . '/poll.latte');
}
}

View File

@ -1,62 +0,0 @@
<?php
declare(strict_types=1);
namespace Rector\Tests\NetteToSymfony\Rector\Class_\NetteControlToSymfonyControllerRector\Fixture;
use App\Service\BasketManager;
use Nette\Application\UI\Control;
class TemplateWithAssign extends Control
{
/**
* @var \App\Service\BasketManager
*/
private $basketManager;
public function __construct(BasketManager $basketManager)
{
$this->basketManager = $basketManager;
}
public function render(): void
{
$this->template->setFile(__DIR__ . '/templates/default.latte');
$this->template->items = $this->basketManager->getItems();
$this->template->discountCode = $this->basketManager->getDiscountCode();
$this->template->render();
}
}
?>
-----
<?php
declare(strict_types=1);
namespace Rector\Tests\NetteToSymfony\Rector\Class_\NetteControlToSymfonyControllerRector\Fixture;
use App\Service\BasketManager;
use Nette\Application\UI\Control;
class TemplateWithAssignController extends \Symfony\Bundle\FrameworkBundle\Controller\AbstractController
{
/**
* @var \App\Service\BasketManager
*/
private $basketManager;
public function __construct(BasketManager $basketManager)
{
$this->basketManager = $basketManager;
}
public function action(): \Symfony\Component\HttpFoundation\Response
{
return $this->render(__DIR__ . '/templates/default.latte', ['items' => $this->basketManager->getItems(), 'discountCode' => $this->basketManager->getDiscountCode()]);
}
}
?>

View File

@ -1,33 +0,0 @@
<?php
declare(strict_types=1);
namespace Rector\Tests\NetteToSymfony\Rector\Class_\NetteControlToSymfonyControllerRector;
use Iterator;
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
use Symplify\SmartFileSystem\SmartFileInfo;
final class NetteControlToSymfonyControllerRectorTest extends AbstractRectorTestCase
{
/**
* @dataProvider provideData()
*/
public function test(SmartFileInfo $fileInfo): void
{
$this->doTestFileInfo($fileInfo);
}
/**
* @return Iterator<SmartFileInfo>
*/
public function provideData(): Iterator
{
return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture');
}
public function provideConfigFilePath(): string
{
return __DIR__ . '/config/configured_rule.php';
}
}

View File

@ -1,11 +0,0 @@
<?php
declare(strict_types=1);
use Rector\NetteToSymfony\Rector\Class_\NetteControlToSymfonyControllerRector;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
return static function (ContainerConfigurator $containerConfigurator): void {
$services = $containerConfigurator->services();
$services->set(NetteControlToSymfonyControllerRector::class);
};

View File

@ -1,34 +0,0 @@
<?php
declare(strict_types=1);
namespace Rector\Tests\NetteToSymfony\Rector\Interface_\DeleteFactoryInterfaceRector;
use Iterator;
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
use Symplify\SmartFileSystem\SmartFileInfo;
final class DeleteFactoryInterfaceFileSystemRectorTest extends AbstractRectorTestCase
{
/**
* @dataProvider provideData()
*/
public function test(SmartFileInfo $smartFileInfo): void
{
$this->doTestFileInfo($smartFileInfo);
$this->assertFileWasRemoved($this->originalTempFileInfo);
}
/**
* @return Iterator<SmartFileInfo>
*/
public function provideData(): Iterator
{
return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture');
}
public function provideConfigFilePath(): string
{
return __DIR__ . '/config/configured_rule.php';
}
}

View File

@ -1,15 +0,0 @@
<?php
declare(strict_types=1);
namespace Rector\Tests\NetteToSymfony\Rector\Interface_\DeleteFactoryInterfaceRector\Fixture;
use Rector\Tests\NetteToSymfony\Rector\Interface_\DeleteFactoryInterfaceRector\Source\SomeControl;
interface SkipSomeFactoryInterface
{
/**
* @return SomeControl
*/
public function create();
}

View File

@ -1,12 +0,0 @@
<?php
declare(strict_types=1);
namespace Rector\Tests\NetteToSymfony\Rector\Interface_\DeleteFactoryInterfaceRector\Source;
use Nette\Application\UI\Control;
final class SomeControl extends Control
{
}

View File

@ -1,11 +0,0 @@
<?php
declare(strict_types=1);
use Rector\NetteToSymfony\Rector\Interface_\DeleteFactoryInterfaceRector;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
return static function (ContainerConfigurator $containerConfigurator): void {
$services = $containerConfigurator->services();
$services->set(DeleteFactoryInterfaceRector::class);
};

View File

@ -1,41 +0,0 @@
<?php
namespace Rector\Tests\NetteToSymfony\Rector\MethodCall\FromHttpRequestGetHeaderToHeadersGetRector\Fixture;
use Symfony\Component\HttpFoundation\Request;
final class SomeController
{
/**
* @var \Nette\Http\Request
*/
private $httpRequest;
public function someAction(Request $request)
{
$header = $this->httpRequest->getHeader('x');
}
}
?>
-----
<?php
namespace Rector\Tests\NetteToSymfony\Rector\MethodCall\FromHttpRequestGetHeaderToHeadersGetRector\Fixture;
use Symfony\Component\HttpFoundation\Request;
final class SomeController
{
/**
* @var \Nette\Http\Request
*/
private $httpRequest;
public function someAction(Request $request)
{
$header = $request->headers->get('x');
}
}
?>

View File

@ -1,53 +0,0 @@
<?php
namespace Rector\Tests\NetteToSymfony\Rector\MethodCall\FromHttpRequestGetHeaderToHeadersGetRector\Fixture;
use Nette\Http\Request;
use Rector\Tests\NetteToSymfony\Rector\MethodCall\FromHttpRequestGetHeaderToHeadersGetRector\Source\IrrelevantRequest;
final class SomeMissingArgumentController
{
/**
* @var Request
*/
private $httpRequest;
public function someAction()
{
$header = $this->httpRequest->getHeader('x');
}
public function anotherAction(IrrelevantRequest $request)
{
$header = $this->httpRequest->getHeader('x');
}
}
?>
-----
<?php
namespace Rector\Tests\NetteToSymfony\Rector\MethodCall\FromHttpRequestGetHeaderToHeadersGetRector\Fixture;
use Nette\Http\Request;
use Rector\Tests\NetteToSymfony\Rector\MethodCall\FromHttpRequestGetHeaderToHeadersGetRector\Source\IrrelevantRequest;
final class SomeMissingArgumentController
{
/**
* @var Request
*/
private $httpRequest;
public function someAction(\Symfony\Component\HttpFoundation\Request $request)
{
$header = $request->headers->get('x');
}
public function anotherAction(IrrelevantRequest $request, \Symfony\Component\HttpFoundation\Request $symfonyRequest)
{
$header = $symfonyRequest->headers->get('x');
}
}
?>

View File

@ -1,33 +0,0 @@
<?php
declare(strict_types=1);
namespace Rector\Tests\NetteToSymfony\Rector\MethodCall\FromHttpRequestGetHeaderToHeadersGetRector;
use Iterator;
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
use Symplify\SmartFileSystem\SmartFileInfo;
final class FromHttpRequestGetHeaderToHeadersGetRectorTest extends AbstractRectorTestCase
{
/**
* @dataProvider provideData()
*/
public function test(SmartFileInfo $fileInfo): void
{
$this->doTestFileInfo($fileInfo);
}
/**
* @return Iterator<SmartFileInfo>
*/
public function provideData(): Iterator
{
return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture');
}
public function provideConfigFilePath(): string
{
return __DIR__ . '/config/configured_rule.php';
}
}

View File

@ -1,10 +0,0 @@
<?php
declare(strict_types=1);
namespace Rector\Tests\NetteToSymfony\Rector\MethodCall\FromHttpRequestGetHeaderToHeadersGetRector\Source;
final class IrrelevantRequest
{
}

View File

@ -1,11 +0,0 @@
<?php
declare(strict_types=1);
use Rector\NetteToSymfony\Rector\MethodCall\FromHttpRequestGetHeaderToHeadersGetRector;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
return static function (ContainerConfigurator $containerConfigurator): void {
$services = $containerConfigurator->services();
$services->set(FromHttpRequestGetHeaderToHeadersGetRector::class);
};

View File

@ -1,41 +0,0 @@
<?php
namespace Rector\Tests\NetteToSymfony\Rector\MethodCall\FromRequestGetParameterToAttributesGetRector\Fixture;
use Nette\Application\Request;
final class SomeController
{
public function someAction(Request $request)
{
$value = $request->getParameter('abz');
}
public function anotherAction(Request $appRequest)
{
$value = $appRequest->getParameter('abz');
}
}
?>
-----
<?php
namespace Rector\Tests\NetteToSymfony\Rector\MethodCall\FromRequestGetParameterToAttributesGetRector\Fixture;
use Nette\Application\Request;
final class SomeController
{
public function someAction(Request $request)
{
$value = $request->attributes->get('abz');
}
public function anotherAction(Request $appRequest)
{
$value = $appRequest->attributes->get('abz');
}
}
?>

View File

@ -1,33 +0,0 @@
<?php
declare(strict_types=1);
namespace Rector\Tests\NetteToSymfony\Rector\MethodCall\FromRequestGetParameterToAttributesGetRector;
use Iterator;
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
use Symplify\SmartFileSystem\SmartFileInfo;
final class FromRequestGetParameterToAttributesGetRectorTest extends AbstractRectorTestCase
{
/**
* @dataProvider provideData()
*/
public function test(SmartFileInfo $fileInfo): void
{
$this->doTestFileInfo($fileInfo);
}
/**
* @return Iterator<SmartFileInfo>
*/
public function provideData(): Iterator
{
return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture');
}
public function provideConfigFilePath(): string
{
return __DIR__ . '/config/configured_rule.php';
}
}

View File

@ -1,11 +0,0 @@
<?php
declare(strict_types=1);
use Rector\NetteToSymfony\Rector\MethodCall\FromRequestGetParameterToAttributesGetRector;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
return static function (ContainerConfigurator $containerConfigurator): void {
$services = $containerConfigurator->services();
$services->set(FromRequestGetParameterToAttributesGetRector::class);
};

View File

@ -1,67 +0,0 @@
<?php
namespace Rector\Tests\NetteToSymfony\Rector\MethodCall\NetteFormToSymfonyFormRector\Fixture;
use Rector\Tests\NetteToSymfony\Rector\MethodCall\NetteFormToSymfonyFormRector\Source\NettePresenter;
use Nette\Application\UI\Form;
class SomePresenter extends NettePresenter
{
public function someAction()
{
$form = new Form;
$form->addText('name', 'Name:');
// "name", "label", "cols", "maxLength"
$form->addText('name', 'Name:', 25, 200);
$form->addPassword('password', 'Password:');
$form->addSubmit('login', 'Sign up');
}
public function selects()
{
$form = new Form;
$form->addSelect('select');
$form->addRadioList('radio_list');
$form->addCheckboxList('checkbox_list');
$form->addMultiSelect('multi_select');
$form->addMultiUpload('multi_upload');
}
}
?>
-----
<?php
namespace Rector\Tests\NetteToSymfony\Rector\MethodCall\NetteFormToSymfonyFormRector\Fixture;
use Rector\Tests\NetteToSymfony\Rector\MethodCall\NetteFormToSymfonyFormRector\Source\NettePresenter;
use Nette\Application\UI\Form;
class SomePresenter extends NettePresenter
{
public function someAction()
{
$form = $this->createFormBuilder();
$form->add('name', \Symfony\Component\Form\Extension\Core\Type\TextType::class, ['label' => 'Name:']);
// "name", "label", "cols", "maxLength"
$form->add('name', \Symfony\Component\Form\Extension\Core\Type\TextType::class, ['label' => 'Name:']);
$form->add('password', \Symfony\Component\Form\Extension\Core\Type\PasswordType::class, ['label' => 'Password:']);
$form->add('login', \Symfony\Component\Form\Extension\Core\Type\SubmitType::class, ['label' => 'Sign up']);
}
public function selects()
{
$form = $this->createFormBuilder();
$form->add('select', \Symfony\Component\Form\Extension\Core\Type\ChoiceType::class, ['expanded' => false, 'multiple' => false]);
$form->add('radio_list', \Symfony\Component\Form\Extension\Core\Type\ChoiceType::class, ['expanded' => true, 'multiple' => false]);
$form->add('checkbox_list', \Symfony\Component\Form\Extension\Core\Type\ChoiceType::class, ['expanded' => true, 'multiple' => true]);
$form->add('multi_select', \Symfony\Component\Form\Extension\Core\Type\ChoiceType::class, ['expanded' => false, 'multiple' => true]);
$form->add('multi_upload', \Symfony\Component\Form\Extension\Core\Type\FileType::class, ['multiple' => true]);
}
}
?>

View File

@ -1,33 +0,0 @@
<?php
declare(strict_types=1);
namespace Rector\Tests\NetteToSymfony\Rector\MethodCall\NetteFormToSymfonyFormRector;
use Iterator;
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
use Symplify\SmartFileSystem\SmartFileInfo;
final class NetteFormToSymfonyFormRectorTest extends AbstractRectorTestCase
{
/**
* @dataProvider provideData()
*/
public function test(SmartFileInfo $fileInfo): void
{
$this->doTestFileInfo($fileInfo);
}
/**
* @return Iterator<SmartFileInfo>
*/
public function provideData(): Iterator
{
return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture');
}
public function provideConfigFilePath(): string
{
return __DIR__ . '/config/configured_rule.php';
}
}

View File

@ -1,17 +0,0 @@
<?php
declare(strict_types=1);
namespace Rector\Tests\NetteToSymfony\Rector\MethodCall\NetteFormToSymfonyFormRector\Source;
use Nette\Application\IPresenter;
use Nette\Application\IResponse;
use Nette\Application\Request;
abstract class NettePresenter implements IPresenter
{
public function run(Request $request): IResponse
{
}
}

View File

@ -1,11 +0,0 @@
<?php
declare(strict_types=1);
use Rector\NetteToSymfony\Rector\MethodCall\NetteFormToSymfonyFormRector;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
return static function (ContainerConfigurator $containerConfigurator): void {
$services = $containerConfigurator->services();
$services->set(NetteFormToSymfonyFormRector::class);
};

View File

@ -1,39 +0,0 @@
<?php
namespace Rector\Tests\NetteToSymfony\Rector\MethodCall\WrapTransParameterNameRector\Fixture;
use Symfony\Component\Translation\Translator;
final class SomeController
{
public function run()
{
$translator = new Translator('');
$translated = $translator->trans(
'Hello %name%',
['name' => 'Tom']
);
}
}
?>
-----
<?php
namespace Rector\Tests\NetteToSymfony\Rector\MethodCall\WrapTransParameterNameRector\Fixture;
use Symfony\Component\Translation\Translator;
final class SomeController
{
public function run()
{
$translator = new Translator('');
$translated = $translator->trans(
'Hello %name%',
['%name%' => 'Tom']
);
}
}
?>

View File

@ -1,33 +0,0 @@
<?php
declare(strict_types=1);
namespace Rector\Tests\NetteToSymfony\Rector\MethodCall\WrapTransParameterNameRector;
use Iterator;
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
use Symplify\SmartFileSystem\SmartFileInfo;
final class WrapTransParameterNameRectorTest extends AbstractRectorTestCase
{
/**
* @dataProvider provideData()
*/
public function test(SmartFileInfo $fileInfo): void
{
$this->doTestFileInfo($fileInfo);
}
/**
* @return Iterator<SmartFileInfo>
*/
public function provideData(): Iterator
{
return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture');
}
public function provideConfigFilePath(): string
{
return __DIR__ . '/config/configured_rule.php';
}
}

View File

@ -1,11 +0,0 @@
<?php
declare(strict_types=1);
use Rector\NetteToSymfony\Rector\MethodCall\WrapTransParameterNameRector;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
return static function (ContainerConfigurator $containerConfigurator): void {
$services = $containerConfigurator->services();
$services->set(WrapTransParameterNameRector::class);
};

View File

@ -2,15 +2,15 @@
namespace Rector\Tests\Transform\Rector\Assign\DimFetchAssignToMethodCallRector\Fixture;
use Nette\Application\Routers\Route;
use Nette\Application\Routers\RouteList;
use Rector\Tests\Transform\Rector\Assign\DimFetchAssignToMethodCallRector\Source\SomeRoute;
use Rector\Tests\Transform\Rector\Assign\DimFetchAssignToMethodCallRector\Source\SomeRouteList;
class RouterFactory
final class RouterFactory
{
public static function createRouter()
{
$routeList = new RouteList();
$routeList[] = new Route('<module>/<presenter>/<action>[/<id>]', 'Homepage:default');
$routeList = new SomeRouteList();
$routeList[] = new SomeRoute('<module>/<presenter>/<action>[/<id>]', 'Homepage:default');
return $routeList;
}
}
@ -21,14 +21,14 @@ class RouterFactory
namespace Rector\Tests\Transform\Rector\Assign\DimFetchAssignToMethodCallRector\Fixture;
use Nette\Application\Routers\Route;
use Nette\Application\Routers\RouteList;
use Rector\Tests\Transform\Rector\Assign\DimFetchAssignToMethodCallRector\Source\SomeRoute;
use Rector\Tests\Transform\Rector\Assign\DimFetchAssignToMethodCallRector\Source\SomeRouteList;
class RouterFactory
final class RouterFactory
{
public static function createRouter()
{
$routeList = new RouteList();
$routeList = new SomeRouteList();
$routeList->addRoute('<module>/<presenter>/<action>[/<id>]', 'Homepage:default');
return $routeList;
}

View File

@ -0,0 +1,10 @@
<?php
declare(strict_types=1);
namespace Rector\Tests\Transform\Rector\Assign\DimFetchAssignToMethodCallRector\Source;
final class SomeRoute
{
}

View File

@ -0,0 +1,10 @@
<?php
declare(strict_types=1);
namespace Rector\Tests\Transform\Rector\Assign\DimFetchAssignToMethodCallRector\Source;
final class SomeRouteList
{
}

View File

@ -1,5 +1,7 @@
<?php
use Rector\Tests\Transform\Rector\Assign\DimFetchAssignToMethodCallRector\Source\SomeRoute;
use Rector\Tests\Transform\Rector\Assign\DimFetchAssignToMethodCallRector\Source\SomeRouteList;
use Rector\Transform\Rector\Assign\DimFetchAssignToMethodCallRector;
use Rector\Transform\ValueObject\DimFetchAssignToMethodCall;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
@ -10,11 +12,7 @@ return static function (ContainerConfigurator $containerConfigurator): void {
$services->set(DimFetchAssignToMethodCallRector::class)
->call('configure', [[
DimFetchAssignToMethodCallRector::DIM_FETCH_ASSIGN_TO_METHOD_CALL => ValueObjectInliner::inline([
new DimFetchAssignToMethodCall(
'Nette\Application\Routers\RouteList',
'Nette\Application\Routers\Route',
'addRoute'
),
new DimFetchAssignToMethodCall(SomeRouteList::class, SomeRoute::class, 'addRoute'),
]),
]]);
};

View File

@ -1,323 +0,0 @@
<?php
declare(strict_types=1);
namespace Rector\NetteTesterToPHPUnit;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\Cast\Bool_;
use PhpParser\Node\Expr\Closure;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\StaticCall;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Identifier;
use PhpParser\Node\Name;
use PhpParser\Node\Name\FullyQualified;
use PhpParser\Node\Stmt\ClassMethod;
use PHPStan\PhpDocParser\Ast\PhpDoc\GenericTagValueNode;
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode;
use PHPStan\Type\BooleanType;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
use Rector\Core\PhpParser\Node\Value\ValueResolver;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\NodeTypeResolver\NodeTypeResolver;
use Rector\NodeTypeResolver\TypeAnalyzer\StringTypeAnalyzer;
use Rector\PostRector\Collector\NodesToAddCollector;
use Rector\PostRector\Collector\NodesToRemoveCollector;
final class AssertManipulator
{
/**
* @see https://github.com/nette/tester/blob/master/src/Framework/Assert.php
*
* @see https://github.com/sebastianbergmann/phpunit/blob/master/src/Framework/Assert.php
*
* @var array<string, string>
*/
private const ASSERT_METHODS_REMAP = [
'same' => 'assertSame',
'notSame' => 'assertNotSame',
'equal' => 'assertEqual',
'notEqual' => 'assertNotEqual',
'true' => 'assertTrue',
'false' => 'assertFalse',
'null' => 'assertNull',
'notNull' => 'assertNotNull',
'count' => 'assertCount',
'match' => 'assertStringMatchesFormat',
'matchFile' => 'assertStringMatchesFormatFile',
'nan' => 'assertIsNumeric',
];
/**
* @var string[]
*/
private const TYPE_TO_METHOD = [
'list' => 'assertIsArray',
'array' => 'assertIsArray',
'bool' => 'assertIsBool',
'callable' => 'assertIsCallable',
'float' => 'assertIsFloat',
'int' => 'assertIsInt',
'integer' => 'assertIsInt',
'object' => 'assertIsObject',
'resource' => 'assertIsResource',
'string' => 'assertIsString',
'scalar' => 'assertIsScalar',
];
/**
* @var string
*/
private const CONTAINS = 'contains';
/**
* @var string
*/
private const THIS = 'this';
/**
* @var string
*/
private const SELF = 'self';
/**
* @var NodeNameResolver
*/
private $nodeNameResolver;
/**
* @var NodeTypeResolver
*/
private $nodeTypeResolver;
/**
* @var ValueResolver
*/
private $valueResolver;
/**
* @var StringTypeAnalyzer
*/
private $stringTypeAnalyzer;
/**
* @var NodesToRemoveCollector
*/
private $nodesToRemoveCollector;
/**
* @var NodesToAddCollector
*/
private $nodesToAddCollector;
/**
* @var PhpDocInfoFactory
*/
private $phpDocInfoFactory;
public function __construct(
NodeNameResolver $nodeNameResolver,
NodeTypeResolver $nodeTypeResolver,
NodesToAddCollector $nodesToAddCollector,
NodesToRemoveCollector $nodesToRemoveCollector,
StringTypeAnalyzer $stringTypeAnalyzer,
ValueResolver $valueResolver,
PhpDocInfoFactory $phpDocInfoFactory
) {
$this->nodeNameResolver = $nodeNameResolver;
$this->nodeTypeResolver = $nodeTypeResolver;
$this->valueResolver = $valueResolver;
$this->stringTypeAnalyzer = $stringTypeAnalyzer;
$this->nodesToRemoveCollector = $nodesToRemoveCollector;
$this->nodesToAddCollector = $nodesToAddCollector;
$this->phpDocInfoFactory = $phpDocInfoFactory;
}
/**
* @return StaticCall|MethodCall
*/
public function processStaticCall(StaticCall $staticCall): Expr
{
if ($this->nodeNameResolver->isNames($staticCall->name, ['truthy', 'falsey'])) {
return $this->processTruthyOrFalseyCall($staticCall);
}
if ($this->nodeNameResolver->isNames($staticCall->name, [self::CONTAINS, 'notContains'])) {
$this->processContainsCall($staticCall);
} elseif ($this->nodeNameResolver->isNames($staticCall->name, ['exception', 'throws'])) {
$this->processExceptionCall($staticCall);
} elseif ($this->nodeNameResolver->isName($staticCall->name, 'type')) {
$this->processTypeCall($staticCall);
} elseif ($this->nodeNameResolver->isName($staticCall->name, 'noError')) {
$this->processNoErrorCall($staticCall);
} else {
$this->renameAssertMethod($staticCall);
}
// self or class, depending on the context
// prefer $this->assertSame() as more conventional and explicit in class-context
if (! $this->sholdBeStaticCall($staticCall)) {
$methodCall = new MethodCall(new Variable(self::THIS), $staticCall->name);
$methodCall->args = $staticCall->args;
$methodCall->setAttributes($staticCall->getAttributes());
$methodCall->setAttribute(AttributeKey::ORIGINAL_NODE, null);
return $methodCall;
}
$staticCall->class = new FullyQualified('PHPUnit\Framework\Assert');
return $staticCall;
}
/**
* @return StaticCall|MethodCall
*/
private function processTruthyOrFalseyCall(StaticCall $staticCall): Expr
{
$method = $this->nodeNameResolver->isName($staticCall->name, 'truthy') ? 'assertTrue' : 'assertFalse';
if (! $this->sholdBeStaticCall($staticCall)) {
$call = new MethodCall(new Variable(self::THIS), $method);
$call->args = $staticCall->args;
$call->setAttributes($staticCall->getAttributes());
$call->setAttribute(AttributeKey::ORIGINAL_NODE, null);
} else {
$call = $staticCall;
$call->name = new Identifier($method);
}
if (! $this->nodeTypeResolver->isStaticType($staticCall->args[0]->value, BooleanType::class)) {
$call->args[0]->value = new Bool_($staticCall->args[0]->value);
}
return $call;
}
private function processContainsCall(StaticCall $staticCall): void
{
if ($this->stringTypeAnalyzer->isStringOrUnionStringOnlyType($staticCall->args[1]->value)) {
$name = $this->nodeNameResolver->isName(
$staticCall->name,
self::CONTAINS
) ? 'assertStringContainsString' : 'assertStringNotContainsString';
} else {
$name = $this->nodeNameResolver->isName(
$staticCall->name,
self::CONTAINS
) ? 'assertContains' : 'assertNotContains';
}
$staticCall->name = new Identifier($name);
}
private function processExceptionCall(StaticCall $staticCall): void
{
$method = 'expectException';
// expect exception
if ($this->sholdBeStaticCall($staticCall)) {
$expectException = new StaticCall(new Name(self::SELF), $method);
} else {
$expectException = new MethodCall(new Variable(self::THIS), $method);
}
$expectException->args[] = $staticCall->args[1];
$this->nodesToAddCollector->addNodeAfterNode($expectException, $staticCall);
// expect message
if (isset($staticCall->args[2])) {
$this->refactorExpectException($staticCall);
}
// expect code
if (isset($staticCall->args[3])) {
$this->refactorExpectExceptionCode($staticCall);
}
/** @var Closure $closure */
$closure = $staticCall->args[0]->value;
$this->nodesToAddCollector->addNodesAfterNode($closure->stmts, $staticCall);
$this->nodesToRemoveCollector->addNodeToRemove($staticCall);
}
private function processTypeCall(StaticCall $staticCall): void
{
$value = $this->valueResolver->getValue($staticCall->args[0]->value);
if (isset(self::TYPE_TO_METHOD[$value])) {
$staticCall->name = new Identifier(self::TYPE_TO_METHOD[$value]);
unset($staticCall->args[0]);
$staticCall->args = array_values($staticCall->args);
} elseif ($value === 'null') {
$staticCall->name = new Identifier('assertNull');
unset($staticCall->args[0]);
$staticCall->args = array_values($staticCall->args);
} else {
$staticCall->name = new Identifier('assertInstanceOf');
}
}
private function processNoErrorCall(StaticCall $staticCall): void
{
/** @var Closure $closure */
$closure = $staticCall->args[0]->value;
$this->nodesToAddCollector->addNodesAfterNode($closure->stmts, $staticCall);
$this->nodesToRemoveCollector->addNodeToRemove($staticCall);
$classMethod = $staticCall->getAttribute(AttributeKey::METHOD_NODE);
if (! $classMethod instanceof ClassMethod) {
return;
}
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($classMethod);
$phpDocInfo->addPhpDocTagNode(new PhpDocTagNode('@doesNotPerformAssertions', new GenericTagValueNode('')));
}
private function renameAssertMethod(StaticCall $staticCall): void
{
foreach (self::ASSERT_METHODS_REMAP as $oldMethod => $newMethod) {
if (! $this->nodeNameResolver->isName($staticCall->name, $oldMethod)) {
continue;
}
$staticCall->name = new Identifier($newMethod);
}
}
private function sholdBeStaticCall(StaticCall $staticCall): bool
{
return ! (bool) $staticCall->getAttribute(AttributeKey::CLASS_NODE);
}
private function refactorExpectException(StaticCall $staticCall): string
{
$method = 'expectExceptionMessage';
if ($this->sholdBeStaticCall($staticCall)) {
$expectExceptionMessage = new StaticCall(new Name(self::SELF), $method);
} else {
$expectExceptionMessage = new MethodCall(new Variable(self::THIS), $method);
}
$expectExceptionMessage->args[] = $staticCall->args[2];
$this->nodesToAddCollector->addNodeAfterNode($expectExceptionMessage, $staticCall);
return $method;
}
private function refactorExpectExceptionCode(StaticCall $staticCall): void
{
if ($this->sholdBeStaticCall($staticCall)) {
$expectExceptionCode = new StaticCall(new Name(self::SELF), 'expectExceptionCode');
} else {
$expectExceptionCode = new MethodCall(new Variable(self::THIS), 'expectExceptionCode');
}
$expectExceptionCode->args[] = $staticCall->args[3];
$this->nodesToAddCollector->addNodeAfterNode($expectExceptionCode, $staticCall);
}
}

View File

@ -1,135 +0,0 @@
<?php
declare(strict_types=1);
namespace Rector\NetteTesterToPHPUnit\Rector\Class_;
use PhpParser\Node;
use PhpParser\Node\Expr\Include_;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Name\FullyQualified;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\ClassLike;
use PHPStan\Type\ObjectType;
use Rector\Core\Rector\AbstractRector;
use Rector\Core\ValueObject\MethodName;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @see \Rector\Tests\NetteTesterToPHPUnit\Rector\Class_\NetteTesterClassToPHPUnitClassRector\NetteTesterClassToPHPUnitClassRectorTest
*/
final class NetteTesterClassToPHPUnitClassRector extends AbstractRector
{
public function getRuleDefinition(): RuleDefinition
{
return new RuleDefinition('Migrate Nette Tester test case to PHPUnit', [
new CodeSample(
<<<'CODE_SAMPLE'
namespace KdybyTests\Doctrine;
use Tester\TestCase;
use Tester\Assert;
require_once __DIR__ . '/../bootstrap.php';
class ExtensionTest extends TestCase
{
public function testFunctionality()
{
Assert::true($default instanceof Kdyby\Doctrine\EntityManager);
Assert::true(5);
Assert::same($container->getService('kdyby.doctrine.default.entityManager'), $default);
}
}
(new \ExtensionTest())->run();
CODE_SAMPLE
,
<<<'CODE_SAMPLE'
namespace KdybyTests\Doctrine;
use Tester\TestCase;
use Tester\Assert;
class ExtensionTest extends \PHPUnit\Framework\TestCase
{
public function testFunctionality()
{
$this->assertInstanceOf(\Kdyby\Doctrine\EntityManager::cllass, $default);
$this->assertTrue(5);
$this->same($container->getService('kdyby.doctrine.default.entityManager'), $default);
}
}
CODE_SAMPLE
),
]);
}
/**
* @return array<class-string<Node>>
*/
public function getNodeTypes(): array
{
return [Class_::class, Include_::class, MethodCall::class];
}
/**
* @param Class_|Include_|MethodCall $node
*/
public function refactor(Node $node): ?Node
{
if ($node instanceof Include_) {
$this->processAboveTestInclude($node);
return null;
}
if ($node instanceof MethodCall) {
$this->processUnderTestRun($node);
return null;
}
if (! $this->isObjectType($node, new ObjectType('Tester\TestCase'))) {
return null;
}
$this->processExtends($node);
$this->processMethods($node);
return $node;
}
private function processAboveTestInclude(Include_ $include): void
{
$classLike = $include->getAttribute(AttributeKey::CLASS_NODE);
if (! $classLike instanceof ClassLike) {
$this->removeNode($include);
}
}
private function processUnderTestRun(MethodCall $methodCall): void
{
if (! $this->isObjectType($methodCall->var, new ObjectType('Tester\TestCase'))) {
return;
}
if ($this->isName($methodCall->name, 'run')) {
$this->removeNode($methodCall);
}
}
private function processExtends(Class_ $class): void
{
$class->extends = new FullyQualified('PHPUnit\Framework\TestCase');
}
private function processMethods(Class_ $class): void
{
foreach ($class->getMethods() as $classMethod) {
if ($this->isNames($classMethod, [MethodName::SET_UP, MethodName::TEAR_DOWN])) {
$this->visibilityManipulator->makeProtected($classMethod);
}
}
}
}

View File

@ -1,106 +0,0 @@
<?php
declare(strict_types=1);
namespace Rector\NetteTesterToPHPUnit\Rector\Class_;
use Nette\Utils\Strings;
use PhpParser\Node;
use PhpParser\Node\Stmt\Class_;
use Rector\Core\Rector\AbstractRector;
use Rector\FileSystemRector\ValueObject\AddedFileWithContent;
use Rector\PSR4\FileInfoAnalyzer\FileInfoDeletionAnalyzer;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @see \Rector\Tests\NetteTesterToPHPUnit\Rector\Class_\RenameTesterTestToPHPUnitToTestFileRector\RenameTesterTestToPHPUnitToTestFileRectorTest
*/
final class RenameTesterTestToPHPUnitToTestFileRector extends AbstractRector
{
/**
* @var string
* @see https://regex101.com/r/ioamnE/1
*/
private const PHP_SUFFIX_REGEX = '#\.php$#';
/**
* @var string
* @see https://regex101.com/r/cOMZIj/1
*/
private const PHPT_SUFFIX_REGEX = '#\.phpt$#';
/**
* @var FileInfoDeletionAnalyzer
*/
private $fileInfoDeletionAnalyzer;
public function __construct(FileInfoDeletionAnalyzer $fileInfoDeletionAnalyzer)
{
$this->fileInfoDeletionAnalyzer = $fileInfoDeletionAnalyzer;
}
public function getRuleDefinition(): RuleDefinition
{
return new RuleDefinition('Rename "*.phpt" file to "*Test.php" file', [
new CodeSample(
<<<'CODE_SAMPLE'
// tests/SomeTestCase.phpt
CODE_SAMPLE
,
<<<'CODE_SAMPLE'
// tests/SomeTestCase.php
CODE_SAMPLE
),
]);
}
/**
* @return array<class-string<Node>>
*/
public function getNodeTypes(): array
{
return [Class_::class];
}
/**
* @param Class_ $node
*/
public function refactor(Node $node): ?Node
{
$smartFileInfo = $this->file->getSmartFileInfo();
$oldRealPath = $smartFileInfo->getRealPath();
if (! Strings::endsWith($oldRealPath, '.phpt')) {
return null;
}
$newRealPath = $this->createNewRealPath($oldRealPath);
if ($newRealPath === $oldRealPath) {
return null;
}
$this->removedAndAddedFilesCollector->removeFile($smartFileInfo);
$addedFileWithContent = new AddedFileWithContent($newRealPath, $smartFileInfo->getContents());
$this->removedAndAddedFilesCollector->addAddedFile($addedFileWithContent);
return null;
}
private function createNewRealPath(string $oldRealPath): string
{
// file suffix
$newRealPath = Strings::replace($oldRealPath, self::PHPT_SUFFIX_REGEX, '.php');
// cleanup tests prefix
$newRealPath = $this->fileInfoDeletionAnalyzer->clearNameFromTestingPrefix($newRealPath);
// Test suffix
if (! Strings::endsWith($newRealPath, 'Test.php')) {
return Strings::replace($newRealPath, self::PHP_SUFFIX_REGEX, 'Test.php');
}
return $newRealPath;
}
}

View File

@ -1,74 +0,0 @@
<?php
declare(strict_types=1);
namespace Rector\NetteTesterToPHPUnit\Rector\StaticCall;
use PhpParser\Node;
use PhpParser\Node\Expr\StaticCall;
use PHPStan\Type\ObjectType;
use Rector\Core\Rector\AbstractRector;
use Rector\NetteTesterToPHPUnit\AssertManipulator;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @see \Rector\Tests\NetteTesterToPHPUnit\Rector\Class_\NetteTesterClassToPHPUnitClassRector\NetteTesterClassToPHPUnitClassRectorTest
*/
final class NetteAssertToPHPUnitAssertRector extends AbstractRector
{
/**
* @var AssertManipulator
*/
private $assertManipulator;
public function __construct(AssertManipulator $assertManipulator)
{
$this->assertManipulator = $assertManipulator;
}
public function getRuleDefinition(): RuleDefinition
{
return new RuleDefinition('Migrate Nette/Assert calls to PHPUnit', [
new CodeSample(
<<<'CODE_SAMPLE'
use Tester\Assert;
function someStaticFunctions()
{
Assert::true(10 == 5);
}
CODE_SAMPLE
,
<<<'CODE_SAMPLE'
use Tester\Assert;
function someStaticFunctions()
{
\PHPUnit\Framework\Assert::assertTrue(10 == 5);
}
CODE_SAMPLE
),
]);
}
/**
* @return array<class-string<Node>>
*/
public function getNodeTypes(): array
{
return [StaticCall::class];
}
/**
* @param StaticCall $node
*/
public function refactor(Node $node): ?Node
{
if (! $this->isObjectType($node->class, new ObjectType('Tester\Assert'))) {
return null;
}
return $this->assertManipulator->processStaticCall($node);
}
}

View File

@ -1,114 +0,0 @@
<?php
declare(strict_types=1);
namespace Rector\NetteToSymfony\Collector;
use PhpParser\Node;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\NodeTraverser;
use PHPStan\Type\ObjectType;
use Rector\Core\PhpParser\Comparing\NodeComparator;
use Rector\NodeTypeResolver\NodeTypeResolver;
use Symplify\Astral\NodeTraverser\SimpleCallableNodeTraverser;
final class OnFormVariableMethodCallsCollector
{
/**
* @var SimpleCallableNodeTraverser
*/
private $simpleCallableNodeTraverser;
/**
* @var NodeTypeResolver
*/
private $nodeTypeResolver;
/**
* @var NodeComparator
*/
private $nodeComparator;
public function __construct(
SimpleCallableNodeTraverser $simpleCallableNodeTraverser,
NodeTypeResolver $nodeTypeResolver,
NodeComparator $nodeComparator
) {
$this->simpleCallableNodeTraverser = $simpleCallableNodeTraverser;
$this->nodeTypeResolver = $nodeTypeResolver;
$this->nodeComparator = $nodeComparator;
}
/**
* @return MethodCall[]
*/
public function collectFromClassMethod(ClassMethod $classMethod): array
{
$newFormVariable = $this->resolveNewFormVariable($classMethod);
if (! $newFormVariable instanceof Expr) {
return [];
}
return $this->collectOnFormVariableMethodCalls($classMethod, $newFormVariable);
}
/**
* Matches:
* $form = new Form;
*/
private function resolveNewFormVariable(ClassMethod $classMethod): ?Expr
{
$newFormVariable = null;
$this->simpleCallableNodeTraverser->traverseNodesWithCallable(
(array) $classMethod->getStmts(),
function (Node $node) use (&$newFormVariable): ?int {
if (! $node instanceof Assign) {
return null;
}
if (! $this->nodeTypeResolver->isObjectType(
$node->expr,
new ObjectType('Nette\Application\UI\Form')
)) {
return null;
}
$newFormVariable = $node->var;
return NodeTraverser::STOP_TRAVERSAL;
}
);
return $newFormVariable;
}
/**
* @return MethodCall[]
*/
private function collectOnFormVariableMethodCalls(ClassMethod $classMethod, Expr $expr): array
{
$onFormVariableMethodCalls = [];
$this->simpleCallableNodeTraverser->traverseNodesWithCallable(
(array) $classMethod->getStmts(),
function (Node $node) use ($expr, &$onFormVariableMethodCalls) {
if (! $node instanceof MethodCall) {
return null;
}
if (! $this->nodeComparator->areNodesEqual($node->var, $expr)) {
return null;
}
$onFormVariableMethodCalls[] = $node;
return null;
}
);
return $onFormVariableMethodCalls;
}
}

View File

@ -1,193 +0,0 @@
<?php
declare(strict_types=1);
namespace Rector\NetteToSymfony\NodeAnalyzer;
use PhpParser\Node;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\PropertyFetch;
use PhpParser\Node\FunctionLike;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Else_;
use PhpParser\Node\Stmt\If_;
use PhpParser\Node\Stmt\Return_;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
use Rector\Nette\NodeAnalyzer\ReturnAnalyzer;
use Rector\Nette\NodeAnalyzer\ThisTemplatePropertyFetchAnalyzer;
use Rector\NetteToSymfony\ValueObject\ClassMethodRender;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeNestingScope\ScopeNestingComparator;
use Rector\NodeNestingScope\ValueObject\ControlStructure;
use Symplify\Astral\NodeTraverser\SimpleCallableNodeTraverser;
final class ClassMethodRenderAnalyzer
{
/**
* @var Expr[]
*/
private $templateVariables = [];
/**
* @var Node[]
*/
private $nodesToRemove = [];
/**
* @var array<string, Assign[]>
*/
private $conditionalAssigns = [];
/**
* @var SimpleCallableNodeTraverser
*/
private $simpleCallableNodeTraverser;
/**
* @var NodeNameResolver
*/
private $nodeNameResolver;
/**
* @var Expr[]
*/
private $templateFileExprs = [];
/**
* @var ScopeNestingComparator
*/
private $scopeNestingComparator;
/**
* @var BetterNodeFinder
*/
private $betterNodeFinder;
/**
* @var ThisTemplatePropertyFetchAnalyzer
*/
private $thisTemplatePropertyFetchAnalyzer;
/**
* @var Return_|null
*/
private $lastReturn;
/**
* @var ReturnAnalyzer
*/
private $returnAnalyzer;
public function __construct(
SimpleCallableNodeTraverser $simpleCallableNodeTraverser,
NodeNameResolver $nodeNameResolver,
ScopeNestingComparator $scopeNestingComparator,
BetterNodeFinder $betterNodeFinder,
ThisTemplatePropertyFetchAnalyzer $thisTemplatePropertyFetchAnalyzer,
ReturnAnalyzer $returnAnalyzer
) {
$this->simpleCallableNodeTraverser = $simpleCallableNodeTraverser;
$this->nodeNameResolver = $nodeNameResolver;
$this->scopeNestingComparator = $scopeNestingComparator;
$this->betterNodeFinder = $betterNodeFinder;
$this->thisTemplatePropertyFetchAnalyzer = $thisTemplatePropertyFetchAnalyzer;
$this->returnAnalyzer = $returnAnalyzer;
}
public function collectFromClassMethod(ClassMethod $classMethod): ClassMethodRender
{
$this->templateFileExprs = [];
$this->templateVariables = [];
$this->nodesToRemove = [];
$this->conditionalAssigns = [];
$this->lastReturn = $this->returnAnalyzer->findLastClassMethodReturn($classMethod);
$this->simpleCallableNodeTraverser->traverseNodesWithCallable(
(array) $classMethod->stmts,
function (Node $node): void {
if ($node instanceof MethodCall) {
$this->collectTemplateFileExpr($node);
}
if ($node instanceof Assign) {
$this->collectVariableFromAssign($node);
}
}
);
return new ClassMethodRender(
$this->templateFileExprs,
$this->templateVariables,
$this->nodesToRemove,
$this->conditionalAssigns
);
}
private function collectTemplateFileExpr(MethodCall $methodCall): void
{
if (! $this->nodeNameResolver->isNames($methodCall->name, ['render', 'setFile'])) {
return;
}
$this->nodesToRemove[] = $methodCall;
if (! isset($methodCall->args[0])) {
return;
}
$this->templateFileExprs[] = $methodCall->args[0]->value;
}
private function collectVariableFromAssign(Assign $assign): void
{
// $this->template = x
if ($assign->var instanceof PropertyFetch) {
$propertyFetch = $assign->var;
if (! $this->thisTemplatePropertyFetchAnalyzer->isTemplatePropertyFetch($propertyFetch->var)) {
return;
}
$variableName = $this->nodeNameResolver->getName($propertyFetch);
$foundParent = $this->betterNodeFinder->findParentTypes(
$propertyFetch->var,
ControlStructure::CONDITIONAL_NODE_SCOPE_TYPES + [FunctionLike::class]
);
if ($foundParent && $this->scopeNestingComparator->isInBothIfElseBranch(
$foundParent,
$propertyFetch
)) {
$this->conditionalAssigns[$variableName][] = $assign;
return;
}
if ($foundParent instanceof If_) {
return;
}
if ($foundParent instanceof Else_) {
return;
}
// there is a return before this assign, to do not remove it and keep ti
if (! $this->returnAnalyzer->isBeforeLastReturn($assign, $this->lastReturn)) {
return;
}
$this->templateVariables[$variableName] = $assign->expr;
$this->nodesToRemove[] = $assign;
return;
}
// $x = $this->template
if (! $this->thisTemplatePropertyFetchAnalyzer->isTemplatePropertyFetch($assign->expr)) {
return;
}
$this->nodesToRemove[] = $assign;
}
}

View File

@ -1,53 +0,0 @@
<?php
declare(strict_types=1);
namespace Rector\NetteToSymfony\NodeAnalyzer;
use PhpParser\Node\Stmt\Interface_;
use PHPStan\Type\ObjectType;
use PHPStan\Type\TypeWithClassName;
use PHPStan\Type\UnionType;
use Rector\StaticTypeMapper\ValueObject\Type\ShortenedObjectType;
use Rector\TypeDeclaration\TypeInferer\ReturnTypeInferer;
final class NetteControlFactoryInterfaceAnalyzer
{
/**
* @var ReturnTypeInferer
*/
private $returnTypeInferer;
public function __construct(ReturnTypeInferer $returnTypeInferer)
{
$this->returnTypeInferer = $returnTypeInferer;
}
/**
* @see https://doc.nette.org/en/3.0/components#toc-components-with-dependencies
*/
public function isComponentFactoryInterface(Interface_ $interface): bool
{
foreach ($interface->getMethods() as $classMethod) {
$returnType = $this->returnTypeInferer->inferFunctionLike($classMethod);
if (! $returnType instanceof TypeWithClassName) {
return false;
}
$controlOrForm = new UnionType([
new ObjectType('Nette\Application\UI\Control'),
new ObjectType('Nette\Application\UI\Form'),
]);
if ($returnType instanceof ShortenedObjectType) {
$returnType = new ObjectType($returnType->getFullyQualifiedName());
}
if ($controlOrForm->isSuperTypeOf($returnType)->yes()) {
return true;
}
}
return false;
}
}

View File

@ -1,71 +0,0 @@
<?php
declare(strict_types=1);
namespace Rector\NetteToSymfony\NodeFactory;
use PhpParser\Node\Arg;
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\BinaryOp\BooleanAnd;
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 PhpParser\Node\Stmt\If_;
use Rector\Core\PhpParser\Node\NodeFactory;
final class ActionWithFormProcessClassMethodFactory
{
/**
* @var NodeFactory
*/
private $nodeFactory;
public function __construct(NodeFactory $nodeFactory)
{
$this->nodeFactory = $nodeFactory;
}
public function create(string $formTypeClass): ClassMethod
{
$classMethod = $this->nodeFactory->createPublicMethod('actionSomeForm');
$requestVariable = new Variable('request');
$classMethod->params[] = new Param($requestVariable, null, new FullyQualified(
'Symfony\Component\HttpFoundation\Request'
));
$classMethod->returnType = new FullyQualified('Symfony\Component\HttpFoundation\Response');
$formVariable = new Variable('form');
$assign = $this->createFormInstanceAssign($formTypeClass, $formVariable);
$classMethod->stmts[] = new Expression($assign);
$handleRequestMethodCall = new MethodCall($formVariable, 'handleRequest', [new Arg($requestVariable)]);
$classMethod->stmts[] = new Expression($handleRequestMethodCall);
$booleanAnd = $this->createFormIsSuccessAndIsValid($formVariable);
$classMethod->stmts[] = new If_($booleanAnd);
return $classMethod;
}
private function createFormInstanceAssign(string $formTypeClass, Variable $formVariable): Assign
{
$classConstFetch = $this->nodeFactory->createClassConstReference($formTypeClass);
$args = [new Arg($classConstFetch)];
$createFormMethodCall = new MethodCall(new Variable('this'), 'createForm', $args);
return new Assign($formVariable, $createFormMethodCall);
}
private function createFormIsSuccessAndIsValid(Variable $formVariable): BooleanAnd
{
$isSuccessMethodCall = new MethodCall($formVariable, 'isSuccess');
$isValidMethodCall = new MethodCall($formVariable, 'isValid');
return new BooleanAnd($isSuccessMethodCall, $isValidMethodCall);
}
}

View File

@ -1,36 +0,0 @@
<?php
declare(strict_types=1);
namespace Rector\NetteToSymfony\NodeFactory;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Identifier;
use PhpParser\Node\Name\FullyQualified;
use PhpParser\Node\Param;
use PhpParser\Node\Stmt\ClassMethod;
use Rector\Core\PhpParser\Node\NodeFactory;
final class BuildFormClassMethodFactory
{
/**
* @var NodeFactory
*/
private $nodeFactory;
public function __construct(NodeFactory $nodeFactory)
{
$this->nodeFactory = $nodeFactory;
}
public function create(Variable $formBuilderVariable): ClassMethod
{
$buildFormClassMethod = $this->nodeFactory->createPublicMethod('buildForm');
$buildFormClassMethod->params[] = new Param($formBuilderVariable, null, new FullyQualified(
'Symfony\Component\Form\FormBuilderInterface'
));
$buildFormClassMethod->params[] = new Param(new Variable('options'), null, new Identifier('array'));
return $buildFormClassMethod;
}
}

View File

@ -1,58 +0,0 @@
<?php
declare(strict_types=1);
namespace Rector\NetteToSymfony\NodeFactory;
use PhpParser\Node\Name;
use PhpParser\Node\Name\FullyQualified;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\Namespace_;
use PHPStan\Analyser\Scope;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
final class SymfonyControllerFactory
{
/**
* @var NodeNameResolver
*/
private $nodeNameResolver;
/**
* @var ActionWithFormProcessClassMethodFactory
*/
private $actionWithFormProcessClassMethodFactory;
public function __construct(
NodeNameResolver $nodeNameResolver,
ActionWithFormProcessClassMethodFactory $actionWithFormProcessClassMethodFactory
) {
$this->nodeNameResolver = $nodeNameResolver;
$this->actionWithFormProcessClassMethodFactory = $actionWithFormProcessClassMethodFactory;
}
public function createNamespace(Class_ $node, Class_ $formTypeClass): ?Namespace_
{
$scope = $node->getAttribute(AttributeKey::SCOPE);
if (! $scope instanceof Scope) {
return null;
}
/** @var string $namespaceName */
$namespaceName = $scope->getNamespace();
$formControllerClass = new Class_('SomeFormController');
$formControllerClass->extends = new FullyQualified(
'Symfony\Bundle\FrameworkBundle\Controller\AbstractController'
);
$formTypeClass = $namespaceName . '\\' . $this->nodeNameResolver->getName($formTypeClass);
$formControllerClass->stmts[] = $this->actionWithFormProcessClassMethodFactory->create($formTypeClass);
$namespace = new Namespace_(new Name($namespaceName));
$namespace->stmts[] = $formControllerClass;
return $namespace;
}
}

View File

@ -1,83 +0,0 @@
<?php
declare(strict_types=1);
namespace Rector\NetteToSymfony\NodeFactory;
use PhpParser\Node\Arg;
use PhpParser\Node\Expr\Array_;
use PhpParser\Node\Expr\ArrayItem;
use PhpParser\Node\Expr\ClassConstFetch;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Scalar\String_;
use PhpParser\Node\Stmt\Expression;
use Rector\Core\PhpParser\Node\NodeFactory;
use Rector\NodeNameResolver\NodeNameResolver;
use Symfony\Component\Form\Extension\Core\Type\TextType;
final class SymfonyMethodCallsFactory
{
/**
* @var NodeNameResolver
*/
private $nodeNameResolver;
/**
* @var NodeFactory
*/
private $nodeFactory;
public function __construct(NodeNameResolver $nodeNameResolver, NodeFactory $nodeFactory)
{
$this->nodeNameResolver = $nodeNameResolver;
$this->nodeFactory = $nodeFactory;
}
/**
* @param MethodCall[] $onFormVariableMethodCalls
* @return Expression[]
*/
public function create(array $onFormVariableMethodCalls, Variable $formBuilderVariable): array
{
$symfonyMethodCalls = [];
// create symfony form from nette form method calls
foreach ($onFormVariableMethodCalls as $onFormVariableMethodCall) {
if (! $this->nodeNameResolver->isName($onFormVariableMethodCall->name, 'addText')) {
continue;
}
// text input
$inputName = $onFormVariableMethodCall->args[0];
$formTypeClassConstant = $this->nodeFactory->createClassConstReference(TextType::class);
$args = $this->createAddTextArgs($inputName, $formTypeClassConstant, $onFormVariableMethodCall);
$methodCall = new MethodCall($formBuilderVariable, 'add', $args);
$symfonyMethodCalls[] = new Expression($methodCall);
}
return $symfonyMethodCalls;
}
/**
* @return Arg[]
*/
private function createAddTextArgs(
Arg $arg,
ClassConstFetch $classConstFetch,
MethodCall $onFormVariableMethodCall
): array {
$args = [$arg, new Arg($classConstFetch)];
if (isset($onFormVariableMethodCall->args[1])) {
$optionsArray = new Array_([
new ArrayItem($onFormVariableMethodCall->args[1]->value, new String_('label')),
]);
$args[] = new Arg($optionsArray);
}
return $args;
}
}

View File

@ -1,211 +0,0 @@
<?php
declare(strict_types=1);
namespace Rector\NetteToSymfony\Rector\ClassMethod;
use PhpParser\Node;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\Array_;
use PhpParser\Node\Expr\ArrayItem;
use PhpParser\Node\Expr\ClassConstFetch;
use PhpParser\Node\Name\FullyQualified;
use PhpParser\Node\Scalar\String_;
use PhpParser\Node\Stmt\ClassLike;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Return_;
use PHPStan\Type\ObjectType;
use Rector\Core\Rector\AbstractRector;
use Rector\NetteToSymfony\ValueObject\EventInfo;
use Rector\NetteToSymfony\ValueObjectFactory\EventInfosFactory;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @changelog https://symfony.com/doc/current/components/http_kernel.html#creating-an-event-listener
*
* @see \Rector\Tests\NetteToSymfony\Rector\ClassMethod\RenameEventNamesInEventSubscriberRector\RenameEventNamesInEventSubscriberRectorTest
*/
final class RenameEventNamesInEventSubscriberRector extends AbstractRector
{
/**
* @var EventInfo[]
*/
private $symfonyClassConstWithAliases = [];
public function __construct(EventInfosFactory $eventInfosFactory)
{
$this->symfonyClassConstWithAliases = $eventInfosFactory->create();
}
public function getRuleDefinition(): RuleDefinition
{
return new RuleDefinition(
'Changes event names from Nette ones to Symfony ones',
[
new CodeSample(
<<<'CODE_SAMPLE'
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
final class SomeClass implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
return ['nette.application' => 'someMethod'];
}
}
CODE_SAMPLE
,
<<<'CODE_SAMPLE'
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
final class SomeClass implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
return [\SymfonyEvents::KERNEL => 'someMethod'];
}
}
CODE_SAMPLE
),
]);
}
/**
* @return array<class-string<Node>>
*/
public function getNodeTypes(): array
{
return [ClassMethod::class];
}
/**
* @param ClassMethod $node
*/
public function refactor(Node $node): ?Node
{
$classLike = $node->getAttribute(AttributeKey::CLASS_NODE);
if (! $classLike instanceof ClassLike) {
return null;
}
if (! $this->isObjectType(
$classLike,
new ObjectType('Symfony\Component\EventDispatcher\EventSubscriberInterface')
)) {
return null;
}
if (! $this->isName($node, 'getSubscribedEvents')) {
return null;
}
/** @var Return_[] $returnNodes */
$returnNodes = $this->betterNodeFinder->findInstanceOf($node, Return_::class);
foreach ($returnNodes as $returnNode) {
if (! $returnNode->expr instanceof Array_) {
continue;
}
$this->renameArrayKeys($returnNode);
}
return $node;
}
private function renameArrayKeys(Return_ $return): void
{
if (! $return->expr instanceof Array_) {
return;
}
foreach ($return->expr->items as $arrayItem) {
if ($arrayItem === null) {
continue;
}
$eventInfo = $this->matchStringKeys($arrayItem);
if (! $eventInfo instanceof EventInfo) {
$eventInfo = $this->matchClassConstKeys($arrayItem);
}
if (! $eventInfo instanceof EventInfo) {
continue;
}
$arrayItem->key = new ClassConstFetch(new FullyQualified(
$eventInfo->getClass()
), $eventInfo->getConstant());
// method name
$className = (string) $return->getAttribute(AttributeKey::CLASS_NAME);
$methodName = (string) $this->valueResolver->getValue($arrayItem->value);
$this->processMethodArgument($className, $methodName, $eventInfo);
}
}
private function matchStringKeys(ArrayItem $arrayItem): ?EventInfo
{
if (! $arrayItem->key instanceof String_) {
return null;
}
foreach ($this->symfonyClassConstWithAliases as $symfonyClassConstWithAlias) {
foreach ($symfonyClassConstWithAlias->getOldStringAliases() as $netteStringName) {
if ($this->valueResolver->isValue($arrayItem->key, $netteStringName)) {
return $symfonyClassConstWithAlias;
}
}
}
return null;
}
private function matchClassConstKeys(ArrayItem $arrayItem): ?EventInfo
{
if (! $arrayItem->key instanceof ClassConstFetch) {
return null;
}
foreach ($this->symfonyClassConstWithAliases as $symfonyClassConstWithAlias) {
$isMatch = $this->resolveClassConstAliasMatch($arrayItem, $symfonyClassConstWithAlias);
if ($isMatch) {
return $symfonyClassConstWithAlias;
}
}
return null;
}
private function processMethodArgument(string $class, string $method, EventInfo $eventInfo): void
{
$classMethodNode = $this->nodeRepository->findClassMethod($class, $method);
if (! $classMethodNode instanceof ClassMethod) {
return;
}
if (count($classMethodNode->params) !== 1) {
return;
}
$classMethodNode->params[0]->type = new FullyQualified($eventInfo->getEventClass());
}
private function resolveClassConstAliasMatch(ArrayItem $arrayItem, EventInfo $eventInfo): bool
{
$classConstFetchNode = $arrayItem->key;
if (! $classConstFetchNode instanceof Expr) {
return false;
}
foreach ($eventInfo->getOldClassConstAliases() as $netteClassConst) {
if ($this->isName($classConstFetchNode, $netteClassConst)) {
return true;
}
}
return false;
}
}

View File

@ -1,342 +0,0 @@
<?php
declare(strict_types=1);
namespace Rector\NetteToSymfony\Rector\ClassMethod;
use Nette\Utils\Strings;
use PhpParser\Node;
use PhpParser\Node\Expr\ArrayDimFetch;
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\StaticCall;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\ClassMethod;
use PHPStan\Type\ObjectType;
use Rector\BetterPhpDocParser\PhpDoc\DoctrineAnnotationTagValueNode;
use Rector\BetterPhpDocParser\ValueObject\PhpDoc\DoctrineAnnotation\CurlyListNode;
use Rector\BetterPhpDocParser\ValueObjectFactory\PhpDocNode\Symfony\SymfonyRouteTagValueNodeFactory;
use Rector\Core\Rector\AbstractRector;
use Rector\NetteToSymfony\Route\RouteInfoFactory;
use Rector\NetteToSymfony\Routing\ExplicitRouteAnnotationDecorator;
use Rector\NetteToSymfony\ValueObject\RouteInfo;
use Rector\TypeDeclaration\TypeInferer\ReturnTypeInferer;
use Stringy\Stringy;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @changelog https://doc.nette.org/en/2.4/routing, https://symfony.com/doc/current/routing.html
*
* @see \Rector\Tests\NetteToSymfony\Rector\ClassMethod\RouterListToControllerAnnotationsRector\RouterListToControllerAnnotationsRectorTest
*/
final class RouterListToControllerAnnotationsRector extends AbstractRector
{
/**
* @var string
* @see https://regex101.com/r/qVlXk2/2
*/
private const ACTION_RENDER_NAME_MATCHING_REGEX = '#^(action|render)(?<short_action_name>.*?$)#sm';
/**
* @var RouteInfoFactory
*/
private $routeInfoFactory;
/**
* @var ReturnTypeInferer
*/
private $returnTypeInferer;
/**
* @var ExplicitRouteAnnotationDecorator
*/
private $explicitRouteAnnotationDecorator;
/**
* @var SymfonyRouteTagValueNodeFactory
*/
private $symfonyRouteTagValueNodeFactory;
/**
* @var ObjectType[]
*/
private $routerObjectTypes = [];
/**
* @var ObjectType
*/
private $routeListObjectType;
public function __construct(
ExplicitRouteAnnotationDecorator $explicitRouteAnnotationDecorator,
ReturnTypeInferer $returnTypeInferer,
RouteInfoFactory $routeInfoFactory,
SymfonyRouteTagValueNodeFactory $symfonyRouteTagValueNodeFactory
) {
$this->routeInfoFactory = $routeInfoFactory;
$this->returnTypeInferer = $returnTypeInferer;
$this->explicitRouteAnnotationDecorator = $explicitRouteAnnotationDecorator;
$this->symfonyRouteTagValueNodeFactory = $symfonyRouteTagValueNodeFactory;
$this->routerObjectTypes = [
new ObjectType('Nette\Application\IRouter'),
new ObjectType('Nette\Routing\Router'),
];
$this->routeListObjectType = new ObjectType('Nette\Application\Routers\RouteList');
}
public function getRuleDefinition(): RuleDefinition
{
return new RuleDefinition(
'Change new Route() from RouteFactory to @Route annotation above controller method',
[
new CodeSample(
<<<'CODE_SAMPLE'
final class RouterFactory
{
public function create(): RouteList
{
$routeList = new RouteList();
$routeList[] = new Route('some-path', SomePresenter::class);
return $routeList;
}
}
final class SomePresenter
{
public function run()
{
}
}
CODE_SAMPLE
,
<<<'CODE_SAMPLE'
final class RouterFactory
{
public function create(): RouteList
{
$routeList = new RouteList();
// case of single action controller, usually get() or __invoke() method
$routeList[] = new Route('some-path', SomePresenter::class);
return $routeList;
}
}
use Symfony\Component\Routing\Annotation\Route;
final class SomePresenter
{
/**
* @Route(path="some-path")
*/
public function run()
{
}
}
CODE_SAMPLE
),
]
);
}
/**
* List of nodes this class checks, classes that implement @see \PhpParser\Node
* @return array<class-string<Node>>
*/
public function getNodeTypes(): array
{
return [ClassMethod::class];
}
/**
* @param ClassMethod $node
*/
public function refactor(Node $node): ?Node
{
if ($node->stmts === []) {
return null;
}
$inferedReturnType = $this->returnTypeInferer->inferFunctionLike($node);
if (! $inferedReturnType->isSuperTypeOf($this->routeListObjectType)->yes()) {
return null;
}
$assignNodes = $this->resolveAssignRouteNodes($node);
if ($assignNodes === []) {
return null;
}
$routeInfos = $this->createRouteInfosFromAssignNodes($assignNodes);
/** @var RouteInfo $routeInfo */
foreach ($routeInfos as $routeInfo) {
$classMethod = $this->resolveControllerClassMethod($routeInfo);
if (! $classMethod instanceof ClassMethod) {
continue;
}
$symfonyRoutePhpDocTagValueNode = $this->createSymfonyRoutePhpDocTagValueNode($routeInfo);
$this->explicitRouteAnnotationDecorator->decorateClassMethodWithRouteAnnotation(
$classMethod,
$symfonyRoutePhpDocTagValueNode
);
}
// complete all other non-explicit methods, from "<presenter>/<action>"
$this->completeImplicitRoutes();
// remove routes
$this->removeNodes($assignNodes);
return null;
}
/**
* @return Assign[]
*/
private function resolveAssignRouteNodes(ClassMethod $classMethod): array
{
// look for <...>[] = IRoute<Type>
return $this->betterNodeFinder->find((array) $classMethod->stmts, function (Node $node): bool {
if (! $node instanceof Assign) {
return false;
}
// $routeList[] =
if (! $node->var instanceof ArrayDimFetch) {
return false;
}
if ($this->nodeTypeResolver->isObjectTypes($node->expr, $this->routerObjectTypes)) {
return true;
}
if ($node->expr instanceof StaticCall) {
// for custom static route factories
return $this->nodeTypeResolver->isObjectType($node->expr, new ObjectType('Nette\Application\IRouter'));
}
return false;
});
}
/**
* @param Assign[] $assignNodes
* @return RouteInfo[]
*/
private function createRouteInfosFromAssignNodes(array $assignNodes): array
{
$routeInfos = [];
// collect annotations and target controllers
foreach ($assignNodes as $assignNode) {
$routeNameToControllerMethod = $this->routeInfoFactory->createFromNode($assignNode->expr);
if (! $routeNameToControllerMethod instanceof RouteInfo) {
continue;
}
$routeInfos[] = $routeNameToControllerMethod;
}
return $routeInfos;
}
private function resolveControllerClassMethod(RouteInfo $routeInfo): ?ClassMethod
{
$classNode = $this->nodeRepository->findClass($routeInfo->getClass());
if (! $classNode instanceof Class_) {
return null;
}
return $classNode->getMethod($routeInfo->getMethod());
}
private function createSymfonyRoutePhpDocTagValueNode(RouteInfo $routeInfo): DoctrineAnnotationTagValueNode
{
$values = [
'path' => '"' . $routeInfo->getPath() . '"',
];
if ($routeInfo->getHttpMethods() !== []) {
$httpMethods = [];
foreach ($routeInfo->getHttpMethods() as $httpMethod) {
$httpMethods[] = '"' . $httpMethod . '"';
}
$values['methods'] = new CurlyListNode($httpMethods);
}
return $this->symfonyRouteTagValueNodeFactory->createFromItems($values);
}
private function completeImplicitRoutes(): void
{
$presenterClasses = $this->nodeRepository->findClassesBySuffix('Presenter');
foreach ($presenterClasses as $presenterClass) {
foreach ($presenterClass->getMethods() as $classMethod) {
if ($this->shouldSkipClassMethod($classMethod)) {
continue;
}
$path = $this->resolvePathFromClassAndMethodNodes($presenterClass, $classMethod);
$symfonyRoutePhpDocTagValueNode = $this->symfonyRouteTagValueNodeFactory->createFromItems([
'path' => '"' . $path . '"',
]);
$this->explicitRouteAnnotationDecorator->decorateClassMethodWithRouteAnnotation(
$classMethod,
$symfonyRoutePhpDocTagValueNode
);
}
}
}
private function shouldSkipClassMethod(ClassMethod $classMethod): bool
{
// not an action method
if (! $classMethod->isPublic()) {
return true;
}
if (! $this->isName($classMethod, '#^(render|action)#')) {
return true;
}
$hasRouteAnnotation = $classMethod->getAttribute(ExplicitRouteAnnotationDecorator::HAS_ROUTE_ANNOTATION);
if ($hasRouteAnnotation) {
return true;
}
// already has Route tag
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($classMethod);
return $phpDocInfo->hasByAnnotationClass('Symfony\Component\Routing\Annotation\Route');
}
private function resolvePathFromClassAndMethodNodes(Class_ $class, ClassMethod $classMethod): string
{
/** @var string $presenterName */
$presenterName = $this->getName($class);
/** @var string $presenterPart */
$presenterPart = Strings::after($presenterName, '\\', -1);
$presenterPart = Strings::substring($presenterPart, 0, -Strings::length('Presenter'));
$stringy = new Stringy($presenterPart);
$presenterPart = (string) $stringy->dasherize();
$match = (array) Strings::match($this->getName($classMethod), self::ACTION_RENDER_NAME_MATCHING_REGEX);
$actionPart = lcfirst($match['short_action_name']);
return $presenterPart . '/' . $actionPart;
}
}

View File

@ -1,205 +0,0 @@
<?php
declare(strict_types=1);
namespace Rector\NetteToSymfony\Rector\Class_;
use PhpParser\Node;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Name\FullyQualified;
use PhpParser\Node\Param;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Namespace_;
use PHPStan\Type\ObjectType;
use Rector\Core\Rector\AbstractRector;
use Rector\FileSystemRector\ValueObject\AddedFileWithNodes;
use Rector\NetteToSymfony\Collector\OnFormVariableMethodCallsCollector;
use Rector\NetteToSymfony\NodeFactory\BuildFormClassMethodFactory;
use Rector\NetteToSymfony\NodeFactory\SymfonyControllerFactory;
use Rector\NetteToSymfony\NodeFactory\SymfonyMethodCallsFactory;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\ExtraFileCodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @changelog https://symfony.com/doc/current/forms.html#creating-form-classes
*
* @see \Rector\Tests\NetteToSymfony\Rector\Class_\FormControlToControllerAndFormTypeRector\FormControlToControllerAndFormTypeRectorTest
*/
final class FormControlToControllerAndFormTypeRector extends AbstractRector
{
/**
* @var OnFormVariableMethodCallsCollector
*/
private $onFormVariableMethodCallsCollector;
/**
* @var SymfonyControllerFactory
*/
private $symfonyControllerFactory;
/**
* @var BuildFormClassMethodFactory
*/
private $buildFormClassMethodFactory;
/**
* @var SymfonyMethodCallsFactory
*/
private $symfonyMethodCallsFactory;
public function __construct(
OnFormVariableMethodCallsCollector $onFormVariableMethodCallsCollector,
SymfonyControllerFactory $symfonyControllerFactory,
BuildFormClassMethodFactory $buildFormClassMethodFactory,
SymfonyMethodCallsFactory $symfonyMethodCallsFactory
) {
$this->onFormVariableMethodCallsCollector = $onFormVariableMethodCallsCollector;
$this->symfonyControllerFactory = $symfonyControllerFactory;
$this->buildFormClassMethodFactory = $buildFormClassMethodFactory;
$this->symfonyMethodCallsFactory = $symfonyMethodCallsFactory;
}
public function getRuleDefinition(): RuleDefinition
{
return new RuleDefinition('Change Form that extends Control to Controller and decoupled FormType', [
new ExtraFileCodeSample(
<<<'CODE_SAMPLE'
use Nette\Application\UI\Form;
use Nette\Application\UI\Control;
class SomeForm extends Control
{
public function createComponentForm()
{
$form = new Form();
$form->addText('name', 'Your name');
$form->onSuccess[] = [$this, 'processForm'];
}
public function processForm(Form $form)
{
// process me
}
}
CODE_SAMPLE
,
<<<'CODE_SAMPLE'
class SomeFormController extends \Symfony\Bundle\FrameworkBundle\Controller\AbstractController
{
/**
* @Route(...)
*/
public function actionSomeForm(\Symfony\Component\HttpFoundation\Request $request): \Symfony\Component\HttpFoundation\Response
{
$form = $this->createForm(SomeFormType::class);
$form->handleRequest($request);
if ($form->isSuccess() && $form->isValid()) {
// process me
}
}
}
CODE_SAMPLE
,
<<<'CODE_SAMPLE'
<?php
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
class SomeFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $formBuilder, array $options)
{
$formBuilder->add('name', TextType::class, [
'label' => 'Your name'
]);
}
}
CODE_SAMPLE
),
]);
}
/**
* @return array<class-string<Node>>
*/
public function getNodeTypes(): array
{
return [Class_::class];
}
/**
* @param Class_ $node
*/
public function refactor(Node $node): ?Node
{
if (! $this->isObjectType($node, new ObjectType('Nette\Application\UI\Control'))) {
return null;
}
foreach ($node->getMethods() as $classMethod) {
if (! $this->isName($classMethod->name, 'createComponent*')) {
continue;
}
$formTypeClass = $this->collectFormMethodCallsAndCreateFormTypeClass($classMethod);
if (! $formTypeClass instanceof Class_) {
continue;
}
$symfonyControllerNamespace = $this->symfonyControllerFactory->createNamespace($node, $formTypeClass);
if (! $symfonyControllerNamespace instanceof Namespace_) {
continue;
}
$addedFileWithNodes = new AddedFileWithNodes('src/Controller/SomeFormController.php', [
$symfonyControllerNamespace,
]);
$this->removedAndAddedFilesCollector->addAddedFile($addedFileWithNodes);
return $formTypeClass;
}
return $node;
}
private function collectFormMethodCallsAndCreateFormTypeClass(ClassMethod $classMethod): ?Class_
{
$onFormVariableMethodCalls = $this->onFormVariableMethodCallsCollector->collectFromClassMethod(
$classMethod
);
if ($onFormVariableMethodCalls === []) {
return null;
}
$formBuilderVariable = new Variable('formBuilder');
// public function buildForm(\Symfony\Component\Form\FormBuilderInterface $formBuilder, array $options)
$buildFormClassMethod = $this->buildFormClassMethodFactory->create($formBuilderVariable);
$symfonyMethodCalls = $this->symfonyMethodCallsFactory->create(
$onFormVariableMethodCalls,
$formBuilderVariable
);
$buildFormClassMethod->stmts = $symfonyMethodCalls;
return $this->createFormTypeClassFromBuildFormClassMethod($buildFormClassMethod);
}
private function createFormTypeClassFromBuildFormClassMethod(ClassMethod $buildFormClassMethod): Class_
{
$formTypeClass = new Class_('SomeFormType');
$formTypeClass->extends = new FullyQualified('Symfony\Component\Form\AbstractType');
$formTypeClass->stmts[] = $buildFormClassMethod;
return $formTypeClass;
}
}

View File

@ -1,189 +0,0 @@
<?php
declare(strict_types=1);
namespace Rector\NetteToSymfony\Rector\Class_;
use PhpParser\Node;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\PropertyFetch;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Identifier;
use PhpParser\Node\Name\FullyQualified;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Return_;
use Rector\CodingStyle\Naming\ClassNaming;
use Rector\Core\Exception\ShouldNotHappenException;
use Rector\Core\Rector\AbstractRector;
use Rector\Core\ValueObject\PhpVersionFeature;
use Rector\Nette\NodeAnalyzer\NetteClassAnalyzer;
use Rector\Nette\NodeFactory\ActionRenderFactory;
use Rector\NetteToSymfony\NodeAnalyzer\ClassMethodRenderAnalyzer;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\StaticTypeMapper\ValueObject\Type\FullyQualifiedObjectType;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @changelog https://doc.nette.org/en/2.4/components https://symfony.com/doc/current/controller.html
*
* @see \Rector\Tests\NetteToSymfony\Rector\Class_\NetteControlToSymfonyControllerRector\NetteControlToSymfonyControllerRectorTest
*/
final class NetteControlToSymfonyControllerRector extends AbstractRector
{
/**
* @var ActionRenderFactory
*/
private $actionRenderFactory;
/**
* @var NetteClassAnalyzer
*/
private $netteClassAnalyzer;
/**
* @var ClassNaming
*/
private $classNaming;
/**
* @var ClassMethodRenderAnalyzer
*/
private $classMethodRenderAnalyzer;
public function __construct(
ActionRenderFactory $actionRenderFactory,
NetteClassAnalyzer $netteClassAnalyzer,
ClassNaming $classNaming,
ClassMethodRenderAnalyzer $classMethodRenderAnalyzer
) {
$this->actionRenderFactory = $actionRenderFactory;
$this->netteClassAnalyzer = $netteClassAnalyzer;
$this->classNaming = $classNaming;
$this->classMethodRenderAnalyzer = $classMethodRenderAnalyzer;
}
public function getRuleDefinition(): RuleDefinition
{
return new RuleDefinition(
'Migrate Nette Component to Symfony Controller',
[
new CodeSample(
<<<'CODE_SAMPLE'
use Nette\Application\UI\Control;
class SomeControl extends Control
{
public function render()
{
$this->template->param = 'some value';
$this->template->render(__DIR__ . '/poll.latte');
}
}
CODE_SAMPLE
,
<<<'CODE_SAMPLE'
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
class SomeController extends AbstractController
{
public function some(): Response
{
return $this->render(__DIR__ . '/poll.latte', ['param' => 'some value']);
}
}
CODE_SAMPLE
),
]);
}
/**
* @return array<class-string<Node>>
*/
public function getNodeTypes(): array
{
return [Class_::class];
}
/**
* @param Class_ $node
*/
public function refactor(Node $node): ?Node
{
if (! $this->netteClassAnalyzer->isInComponent($node)) {
return null;
}
$shortClassName = $this->nodeNameResolver->getShortName($node);
$shortClassName = $this->classNaming->replaceSuffix($shortClassName, 'Control', 'Controller');
$node->name = new Identifier($shortClassName);
$node->extends = new FullyQualified('Symfony\Bundle\FrameworkBundle\Controller\AbstractController');
$classMethod = $node->getMethod('render');
if ($classMethod !== null) {
$this->processRenderMethod($classMethod);
}
return $node;
}
private function processRenderMethod(ClassMethod $classMethod): void
{
$this->processGetPresenterGetSessionMethodCall($classMethod);
$classMethod->name = new Identifier('action');
$classMethodRender = $this->classMethodRenderAnalyzer->collectFromClassMethod($classMethod);
$methodCall = $this->actionRenderFactory->createThisRenderMethodCall($classMethodRender);
// add return in the end
$return = new Return_($methodCall);
$classMethod->stmts[] = $return;
if ($this->isAtLeastPhpVersion(PhpVersionFeature::SCALAR_TYPES)) {
$classMethod->returnType = new FullyQualified('Symfony\Component\HttpFoundation\Response');
}
$this->removeNodes($classMethodRender->getNodesToRemove());
}
private function processGetPresenterGetSessionMethodCall(ClassMethod $classMethod): void
{
$this->traverseNodesWithCallable((array) $classMethod->getStmts(), function (Node $node): ?MethodCall {
if (! $node instanceof MethodCall) {
return null;
}
if (! $this->isName($node->name, 'getSession')) {
return null;
}
if (! $node->var instanceof MethodCall) {
return null;
}
if (! $this->isName($node->var->name, 'getPresenter')) {
return null;
}
$node->var = new PropertyFetch(new Variable('this'), 'session');
$classLike = $node->getAttribute(AttributeKey::CLASS_NODE);
if (! $classLike instanceof Class_) {
throw new ShouldNotHappenException();
}
$this->addConstructorDependencyToClass(
$classLike,
new FullyQualifiedObjectType('Nette\Http\Session'),
'session'
);
return $node;
});
}
}

View File

@ -1,70 +0,0 @@
<?php
declare(strict_types=1);
namespace Rector\NetteToSymfony\Rector\Interface_;
use PhpParser\Node;
use PhpParser\Node\Stmt\Interface_;
use Rector\Core\Rector\AbstractRector;
use Rector\NetteToSymfony\NodeAnalyzer\NetteControlFactoryInterfaceAnalyzer;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @see \Rector\Tests\NetteToSymfony\Rector\Interface_\DeleteFactoryInterfaceRector\DeleteFactoryInterfaceFileSystemRectorTest
*/
final class DeleteFactoryInterfaceRector extends AbstractRector
{
/**
* @var NetteControlFactoryInterfaceAnalyzer
*/
private $netteControlFactoryInterfaceAnalyzer;
public function __construct(NetteControlFactoryInterfaceAnalyzer $netteControlFactoryInterfaceAnalyzer)
{
$this->netteControlFactoryInterfaceAnalyzer = $netteControlFactoryInterfaceAnalyzer;
}
public function getRuleDefinition(): RuleDefinition
{
return new RuleDefinition(
'Interface factories are not needed in Symfony. Clear constructor injection is used instead', [
new CodeSample(
<<<'CODE_SAMPLE'
interface SomeControlFactoryInterface
{
public function create();
}
CODE_SAMPLE
,
<<<'CODE_SAMPLE'
CODE_SAMPLE
),
]
);
}
/**
* @return array<class-string<Node>>
*/
public function getNodeTypes(): array
{
return [Interface_::class];
}
/**
* @param Interface_ $node
*/
public function refactor(Node $node): ?Node
{
if (! $this->netteControlFactoryInterfaceAnalyzer->isComponentFactoryInterface($node)) {
return null;
}
$smartFileInfo = $this->file->getSmartFileInfo();
$this->removedAndAddedFilesCollector->removeFile($smartFileInfo);
return null;
}
}

View File

@ -1,103 +0,0 @@
<?php
declare(strict_types=1);
namespace Rector\NetteToSymfony\Rector\MethodCall;
use PhpParser\Node;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\PropertyFetch;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Identifier;
use PHPStan\Type\ObjectType;
use Rector\Core\NodeManipulator\ClassMethodManipulator;
use Rector\Core\Rector\AbstractRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @changelog https://doc.nette.org/en/2.4/http-request-response https://github.com/symfony/symfony/blob/master/src/Symfony/Component/HttpFoundation/Request.php
*
* @see \Rector\Tests\NetteToSymfony\Rector\MethodCall\FromHttpRequestGetHeaderToHeadersGetRector\FromHttpRequestGetHeaderToHeadersGetRectorTest
*/
final class FromHttpRequestGetHeaderToHeadersGetRector extends AbstractRector
{
/**
* @var ClassMethodManipulator
*/
private $classMethodManipulator;
public function __construct(ClassMethodManipulator $classMethodManipulator)
{
$this->classMethodManipulator = $classMethodManipulator;
}
public function getRuleDefinition(): RuleDefinition
{
return new RuleDefinition(
'Changes getHeader() to $request->headers->get()',
[
new CodeSample(
<<<'CODE_SAMPLE'
use Nette\Request;
final class SomeController
{
public static function someAction(Request $request)
{
$header = $this->httpRequest->getHeader('x');
}
}
CODE_SAMPLE
,
<<<'CODE_SAMPLE'
use Nette\Request;
final class SomeController
{
public static function someAction(Request $request)
{
$header = $request->headers->get('x');
}
}
CODE_SAMPLE
),
]);
}
/**
* @return array<class-string<Node>>
*/
public function getNodeTypes(): array
{
return [MethodCall::class];
}
/**
* @param MethodCall $node
*/
public function refactor(Node $node): ?Node
{
if (! $this->isObjectType($node->var, new ObjectType('Nette\Http\Request'))) {
return null;
}
if (! $this->isName($node->name, 'getHeader')) {
return null;
}
$requestName = $this->classMethodManipulator->addMethodParameterIfMissing(
$node,
new ObjectType('Symfony\Component\HttpFoundation\Request'),
['request', 'symfonyRequest']
);
$variable = new Variable($requestName);
$headersPropertyFetch = new PropertyFetch($variable, 'headers');
$node->var = $headersPropertyFetch;
$node->name = new Identifier('get');
return $node;
}
}

View File

@ -1,85 +0,0 @@
<?php
declare(strict_types=1);
namespace Rector\NetteToSymfony\Rector\MethodCall;
use Nette\Application\Request;
use PhpParser\Node;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\PropertyFetch;
use PhpParser\Node\Identifier;
use PHPStan\Type\ObjectType;
use Rector\Core\Rector\AbstractRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @changelog https://doc.nette.org/en/2.4/http-request-response https://github.com/symfony/symfony/blob/master/src/Symfony/Component/HttpFoundation/Request.php
*
* @see \Rector\Tests\NetteToSymfony\Rector\MethodCall\FromRequestGetParameterToAttributesGetRector\FromRequestGetParameterToAttributesGetRectorTest
*/
final class FromRequestGetParameterToAttributesGetRector extends AbstractRector
{
public function getRuleDefinition(): RuleDefinition
{
return new RuleDefinition(
'Changes "getParameter()" to "attributes->get()" from Nette to Symfony',
[
new CodeSample(
<<<'CODE_SAMPLE'
use Nette\Request;
final class SomeController
{
public static function someAction(Request $request)
{
$value = $request->getParameter('abz');
}
}
CODE_SAMPLE
,
<<<'CODE_SAMPLE'
use Nette\Request;
final class SomeController
{
public static function someAction(Request $request)
{
$value = $request->attribute->get('abz');
}
}
CODE_SAMPLE
),
]);
}
/**
* @return array<class-string<Node>>
*/
public function getNodeTypes(): array
{
return [MethodCall::class];
}
/**
* @param MethodCall $node
*/
public function refactor(Node $node): ?Node
{
if (! $this->isObjectType($node->var, new ObjectType('Nette\Application\Request'))) {
return null;
}
if (! $this->isName($node->name, 'getParameter')) {
return null;
}
$requestAttributesPropertyFetch = new PropertyFetch($node->var, 'attributes');
$node->var = $requestAttributesPropertyFetch;
$node->name = new Identifier('get');
return $node;
}
}

View File

@ -1,207 +0,0 @@
<?php
declare(strict_types=1);
namespace Rector\NetteToSymfony\Rector\MethodCall;
use PhpParser\Node;
use PhpParser\Node\Arg;
use PhpParser\Node\Expr\Array_;
use PhpParser\Node\Expr\ArrayItem;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\New_;
use PhpParser\Node\Identifier;
use PhpParser\Node\Scalar\String_;
use PhpParser\Node\Stmt\ClassLike;
use PHPStan\Type\ObjectType;
use Rector\Core\Rector\AbstractRector;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @changelog https://doc.nette.org/en/2.4/forms https://symfony.com/doc/current/forms.html
*
* @see \Rector\Tests\NetteToSymfony\Rector\MethodCall\NetteFormToSymfonyFormRector\NetteFormToSymfonyFormRectorTest
*/
final class NetteFormToSymfonyFormRector extends AbstractRector
{
/**
* @var array<string, string>
*/
private const ADD_METHOD_TO_FORM_TYPE = [
'addText' => 'Symfony\Component\Form\Extension\Core\Type\TextType',
'addPassword' => 'Symfony\Component\Form\Extension\Core\Type\PasswordType',
'addTextArea' => 'Symfony\Component\Form\Extension\Core\Type\TextareaType',
'addEmail' => 'Symfony\Component\Form\Extension\Core\Type\EmailType',
'addInteger' => 'Symfony\Component\Form\Extension\Core\Type\IntegerType',
'addHidden' => 'Symfony\Component\Form\Extension\Core\Type\HiddenType',
// https://symfony.com/doc/current/reference/forms/types/checkbox.html
'addCheckbox' => 'Symfony\Component\Form\Extension\Core\Type\CheckboxType',
'addUpload' => 'Symfony\Component\Form\Extension\Core\Type\FileType',
'addImage' => 'Symfony\Component\Form\Extension\Core\Type\FileType',
'addMultiUpload' => 'Symfony\Component\Form\Extension\Core\Type\FileType',
// https://symfony.com/doc/current/reference/forms/types/choice.html#select-tag-checkboxes-or-radio-buttons
'addSelect' => 'Symfony\Component\Form\Extension\Core\Type\ChoiceType',
'addRadioList' => 'Symfony\Component\Form\Extension\Core\Type\ChoiceType',
'addCheckboxList' => 'Symfony\Component\Form\Extension\Core\Type\ChoiceType',
'addMultiSelect' => 'Symfony\Component\Form\Extension\Core\Type\ChoiceType',
'addSubmit' => 'Symfony\Component\Form\Extension\Core\Type\SubmitType',
'addButton' => 'Symfony\Component\Form\Extension\Core\Type\ButtonType',
];
public function getRuleDefinition(): RuleDefinition
{
return new RuleDefinition(
'Migrate Nette\Forms in Presenter to Symfony',
[
new CodeSample(
<<<'CODE_SAMPLE'
use Nette\Application\UI;
class SomePresenter extends UI\Presenter
{
public function someAction()
{
$form = new UI\Form;
$form->addText('name', 'Name:');
$form->addSubmit('login', 'Sign up');
}
}
CODE_SAMPLE
,
<<<'CODE_SAMPLE'
use Nette\Application\UI;
class SomePresenter extends UI\Presenter
{
public function someAction()
{
$form = $this->createFormBuilder();
$form->add('name', \Symfony\Component\Form\Extension\Core\Type\TextType::class, [
'label' => 'Name:'
]);
$form->add('login', \Symfony\Component\Form\Extension\Core\Type\SubmitType::class, [
'label' => 'Sign up'
]);
}
}
CODE_SAMPLE
),
]);
}
/**
* @return array<class-string<Node>>
*/
public function getNodeTypes(): array
{
return [New_::class, MethodCall::class];
}
/**
* @param New_|MethodCall $node
*/
public function refactor(Node $node): ?Node
{
$classLike = $node->getAttribute(AttributeKey::CLASS_NODE);
if (! $classLike instanceof ClassLike) {
return null;
}
if (! $this->isObjectType($classLike, new ObjectType('Nette\Application\IPresenter'))) {
return null;
}
if ($node instanceof New_) {
return $this->processNew($node);
}
/** @var MethodCall $node */
if (! $this->isObjectType($node->var, new ObjectType('Nette\Application\UI\Form'))) {
return null;
}
foreach (self::ADD_METHOD_TO_FORM_TYPE as $method => $classType) {
if (! $this->isName($node->name, $method)) {
continue;
}
$this->processAddMethod($node, $method, $classType);
}
return $node;
}
private function processNew(New_ $new): ?MethodCall
{
if (! $this->isName($new->class, 'Nette\Application\UI\Form')) {
return null;
}
return $this->nodeFactory->createMethodCall('this', 'createFormBuilder');
}
private function processAddMethod(MethodCall $methodCall, string $method, string $classType): void
{
$methodCall->name = new Identifier('add');
// remove unused params
if ($method === 'addText') {
unset($methodCall->args[3], $methodCall->args[4]);
}
// has label
$optionsArray = new Array_();
if (isset($methodCall->args[1])) {
$optionsArray->items[] = new ArrayItem($methodCall->args[1]->value, new String_('label'));
}
$this->addChoiceTypeOptions($method, $optionsArray);
$this->addMultiFileTypeOptions($method, $optionsArray);
$methodCall->args[1] = new Arg($this->nodeFactory->createClassConstReference($classType));
if ($optionsArray->items !== []) {
$methodCall->args[2] = new Arg($optionsArray);
}
}
private function addChoiceTypeOptions(string $method, Array_ $optionsArray): void
{
if ($method === 'addSelect') {
$expanded = false;
$multiple = false;
} elseif ($method === 'addRadioList') {
$expanded = true;
$multiple = false;
} elseif ($method === 'addCheckboxList') {
$expanded = true;
$multiple = true;
} elseif ($method === 'addMultiSelect') {
$expanded = false;
$multiple = true;
} else {
return;
}
$optionsArray->items[] = new ArrayItem(
$expanded ? $this->nodeFactory->createTrue() : $this->nodeFactory->createFalse(),
new String_('expanded')
);
$optionsArray->items[] = new ArrayItem(
$multiple ? $this->nodeFactory->createTrue() : $this->nodeFactory->createFalse(),
new String_('multiple')
);
}
private function addMultiFileTypeOptions(string $method, Array_ $optionsArray): void
{
if ($method !== 'addMultiUpload') {
return;
}
$optionsArray->items[] = new ArrayItem($this->nodeFactory->createTrue(), new String_('multiple'));
}
}

View File

@ -1,125 +0,0 @@
<?php
declare(strict_types=1);
namespace Rector\NetteToSymfony\Rector\MethodCall;
use Nette\Utils\Strings;
use PhpParser\Node;
use PhpParser\Node\Expr\Array_;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Scalar\String_;
use PHPStan\Type\ObjectType;
use Rector\Core\Rector\AbstractRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @changelog https://symfony.com/doc/current/components/translation/usage.html#message-placeholders
* @changelog https://github.com/Kdyby/Translation/blob/master/docs/en/index.md#placeholders
* https://github.com/Kdyby/Translation/blob/6b0721c767a7be7f15b2fb13c529bea8536230aa/src/Translator.php#L172
* @see \Rector\Tests\NetteToSymfony\Rector\MethodCall\WrapTransParameterNameRector\WrapTransParameterNameRectorTest
*/
final class WrapTransParameterNameRector extends AbstractRector
{
/**
* @var string
* @see https://regex101.com/r/b8boED/1
*/
private const BETWEEN_PERCENT_CHARS_REGEX = '#%(.*?)%#';
public function getRuleDefinition(): RuleDefinition
{
return new RuleDefinition(
'Adds %% to placeholder name of trans() method if missing',
[
new CodeSample(
<<<'CODE_SAMPLE'
use Symfony\Component\Translation\Translator;
final class SomeController
{
public function run()
{
$translator = new Translator('');
$translated = $translator->trans(
'Hello %name%',
['name' => $name]
);
}
}
CODE_SAMPLE
,
<<<'CODE_SAMPLE'
use Symfony\Component\Translation\Translator;
final class SomeController
{
public function run()
{
$translator = new Translator('');
$translated = $translator->trans(
'Hello %name%',
['%name%' => $name]
);
}
}
CODE_SAMPLE
),
]);
}
/**
* @return array<class-string<Node>>
*/
public function getNodeTypes(): array
{
return [MethodCall::class];
}
/**
* @param MethodCall $node
*/
public function refactor(Node $node): ?Node
{
if (! $this->isObjectType(
$node->var,
new ObjectType('Symfony\Component\Translation\TranslatorInterface')
)) {
return null;
}
if (! $this->isName($node->name, 'trans')) {
return null;
}
if (count($node->args) < 2) {
return null;
}
if (! $node->args[1]->value instanceof Array_) {
return null;
}
/** @var Array_ $parametersArrayNode */
$parametersArrayNode = $node->args[1]->value;
foreach ($parametersArrayNode->items as $arrayItem) {
if ($arrayItem === null) {
continue;
}
if (! $arrayItem->key instanceof String_) {
continue;
}
if (Strings::match($arrayItem->key->value, self::BETWEEN_PERCENT_CHARS_REGEX)) {
continue;
}
$arrayItem->key = new String_('%' . $arrayItem->key->value . '%');
}
return $node;
}
}

View File

@ -1,208 +0,0 @@
<?php
declare(strict_types=1);
namespace Rector\NetteToSymfony\Route;
use Nette\Utils\Strings;
use PhpParser\Node;
use PhpParser\Node\Expr\ClassConstFetch;
use PhpParser\Node\Expr\New_;
use PhpParser\Node\Expr\StaticCall;
use PhpParser\Node\Scalar\String_;
use PhpParser\Node\Stmt\Class_;
use PHPStan\Reflection\ReflectionProvider;
use Rector\Core\PhpParser\Node\Value\ValueResolver;
use Rector\NetteToSymfony\ValueObject\RouteInfo;
use Rector\NodeCollector\NodeCollector\NodeRepository;
use Rector\NodeNameResolver\NodeNameResolver;
final class RouteInfoFactory
{
/**
* @var NodeNameResolver
*/
private $nodeNameResolver;
/**
* @var ValueResolver
*/
private $valueResolver;
/**
* @var NodeRepository
*/
private $nodeRepository;
/**
* @var ReflectionProvider
*/
private $reflectionProvider;
public function __construct(
NodeNameResolver $nodeNameResolver,
NodeRepository $nodeRepository,
ValueResolver $valueResolver,
ReflectionProvider $reflectionProvider
) {
$this->nodeNameResolver = $nodeNameResolver;
$this->valueResolver = $valueResolver;
$this->nodeRepository = $nodeRepository;
$this->reflectionProvider = $reflectionProvider;
}
public function createFromNode(Node $node): ?RouteInfo
{
if ($node instanceof New_) {
if ($this->hasNoArg($node)) {
return null;
}
return $this->createRouteInfoFromArgs($node);
}
// Route::create()
if ($node instanceof StaticCall) {
if (! isset($node->args[0])) {
return null;
}
if (! isset($node->args[1])) {
return null;
}
if (! $this->nodeNameResolver->isNames($node->name, ['get', 'head', 'post', 'put', 'patch', 'delete'])) {
return null;
}
/** @var string $methodName */
$methodName = $this->nodeNameResolver->getName($node->name);
$uppercasedMethodName = strtoupper($methodName);
$methods = [];
if ($uppercasedMethodName !== null) {
$methods[] = $uppercasedMethodName;
}
return $this->createRouteInfoFromArgs($node, $methods);
}
return null;
}
private function hasNoArg(New_ $new): bool
{
if (! isset($new->args[0])) {
return true;
}
return ! isset($new->args[1]);
}
/**
* @param New_|StaticCall $node
* @param string[] $methods
*/
private function createRouteInfoFromArgs(Node $node, array $methods = []): ?RouteInfo
{
$pathArgument = $node->args[0]->value;
$routePath = $this->valueResolver->getValue($pathArgument);
// route path is needed
if ($routePath === null) {
return null;
}
if (! is_string($routePath)) {
return null;
}
$routePath = $this->normalizeArgumentWrappers($routePath);
$targetNode = $node->args[1]->value;
if ($targetNode instanceof ClassConstFetch) {
return $this->createForClassConstFetch($node, $methods, $routePath);
}
if ($targetNode instanceof String_) {
return $this->createForString($targetNode, $routePath);
}
return null;
}
private function normalizeArgumentWrappers(string $routePath): string
{
return str_replace(['<', '>'], ['{', '}'], $routePath);
}
/**
* @param New_|StaticCall $node
* @param string[] $methods
*/
private function createForClassConstFetch(Node $node, array $methods, string $routePath): ?RouteInfo
{
/** @var ClassConstFetch $controllerMethodNode */
$controllerMethodNode = $node->args[1]->value;
// SomePresenter::class
if ($this->nodeNameResolver->isName($controllerMethodNode->name, 'class')) {
$presenterClass = $this->nodeNameResolver->getName($controllerMethodNode->class);
if ($presenterClass === null) {
return null;
}
if (! $this->reflectionProvider->hasClass($presenterClass)) {
return null;
}
$classReflection = $this->reflectionProvider->getClass($presenterClass);
if ($classReflection->hasMethod('run')) {
return new RouteInfo($presenterClass, 'run', $routePath, $methods);
}
}
return null;
}
private function createForString(String_ $string, string $routePath): ?RouteInfo
{
$targetValue = $string->value;
if (! Strings::contains($targetValue, ':')) {
return null;
}
[$controller, $method] = explode(':', $targetValue);
// detect class by controller name?
// foreach all instance and try to match a name $controller . 'Presenter/Controller'
$class = $this->nodeRepository->findByShortName($controller . 'Presenter');
if (! $class instanceof Class_) {
$class = $this->nodeRepository->findByShortName($controller . 'Controller');
}
// unable to find here
if (! $class instanceof Class_) {
return null;
}
$controllerClass = $this->nodeNameResolver->getName($class);
if ($controllerClass === null) {
return null;
}
if (! $this->reflectionProvider->hasClass($controllerClass)) {
return null;
}
$controllerClassReflection = $this->reflectionProvider->getClass($controllerClass);
$renderMethodName = 'render' . ucfirst($method);
if ($controllerClassReflection->hasMethod($renderMethodName)) {
return new RouteInfo($controllerClass, $renderMethodName, $routePath, []);
}
$actionMethodName = 'action' . ucfirst($method);
if ($controllerClassReflection->hasMethod($actionMethodName)) {
return new RouteInfo($controllerClass, $actionMethodName, $routePath, []);
}
return null;
}
}

View File

@ -1,43 +0,0 @@
<?php
declare(strict_types=1);
namespace Rector\NetteToSymfony\Routing;
use PhpParser\Node\Stmt\ClassMethod;
use Rector\BetterPhpDocParser\PhpDoc\DoctrineAnnotationTagValueNode;
use Rector\BetterPhpDocParser\PhpDoc\SpacelessPhpDocTagNode;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
final class ExplicitRouteAnnotationDecorator
{
/**
* @var string
*/
public const HAS_ROUTE_ANNOTATION = 'has_route_annotation';
/**
* @var PhpDocInfoFactory
*/
private $phpDocInfoFactory;
public function __construct(PhpDocInfoFactory $phpDocInfoFactory)
{
$this->phpDocInfoFactory = $phpDocInfoFactory;
}
public function decorateClassMethodWithRouteAnnotation(
ClassMethod $classMethod,
DoctrineAnnotationTagValueNode $doctrineAnnotationTagValueNode
): void {
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($classMethod);
$spacelessPhpDocTagNode = new SpacelessPhpDocTagNode(
'@\Symfony\Component\Routing\Annotation\Route',
$doctrineAnnotationTagValueNode
);
$phpDocInfo->addPhpDocTagNode($spacelessPhpDocTagNode);
$classMethod->setAttribute(self::HAS_ROUTE_ANNOTATION, true);
}
}

View File

@ -1,104 +0,0 @@
<?php
declare(strict_types=1);
namespace Rector\NetteToSymfony;
use PhpParser\Node\Arg;
use PhpParser\Node\Expr\Array_;
use PhpParser\Node\Expr\ArrayItem;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Identifier;
use PhpParser\Node\Name\FullyQualified;
use PhpParser\Node\Param;
use PhpParser\Node\Scalar\String_;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\Expression;
use Rector\Core\PhpParser\Node\NodeFactory;
use Rector\NodeNameResolver\NodeNameResolver;
use Symfony\Component\Form\Extension\Core\Type\TextType;
final class SymfonyFormAbstractTypeFactory
{
/**
* @var NodeFactory
*/
private $nodeFactory;
/**
* @var NodeNameResolver
*/
private $nodeNameResolver;
public function __construct(NodeFactory $nodeFactory, NodeNameResolver $nodeNameResolver)
{
$this->nodeFactory = $nodeFactory;
$this->nodeNameResolver = $nodeNameResolver;
}
/**
* @api
* @param MethodCall[] $methodCalls
*/
public function createFromNetteFormMethodCalls(array $methodCalls): Class_
{
$formBuilderVariable = new Variable('formBuilder');
// public function buildForm(\Symfony\Component\Form\FormBuilderInterface $formBuilder, array $options)
$buildFormClassMethod = $this->nodeFactory->createPublicMethod('buildForm');
$buildFormClassMethod->params[] = new Param($formBuilderVariable, null, new FullyQualified(
'Symfony\Component\Form\FormBuilderInterface'
));
$buildFormClassMethod->params[] = new Param(new Variable('options'), null, new Identifier('array'));
$symfonyMethodCalls = $this->createBuildFormMethodCalls($methodCalls, $formBuilderVariable);
$buildFormClassMethod->stmts = $symfonyMethodCalls;
$formTypeClass = new Class_('SomeFormType');
$formTypeClass->extends = new FullyQualified('Symfony\Component\Form\AbstractType');
$formTypeClass->stmts[] = $buildFormClassMethod;
return $formTypeClass;
}
/**
* @param MethodCall[] $methodCalls
* @return Expression[]
*/
private function createBuildFormMethodCalls(array $methodCalls, Variable $formBuilderVariable): array
{
$buildFormMethodCalls = [];
// create symfony form from nette form method calls
foreach ($methodCalls as $methodCall) {
if ($this->nodeNameResolver->isName($methodCall->name, 'addText')) {
$optionsArray = $this->createOptionsArray($methodCall);
$formTypeClassConstant = $this->nodeFactory->createClassConstReference(TextType::class);
$args = [$methodCall->args[0], new Arg($formTypeClassConstant)];
if ($optionsArray instanceof Array_) {
$args[] = new Arg($optionsArray);
}
$methodCall = new MethodCall($formBuilderVariable, 'add', $args);
$buildFormMethodCalls[] = new Expression($methodCall);
}
}
return $buildFormMethodCalls;
}
private function createOptionsArray(MethodCall $methodCall): ?Array_
{
if (! isset($methodCall->args[1])) {
return null;
}
return new Array_([new ArrayItem($methodCall->args[1]->value, new String_('label'))]);
}
}

View File

@ -1,80 +0,0 @@
<?php
declare(strict_types=1);
namespace Rector\NetteToSymfony\ValueObject;
use PhpParser\Node;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\Assign;
use Rector\Nette\Contract\ValueObject\ParameterArrayInterface;
final class ClassMethodRender implements ParameterArrayInterface
{
/**
* @var Node[]
*/
private $nodesToRemove = [];
/**
* @var array<string, Expr>
*/
private $templateVariables = [];
/**
* @var array<string, Assign[]>
*/
private $conditionalAssigns = [];
/**
* @var Expr[]
*/
private $templateFileExprs = [];
/**
* @param Expr[] $templateFileExprs
* @param array<string, Expr> $templateVariables
* @param Node[] $nodesToRemove
* @param array<string, Assign[]> $conditionalAssigns
*/
public function __construct(
array $templateFileExprs,
array $templateVariables,
array $nodesToRemove,
array $conditionalAssigns
) {
$this->templateVariables = $templateVariables;
$this->nodesToRemove = $nodesToRemove;
$this->conditionalAssigns = $conditionalAssigns;
$this->templateFileExprs = $templateFileExprs;
}
/**
* @return array<string, Expr>
*/
public function getTemplateVariables(): array
{
return $this->templateVariables;
}
/**
* @return string[]
*/
public function getConditionalVariableNames(): array
{
return array_keys($this->conditionalAssigns);
}
/**
* @return Node[]
*/
public function getNodesToRemove(): array
{
return $this->nodesToRemove;
}
public function getFirstTemplateFileExpr(): ?Expr
{
return $this->templateFileExprs[0] ?? null;
}
}

View File

@ -1,82 +0,0 @@
<?php
declare(strict_types=1);
namespace Rector\NetteToSymfony\ValueObject;
final class EventInfo
{
/**
* @var string
*/
private $class;
/**
* @var string
*/
private $constant;
/**
* @var string
*/
private $eventClass;
/**
* @var string[]
*/
private $oldStringAliases = [];
/**
* @var string[]
*/
private $oldClassConstAliases = [];
/**
* @param string[] $oldStringAliases
* @param string[] $oldClassConstAliases
*/
public function __construct(
array $oldStringAliases,
array $oldClassConstAliases,
string $class,
string $constant,
string $eventClass
) {
$this->oldStringAliases = $oldStringAliases;
$this->oldClassConstAliases = $oldClassConstAliases;
$this->class = $class;
$this->constant = $constant;
$this->eventClass = $eventClass;
}
/**
* @return string[]
*/
public function getOldStringAliases(): array
{
return $this->oldStringAliases;
}
/**
* @return string[]
*/
public function getOldClassConstAliases(): array
{
return $this->oldClassConstAliases;
}
public function getClass(): string
{
return $this->class;
}
public function getConstant(): string
{
return $this->constant;
}
public function getEventClass(): string
{
return $this->eventClass;
}
}

View File

@ -1,62 +0,0 @@
<?php
declare(strict_types=1);
namespace Rector\NetteToSymfony\ValueObject;
final class RouteInfo
{
/**
* @var string
*/
private $class;
/**
* @var string
*/
private $method;
/**
* @var string
*/
private $path;
/**
* @var string[]
*/
private $httpMethods = [];
/**
* @param string[] $httpMethods
*/
public function __construct(string $class, string $method, string $path, array $httpMethods = [])
{
$this->class = $class;
$this->method = $method;
$this->path = $path;
$this->httpMethods = $httpMethods;
}
public function getClass(): string
{
return $this->class;
}
public function getMethod(): string
{
return $this->method;
}
public function getPath(): string
{
return $this->path;
}
/**
* @return string[]
*/
public function getHttpMethods(): array
{
return $this->httpMethods;
}
}

View File

@ -1,82 +0,0 @@
<?php
declare(strict_types=1);
namespace Rector\NetteToSymfony\ValueObjectFactory;
use Rector\NetteToSymfony\ValueObject\EventInfo;
final class EventInfosFactory
{
/**
* @return EventInfo[]
*/
public function create(): array
{
$eventInfos = [];
$eventInfos[] = new EventInfo(
['nette.application.startup', 'nette.application.request'],
[
'Contributte\Events\Extra\Event\Application\StartupEvent::NAME',
'Contributte\Events\Extra\Event\Application\RequestEvent::NAME',
'Contributte\Events\Extra\Event\Application\ApplicationEvents::ON_REQUEST',
'Contributte\Events\Extra\Event\Application\ApplicationEvents::ON_STARTUP',
],
'Symfony\Component\HttpKernel\KernelEvents',
'REQUEST',
'Symfony\Component\HttpKernel\Event\GetResponseEvent'
);
$eventInfos[] = new EventInfo(
['nette.application.startup', 'nette.application.request'],
[
'Contributte\Events\Extra\Event\Application\StartupEvent::NAME',
'Contributte\Events\Extra\Event\Application\RequestEvent::NAME',
'Contributte\Events\Extra\Event\Application\ApplicationEvents::ON_REQUEST',
'Contributte\Events\Extra\Event\Application\ApplicationEvents::ON_STARTUP',
],
'Symfony\Component\HttpKernel\KernelEvents',
'REQUEST',
'Symfony\Component\HttpKernel\Event\GetResponseEvent'
);
$eventInfos[] = new EventInfo(
['nette.application.presenter', 'nette.application.presenter.startup'],
[
'Contributte\Events\Extra\Event\Application\PresenterEvent::NAME',
'Contributte\Events\Extra\Event\Application\PresenterStartupEvent::NAME',
'Contributte\Events\Extra\Event\Application\PresenterShutdownEvent::NAME',
'Contributte\Events\Extra\Event\Application\ApplicationEvents::ON_PRESENTER_SHUTDOWN',
'Contributte\Events\Extra\Event\Application\ApplicationEvents::ON_PRESENTER_STARTUP',
'Contributte\Events\Extra\Event\Application\ApplicationEvents::ON_PRESENTER',
],
'Symfony\Component\HttpKernel\KernelEvents',
'CONTROLLER',
'Symfony\Component\HttpKernel\Event\FilterControllerEvent'
);
$eventInfos[] = new EventInfo(
['nette.application.error'],
[
'Contributte\Events\Extra\Event\Application\ErrorEvent::NAME',
'Contributte\Events\Extra\Event\Application\ApplicationEvents::ON_ERROR',
],
'Symfony\Component\HttpKernel\KernelEvents',
'EXCEPTION',
'Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent'
);
$eventInfos[] = new EventInfo(
['nette.application.response'],
[
'Contributte\Events\Extra\Event\Application\ResponseEvent::NAME',
'Contributte\Events\Extra\Event\Application\ApplicationEvents::ON_RESPONSE',
],
'Symfony\Component\HttpKernel\KernelEvents',
'RESPONSE',
'Symfony\Component\HttpKernel\Event\FilterResponseEvent'
);
return $eventInfos;
}
}

View File

@ -235,6 +235,11 @@ final class PhpFileProcessor implements FileProcessorInterface
$callback($file);
} catch (AnalysedCodeException $analysedCodeException) {
// inform about missing classes in tests
if (StaticPHPUnitEnvironment::isPHPUnitRun()) {
throw $analysedCodeException;
}
$this->notParsedFiles[] = $file;
$error = $this->errorFactory->createAutoloadError($analysedCodeException);
$file->addRectorError($error);