Skip to content

Commit

Permalink
Merge pull request #4711 from izayoi256/feature/proxy-regenerate
Browse files Browse the repository at this point in the history
Entity拡張時にオリジナルのファイルを優先して参照するよう変更
  • Loading branch information
Kiyotaka Oku committed Dec 18, 2020
2 parents 7b064c2 + eeb8bb8 commit ece7185
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 2 deletions.
27 changes: 25 additions & 2 deletions src/Eccube/Service/EntityProxyService.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,7 @@ public function generate($includesDirs, $excludeDirs, $outputDir, OutputInterfac
// プロキシファイルの生成
foreach ($targetEntities as $targetEntity) {
$traits = isset($addTraits[$targetEntity]) ? $addTraits[$targetEntity] : [];
$rc = new ClassReflection($targetEntity);
$fileName = str_replace('\\', '/', $rc->getFileName());
$fileName = $this->originalEntityPath($targetEntity);
$baseName = basename($fileName);
$entityTokens = Tokens::fromCode(file_get_contents($fileName));

Expand Down Expand Up @@ -115,6 +114,30 @@ public function generate($includesDirs, $excludeDirs, $outputDir, OutputInterfac
return $generatedFiles;
}

private function originalEntityPath(string $entityClassName): string
{
$projectDir = rtrim(str_replace('\\', '/', $this->container->getParameter('kernel.project_dir')), '/');
$originalPath = null;

if (preg_match('/\AEccube\\\\Entity\\\\(.+)\z/', $entityClassName, $matches)) {
$pathToEntity = str_replace('\\', '/', $matches[1]);
$originalPath = sprintf('%s/src/Eccube/Entity/%s.php', $projectDir, $pathToEntity);
} elseif (preg_match('/\ACustomize\\\\Entity\\\\(.+)\z/', $entityClassName, $matches)) {
$pathToEntity = str_replace('\\', '/', $matches[1]);
$originalPath = sprintf('%s/app/Customize/Entity/%s.php', $projectDir, $pathToEntity);
} elseif (preg_match('/\APlugin\\\\([^\\\\]+)\\\\Entity\\\\(.+)\z/', $entityClassName, $matches)) {
$pathToEntity = str_replace('\\', '/', $matches[2]);
$originalPath = sprintf('%s/app/Plugin/%s/Entity/%s.php', $projectDir, $matches[1], $pathToEntity);
}

if ($originalPath !== null && file_exists($originalPath)) {
return $originalPath;
}

$rc = new ClassReflection($entityClassName);
return str_replace('\\', '/', $rc->getFileName());
}

/**
* 複数のディレクトリセットをスキャンしてディレクトリセットごとのEntityとTraitのマッピングを返します.
*
Expand Down
49 changes: 49 additions & 0 deletions tests/Eccube/Tests/Service/EntityProxyServiceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use Eccube\Annotation\EntityExtension;
use Eccube\Service\EntityProxyService;
use PhpCsFixer\Tokenizer\CT;
use PhpCsFixer\Tokenizer\Token;
use PhpCsFixer\Tokenizer\Tokens;
use Eccube\Tests\EccubeTestCase;
use Symfony\Component\Finder\Finder;
Expand Down Expand Up @@ -84,6 +85,54 @@ public function testGenerate()
self::assertNotNull($sequence);
}

public function testGenerateFromOriginalFile()
{
$this->markTestSkipped();

$findSequence = static function (Tokens $tokens) {
return $tokens->findSequence([
[T_PRIVATE, 'private'],
[T_VARIABLE, '$hoge'],
]);
};

$this->entityProxyService->generate([__DIR__], [], $this->tempOutputDir);

$generatedFile = $this->tempOutputDir.'/src/Eccube/Entity/Product.php';
self::assertTrue(file_exists($generatedFile));

$tokens = Tokens::fromCode(file_get_contents($generatedFile));
// private $hoge;がないことを確認
self::assertNull($findSequence($tokens));

// private $hoge;を挿入
$additionalVariableTokens = [
new Token([T_WHITESPACE, PHP_EOL . ' ']),
new Token([T_PRIVATE, 'private']),
new Token([T_WHITESPACE, ' ']),
new Token([T_VARIABLE, '$hoge']),
new Token(';'),
new Token([T_WHITESPACE, PHP_EOL])
];

$classTokens = $tokens->findSequence([[T_CLASS], [T_STRING]]);
$classTokenEnd = $tokens->getNextTokenOfKind(array_keys($classTokens)[0], ['{']);
$tokens->insertAt($classTokenEnd + 1, $additionalVariableTokens);
$newCode = $tokens->generateCode();
$newTokens = Tokens::fromCode($newCode);

// private $hoge;が存在することを確認
self::assertNotNull($findSequence($newTokens));

// 再生成する
file_put_contents($generatedFile, $newCode);
$this->entityProxyService->generate([__DIR__], [], $this->tempOutputDir);
$regeneratedTokens = Tokens::fromCode(file_get_contents($generatedFile));

// private $hoge;が存在しないことを確認
self::assertNull($findSequence($regeneratedTokens));
}

public function testGenerateExcluded()
{
$this->entityProxyService->generate([__DIR__], [], $this->tempOutputDir);
Expand Down

0 comments on commit ece7185

Please sign in to comment.