Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TASK: Add SiteLanguageAwareInterface #3195

Merged
merged 1 commit into from
Oct 24, 2022
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
1 change: 1 addition & 0 deletions config/v12/typo3-120.php
Original file line number Diff line number Diff line change
Expand Up @@ -160,4 +160,5 @@
);
$rectorConfig->rule(\Ssch\TYPO3Rector\Rector\v12\v0\typo3\UseConfigArrayForTSFEPropertiesRector::class);
$rectorConfig->rule(\Ssch\TYPO3Rector\Rector\v12\v0\typo3\ReplacePageRepoOverlayFunctionRector::class);
$rectorConfig->rule(\Ssch\TYPO3Rector\Rector\v12\v0\typo3\ImplementSiteLanguageAwareInterfaceRector::class);
};
170 changes: 170 additions & 0 deletions src/Rector/v12/v0/typo3/ImplementSiteLanguageAwareInterfaceRector.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
<?php

declare(strict_types=1);

namespace Ssch\TYPO3Rector\Rector\v12\v0\typo3;

use PhpParser\Builder\Property;
use PhpParser\Node;
use PhpParser\Node\Name\FullyQualified;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Return_;
use PHPStan\Analyser\Scope;
use PHPStan\Reflection\ClassReflection;
use Rector\Core\Rector\AbstractScopeAwareRector;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;

/**
* @changelog https://docs.typo3.org/c/typo3/cms-core/master/en-us/Changelog/12.0/Deprecation-97435-UsageOfSiteLanguageAwareTraitToDenoteSiteLanguageAwareness.html
* @see \Ssch\TYPO3Rector\Tests\Rector\v12\v0\typo3\ImplementSiteLanguageAwareInterfaceRector\ImplementSiteLanguageAwareInterfaceRectorTest
*/
final class ImplementSiteLanguageAwareInterfaceRector extends AbstractScopeAwareRector
{
/**
* @return array<class-string<Node>>
*/
public function getNodeTypes(): array
{
return [Class_::class];
}

/**
* @param Class_ $node
*/
public function refactorWithScope(Node $node, Scope $scope): ?Node
{
$classHasChanged = false;

$classReflection = $scope->getClassReflection();
if (! $classReflection instanceof ClassReflection) {
return null;
}

foreach ($node->getTraitUses() as $traitUse) {
foreach ($traitUse->traits as $trait) {
if (! $this->isName($trait, 'TYPO3\CMS\Core\Site\SiteLanguageAwareTrait')) {
continue;
}

$this->removeNode($traitUse);
$classHasChanged = true;
}
}

// It was not working with the ClassReflection
$implementInterface = true;
foreach ($node->implements as $implement) {
if ($this->isName($implement, 'TYPO3\\CMS\\Core\\Site\\SiteLanguageAwareInterface')) {
$implementInterface = false;
}
}

if ($implementInterface) {
$node->implements[] = new FullyQualified('TYPO3\CMS\Core\Site\SiteLanguageAwareInterface');
$classHasChanged = true;
}

$siteLanguageName = new FullyQualified('TYPO3\CMS\Core\Site\Entity\SiteLanguage');

$hasSiteLanguageProperty = false;
$properties = $node->getProperties();
foreach ($properties as $property) {
if ($this->isName($property, 'siteLanguage')) {
$hasSiteLanguageProperty = true;
}
}

if (! $hasSiteLanguageProperty) {
$node->stmts[] = (new Property('siteLanguage'))
->makeProtected()
->setType($siteLanguageName)
->getNode();
$classHasChanged = true;
}

if (! $classReflection->hasMethod('setSiteLanguage')) {
$setterOfSiteLanguage = new ClassMethod(
'setSiteLanguage',
[
'flags' => Class_::MODIFIER_PUBLIC,
'stmts' => [
new Node\Stmt\Expression(
$this->nodeFactory->createPropertyAssignmentWithExpr(
'siteLanguage',
new Node\Expr\Variable('siteLanguage')
)
),
],
'params' => [new Node\Param(new Node\Expr\Variable('siteLanguage'), null, $siteLanguageName)],
]
);
$node->stmts[] = $setterOfSiteLanguage;
$classHasChanged = true;
}

if (! $classReflection->hasMethod('getSiteLanguage')) {
$getterOfSiteLanguage = new ClassMethod(
'getSiteLanguage',
[
'flags' => Class_::MODIFIER_PUBLIC,
'stmts' => [new Return_($this->nodeFactory->createPropertyFetch('this', 'siteLanguage'))],
'returnType' => $siteLanguageName,
]
);
$node->stmts[] = $getterOfSiteLanguage;
$classHasChanged = true;
}

if ($classHasChanged) {
// invoke re-print
$node->setAttribute(AttributeKey::ORIGINAL_NODE, null);

return $node;
}

return null;
}

/**
* @codeCoverageIgnore
*/
public function getRuleDefinition(): RuleDefinition
{
return new RuleDefinition('Implement SiteLanguageAwareInterface instead of using SiteLanguageAwareTrait', [
new CodeSample(
<<<'CODE_SAMPLE'
use TYPO3\CMS\Core\Site\SiteLanguageAwareTrait;

class MyClass
{
use SiteLanguageAwareTrait;
}
CODE_SAMPLE
,
<<<'CODE_SAMPLE'
use TYPO3\CMS\Core\Site\SiteLanguageAwareInterface;
use TYPO3\CMS\Core\Site\Entity\SiteLanguage;

class MyClass implements SiteLanguageAwareInterface
{

protected SiteLanguage $siteLanguage;

public function setSiteLanguage(SiteLanguage $siteLanguage)
{
$this->siteLanguage = $siteLanguage;
}

public function getSiteLanguage(): SiteLanguage
{
return $this->siteLanguage;
}
}
CODE_SAMPLE
),
]);
}
}
16 changes: 16 additions & 0 deletions stubs/TYPO3/CMS/Core/Site/SiteLanguageAwareInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

