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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,6 @@ phpstan-dependencies.json
phpstan-paths.txt

# tests - travis
/laravel-dir
/laravel-dir

uuid-migration.json
6 changes: 0 additions & 6 deletions packages/BetterPhpDocParser/src/PhpDocInfo/PhpDocInfo.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
use Rector\BetterPhpDocParser\Attributes\Attribute\Attribute;
use Rector\BetterPhpDocParser\Attributes\Contract\Ast\AttributeAwareNodeInterface;
use Rector\DoctrinePhpDocParser\Ast\PhpDoc\Class_\EntityTagValueNode;
use Rector\DoctrinePhpDocParser\Ast\PhpDoc\Property_\ColumnTagValueNode;
use Rector\DoctrinePhpDocParser\Ast\PhpDoc\Property_\IdTagValueNode;
use Rector\DoctrinePhpDocParser\Ast\PhpDoc\Property_\JoinColumnTagValueNode;
use Rector\DoctrinePhpDocParser\Ast\PhpDoc\Property_\ManyToManyTagValueNode;
Expand Down Expand Up @@ -212,11 +211,6 @@ public function getDoctrineEntity(): ?EntityTagValueNode
return $this->getByType(EntityTagValueNode::class);
}

public function getDoctrineColumn(): ?ColumnTagValueNode
{
return $this->getByType(ColumnTagValueNode::class);
}

public function getDoctrineJoinColumnTagValueNode(): ?JoinColumnTagValueNode
{
return $this->getByType(JoinColumnTagValueNode::class);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php declare(strict_types=1);

namespace Rector\Doctrine\AbstarctRector;
namespace Rector\Doctrine\AbstractRector;

use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\Property;
Expand Down Expand Up @@ -32,25 +32,6 @@ protected function isDoctrineEntityClass(Class_ $class): bool
return $this->doctrineDocBlockResolver->isDoctrineEntityClass($class);
}

protected function isDoctrineEntityClassWithIdProperty(Class_ $class): bool
{
if (! $this->doctrineDocBlockResolver->isDoctrineEntityClass($class)) {
return false;
}

foreach ($class->stmts as $classStmt) {
if (! $classStmt instanceof Property) {
continue;
}

if ($this->doctrineDocBlockResolver->hasPropertyDoctrineIdTag($classStmt)) {
return true;
}
}

return false;
}

protected function getTargetEntity(Property $property): ?string
{
return $this->doctrineDocBlockResolver->getTargetEntity($property);
Expand Down
11 changes: 8 additions & 3 deletions packages/Doctrine/src/Collector/UuidMigrationDataCollector.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,16 @@ public function addClassAndProperty(string $class, string $property): void
$this->propertiesByClass[$class]['properties'][] = $property;
}

public function addClassToManyRelationProperty(string $class, string $property, string $tableName): void
{
public function addClassToManyRelationProperty(
string $class,
string $property,
string $currentTableName,
string $uuidTableName
): void {
$this->propertiesByClass[$class]['to_many_relations'][] = [
'property' => $property,
'table_name' => $tableName,
'current_table_name' => $currentTableName,
'uuid_table_name' => $uuidTableName,
];
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Rector\Doctrine\Extension;

use Nette\Utils\FileSystem;
use Nette\Utils\Json;
use Rector\Contract\Extension\FinishingExtensionInterface;
use Rector\Doctrine\Collector\UuidMigrationDataCollector;
Expand Down Expand Up @@ -41,6 +42,11 @@ public function run(): void

$jsonContent = Json::encode($data, Json::PRETTY);

$this->symfonyStyle->writeln($jsonContent);
$filePath = getcwd() . '/uuid-migration.json';
FileSystem::write($filePath, $jsonContent);

$this->symfonyStyle->warning(
'See freshly created "uuid-migration.json" file for changes on entities and further SQL migration steps'
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
use PHPStan\PhpDocParser\Ast\PhpDoc\VarTagValueNode;
use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
use Rector\BetterPhpDocParser\Attributes\Ast\PhpDoc\AttributeAwarePhpDocTagNode;
use Rector\Doctrine\Uuid\UuidTableNameResolver;
use Rector\Doctrine\Uuid\JoinTableNameResolver;
use Rector\Doctrine\ValueObject\DoctrineClass;
use Rector\DoctrinePhpDocParser\Ast\PhpDoc\Property_\ColumnTagValueNode;
use Rector\DoctrinePhpDocParser\Ast\PhpDoc\Property_\CustomIdGeneratorTagValueNode;
Expand All @@ -24,14 +24,14 @@ final class PhpDocTagNodeFactory
private $doctrineUuidGeneratorClass;

/**
* @var UuidTableNameResolver
* @var JoinTableNameResolver
*/
private $uuidTableNameResolver;
private $joinTableNameResolver;

public function __construct(string $doctrineUuidGeneratorClass, UuidTableNameResolver $uuidTableNameResolver)
public function __construct(string $doctrineUuidGeneratorClass, JoinTableNameResolver $joinTableNameResolver)
{
$this->doctrineUuidGeneratorClass = $doctrineUuidGeneratorClass;
$this->uuidTableNameResolver = $uuidTableNameResolver;
$this->joinTableNameResolver = $joinTableNameResolver;
}

public function createVarTagUuidInterface(): PhpDocTagNode
Expand Down Expand Up @@ -78,9 +78,10 @@ public function createCustomIdGeneratorTag(): PhpDocTagNode

public function createJoinTableTagNode(Property $property): PhpDocTagNode
{
$joinTableName = $this->uuidTableNameResolver->resolveManyToManyTableNameForProperty($property);
$joinTableName = $this->joinTableNameResolver->resolveManyToManyTableNameForProperty($property);
$uuidJoinTable = $joinTableName . '_uuid';

$joinTableTagValueNode = new JoinTableTagValueNode($joinTableName, null, [
$joinTableTagValueNode = new JoinTableTagValueNode($uuidJoinTable, null, [
new JoinColumnTagValueNode(null, 'uuid'),
], [new JoinColumnTagValueNode(null, 'uuid')]);

Expand Down
22 changes: 21 additions & 1 deletion packages/Doctrine/src/PhpDocParser/DoctrineDocBlockResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\Property;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
use Rector\DoctrinePhpDocParser\Ast\PhpDoc\Property_\ColumnTagValueNode;
use Rector\DoctrinePhpDocParser\Ast\PhpDoc\Property_\TableTagValueNode;
use Rector\DoctrinePhpDocParser\Contract\Ast\PhpDoc\DoctrineRelationTagValueNodeInterface;
use Rector\NodeTypeResolver\PhpDoc\NodeAnalyzer\DocBlockManipulator;
Expand All @@ -32,6 +33,25 @@ public function isDoctrineEntityClass(Class_ $class): bool
return (bool) $classPhpDocInfo->getDoctrineEntity();
}

public function isDoctrineEntityClassWithIdProperty(Class_ $class): bool
{
if (! $this->isDoctrineEntityClass($class)) {
return false;
}

foreach ($class->stmts as $classStmt) {
if (! $classStmt instanceof Property) {
continue;
}

if ($this->hasPropertyDoctrineIdTag($classStmt)) {
return true;
}
}

return false;
}

public function getTargetEntity(Property $property): ?string
{
$doctrineRelationTagValueNode = $this->getDoctrineRelationTagValueNode($property);
Expand Down Expand Up @@ -79,7 +99,7 @@ public function isDoctrineProperty(Property $property): bool
return false;
}

if ($propertyPhpDocInfo->getDoctrineColumn()) {
if ($propertyPhpDocInfo->getByType(ColumnTagValueNode::class)) {
return true;
}

Expand Down
131 changes: 131 additions & 0 deletions packages/Doctrine/src/Provider/EntityWithMissingUuidProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
<?php declare(strict_types=1);

namespace Rector\Doctrine\Provider;

use Nette\Utils\Strings;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\Property;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
use Rector\Doctrine\PhpDocParser\DoctrineDocBlockResolver;
use Rector\DoctrinePhpDocParser\Ast\PhpDoc\Property_\ColumnTagValueNode;
use Rector\NodeContainer\ParsedNodesByType;
use Rector\PhpParser\Node\Manipulator\ClassManipulator;
use Rector\PhpParser\Node\Resolver\NameResolver;

final class EntityWithMissingUuidProvider
{
/**
* @var ParsedNodesByType
*/
private $parsedNodesByType;

/**
* @var DoctrineDocBlockResolver
*/
private $doctrineDocBlockResolver;

/**
* @var ClassManipulator
*/
private $classManipulator;

/**
* @var NameResolver
*/
private $nameResolver;

/**
* @var PhpDocInfoFactory
*/
private $phpDocInfoFactory;

/**
* @var Class_[]
*/
private $entitiesWithMissingUuidProperty = [];

public function __construct(
ParsedNodesByType $parsedNodesByType,
DoctrineDocBlockResolver $doctrineDocBlockResolver,
ClassManipulator $classManipulator,
NameResolver $nameResolver,
PhpDocInfoFactory $phpDocInfoFactory
) {
$this->parsedNodesByType = $parsedNodesByType;
$this->doctrineDocBlockResolver = $doctrineDocBlockResolver;
$this->classManipulator = $classManipulator;
$this->nameResolver = $nameResolver;
$this->phpDocInfoFactory = $phpDocInfoFactory;
}

/**
* @return Class_[]
*/
public function provide(): array
{
if ($this->entitiesWithMissingUuidProperty !== [] && ! defined('RECTOR_REPOSITORY')) {
return $this->entitiesWithMissingUuidProperty;
}

$entitiesWithMissingUuidProperty = [];
foreach ($this->parsedNodesByType->getClasses() as $class) {
if (! $this->doctrineDocBlockResolver->isDoctrineEntityClassWithIdProperty($class)) {
continue;
}

// already has $uuid property
if ($this->classManipulator->getProperty($class, 'uuid')) {
continue;
}

if ($this->hasClassIdPropertyWithUuidType($class)) {
continue;
}

$entitiesWithMissingUuidProperty[] = $class;
}

$this->entitiesWithMissingUuidProperty = $entitiesWithMissingUuidProperty;

return $entitiesWithMissingUuidProperty;
}

private function hasClassIdPropertyWithUuidType(Class_ $class): bool
{
foreach ($class->stmts as $classStmt) {
if (! $classStmt instanceof Property) {
continue;
}

if (! $this->nameResolver->isName($classStmt, 'id')) {
continue;
}

return $this->isPropertyClassIdWithUuidType($classStmt);
}

return false;
}

private function isPropertyClassIdWithUuidType(Property $property): bool
{
$propertyPhpDocInfo = $this->phpDocInfoFactory->createFromNode($property);

$idTagValueNode = $propertyPhpDocInfo->getDoctrineId();
if ($idTagValueNode === null) {
return false;
}

/** @var ColumnTagValueNode|null $columnTagValueNode */
$columnTagValueNode = $propertyPhpDocInfo->getByType(ColumnTagValueNode::class);
if ($columnTagValueNode === null) {
return false;
}

if ($columnTagValueNode->getType() === null) {
return false;
}

return (bool) Strings::match($columnTagValueNode->getType(), '#^uuid(_binary)?$#');
}
}
Loading