namespace TYPO3\CMS\Core\Site;

use TYPO3\CMS\Core\Site\Entity\SiteLanguage;

if (interface_exists('TYPO3\CMS\Core\Site\SiteLanguageAwareInterface')) {
return;
}

interface SiteLanguageAwareInterface
{
public function setSiteLanguage(SiteLanguage $siteLanguage);

public function getSiteLanguage(): SiteLanguage;
}
12 changes: 12 additions & 0 deletions stubs/TYPO3/CMS/Core/Site/SiteLanguageAwareTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

namespace TYPO3\CMS\Core\Site;

if (trait_exists('TYPO3\CMS\Core\Site\SiteLanguageAwareTrait')) {
return;
}

trait SiteLanguageAwareTrait
{

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

namespace Ssch\TYPO3Rector\Tests\Rector\v12\v0\typo3\ImplementSiteLanguageAwareInterfaceRector\Fixture;

use TYPO3\CMS\Core\Site\Entity\SiteLanguage;
use TYPO3\CMS\Core\Site\SiteLanguageAwareInterface;
use TYPO3\CMS\Core\Site\SiteLanguageAwareTrait;

class MyClassWithoutInterfaceButOtherMethods
{
public function setSiteLanguage(SiteLanguage $siteLanguage)
{
$this->siteLanguage = $siteLanguage;
}
public function getSiteLanguage(): SiteLanguage
{
return $this->siteLanguage;
}
}

?>
-----
<?php

namespace Ssch\TYPO3Rector\Tests\Rector\v12\v0\typo3\ImplementSiteLanguageAwareInterfaceRector\Fixture;

use TYPO3\CMS\Core\Site\Entity\SiteLanguage;
use TYPO3\CMS\Core\Site\SiteLanguageAwareInterface;
use TYPO3\CMS\Core\Site\SiteLanguageAwareTrait;

class MyClassWithoutInterfaceButOtherMethods implements SiteLanguageAwareInterface
{
public function setSiteLanguage(SiteLanguage $siteLanguage)
{
$this->siteLanguage = $siteLanguage;
}
public function getSiteLanguage(): SiteLanguage
{
return $this->siteLanguage;
}
protected SiteLanguage $siteLanguage;
}

?>
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

namespace Ssch\TYPO3Rector\Tests\Rector\v12\v0\typo3\ImplementSiteLanguageAwareInterfaceRector\Fixture;

use TYPO3\CMS\Core\Site\Entity\SiteLanguage;
use TYPO3\CMS\Core\Site\SiteLanguageAwareInterface;

class MyClassWithoutInterfaceButOtherMethods implements SiteLanguageAwareInterface
{
protected SiteLanguage $siteLanguage;

public function setSiteLanguage(SiteLanguage $siteLanguage)
{
$this->siteLanguage = $siteLanguage;
}
public function getSiteLanguage(): SiteLanguage
{
return $this->siteLanguage;
}
protected SiteLanguage $siteLanguage;
}

?>

Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

namespace Ssch\TYPO3Rector\Tests\Rector\v12\v0\typo3\ImplementSiteLanguageAwareInterfaceRector\Fixture;

use TYPO3\CMS\Core\Site\SiteLanguageAwareTrait;

class MyClassWithoutInterface
{
use SiteLanguageAwareTrait;
}

?>
-----
<?php

namespace Ssch\TYPO3Rector\Tests\Rector\v12\v0\typo3\ImplementSiteLanguageAwareInterfaceRector\Fixture;

use TYPO3\CMS\Core\Site\SiteLanguageAwareInterface;
use TYPO3\CMS\Core\Site\Entity\SiteLanguage;
use TYPO3\CMS\Core\Site\SiteLanguageAwareTrait;

class MyClassWithoutInterface implements SiteLanguageAwareInterface
{
protected SiteLanguage $siteLanguage;
public function setSiteLanguage(SiteLanguage $siteLanguage)
{
$this->siteLanguage = $siteLanguage;
}
public function getSiteLanguage(): SiteLanguage
{
return $this->siteLanguage;
}
}

?>
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php

namespace Ssch\TYPO3Rector\Tests\Rector\v12\v0\typo3\ImplementSiteLanguageAwareInterfaceRector\Fixture;

use TYPO3\CMS\Core\Site\Entity\SiteLanguage;
use TYPO3\CMS\Core\Site\SiteLanguageAwareInterface;
use TYPO3\CMS\Core\Site\SiteLanguageAwareTrait;

class MyClass implements SiteLanguageAwareInterface
{
use SiteLanguageAwareTrait;

protected SiteLanguage $siteLanguage;

public function setSiteLanguage(SiteLanguage $siteLanguage)
{
$this->siteLanguage = $siteLanguage;
}
public function getSiteLanguage(): SiteLanguage
{
return $this->siteLanguage;
}
}

?>
-----
<?php

namespace Ssch\TYPO3Rector\Tests\Rector\v12\v0\typo3\ImplementSiteLanguageAwareInterfaceRector\Fixture;

use TYPO3\CMS\Core\Site\Entity\SiteLanguage;
use TYPO3\CMS\Core\Site\SiteLanguageAwareInterface;
use TYPO3\CMS\Core\Site\SiteLanguageAwareTrait;

class MyClass implements SiteLanguageAwareInterface
{
protected SiteLanguage $siteLanguage;
public function setSiteLanguage(SiteLanguage $siteLanguage)
{
$this->siteLanguage = $siteLanguage;
}
public function getSiteLanguage(): SiteLanguage
{
return $this->siteLanguage;
}
}

?>
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

declare(strict_types=1);

namespace Ssch\TYPO3Rector\Tests\Rector\v12\v0\typo3\ImplementSiteLanguageAwareInterfaceRector;

use Iterator;
use Rector\Testing\PHPUnit\AbstractRectorTestCase;

final class ImplementSiteLanguageAwareInterfaceRectorTest extends AbstractRectorTestCase
{
/**
* @dataProvider provideData()
*/
public function test(string $filePath): void
{
$this->doTestFile($filePath);
}

/**
* @return Iterator<array<string>>
*/
public function provideData(): Iterator
{
return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture');
}

public function provideConfigFilePath(): string
{
return __DIR__ . '/config/configured_rule.php';
}
}
Loading