Skip to content

Commit

Permalink
[TASK] Refactor method fileResource of ContentObjectRenderer (#1589)
Browse files Browse the repository at this point in the history
Resolves: #662
  • Loading branch information
sabbelasichon authored Nov 11, 2020
1 parent acfba55 commit c4fcbf4
Show file tree
Hide file tree
Showing 7 changed files with 285 additions and 26 deletions.
159 changes: 159 additions & 0 deletions src/Rector/v8/v5/ContentObjectRendererFileResourceRector.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
<?php

declare(strict_types=1);

namespace Ssch\TYPO3Rector\Rector\v8\v5;

use PhpParser\Node;
use PhpParser\Node\Expr\ArrayDimFetch;
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\BinaryOp\BooleanAnd;
use PhpParser\Node\Expr\BinaryOp\NotIdentical;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\PropertyFetch;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Scalar\String_;
use PhpParser\Node\Stmt\Expression;
use PhpParser\Node\Stmt\If_;
use Rector\Core\Rector\AbstractRector;
use Rector\Core\RectorDefinition\CodeSample;
use Rector\Core\RectorDefinition\RectorDefinition;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Ssch\TYPO3Rector\Helper\Typo3NodeResolver;
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;

/**
* @see https://docs.typo3.org/c/typo3/cms-core/master/en-us/Changelog/8.5/Deprecation-77524-DeprecatedMethodFileResourceOfContentObjectRenderer.html
*/
final class ContentObjectRendererFileResourceRector extends AbstractRector
{
/**
* @var string
*/
private const PATH = 'path';

/**
* @var Typo3NodeResolver
*/
private $typo3NodeResolver;

public function __construct(Typo3NodeResolver $typo3NodeResolver)
{
$this->typo3NodeResolver = $typo3NodeResolver;
}

public function getNodeTypes(): array
{
return [MethodCall::class];
}

/**
* @param MethodCall $node
*/
public function refactor(Node $node): ?Node
{
if ($this->shouldSkip($node)) {
return null;
}

if (! $this->isName($node->name, 'fileResource')) {
return null;
}

$parentNode = $node->getAttribute(AttributeKey::PARENT_NODE);

if (! $parentNode instanceof Assign) {
return null;
}

$this->addInitializeVariableNode($node);
$this->addTypoScriptFrontendControllerAssignmentNode($node);
$this->addFileNameNode($node);
$this->addIfNode($node);

$this->removeNode($parentNode);

return null;
}

/**
* @codeCoverageIgnore
*/
public function getDefinition(): RectorDefinition
{
return new RectorDefinition('Migrate fileResource method of class ContentObjectRenderer', [
new CodeSample(<<<'PHP'
$template = $this->cObj->fileResource('EXT:vendor/Resources/Private/Templates/Template.html');
PHP
, <<<'PHP'
$path = $GLOBALS['TSFE']->tmpl->getFileName('EXT:vendor/Resources/Private/Templates/Template.html');
if ($path !== null && file_exists($path)) {
$template = file_get_contents($path);
}
PHP
),
]);
}

private function shouldSkip(MethodCall $node): bool
{
if ($this->isObjectType($node->var, ContentObjectRenderer::class)) {
return false;
}
return ! $this->typo3NodeResolver->isMethodCallOnPropertyOfGlobals(
$node,
Typo3NodeResolver::TYPO_SCRIPT_FRONTEND_CONTROLLER,
'cObj'
);
}

private function addInitializeVariableNode(MethodCall $node): void
{
$parentNode = $node->getAttribute('parent');
if (! $parentNode->var instanceof PropertyFetch) {
$initializeVariable = new Expression(new Assign($parentNode->var, new String_('')));
$this->addNodeBeforeNode($initializeVariable, $node);
}
}

private function addTypoScriptFrontendControllerAssignmentNode(MethodCall $node): void
{
$typoscriptFrontendControllerVariable = new Variable('typoscriptFrontendController');
$typoscriptFrontendControllerNode = new Assign(
$typoscriptFrontendControllerVariable,
new ArrayDimFetch(new Variable('GLOBALS'), new String_('TSFE'))
);
$this->addNodeBeforeNode($typoscriptFrontendControllerNode, $node);
}

private function addFileNameNode(MethodCall $node): void
{
$fileNameNode = new Assign(
new Variable(self::PATH),
$this->createMethodCall(
$this->createPropertyFetch(new Variable('typoscriptFrontendController'), 'tmpl'),
'getFileName',
$node->args
)
);
$this->addNodeBeforeNode($fileNameNode, $node);
}

private function addIfNode(MethodCall $node): void
{
$parentNode = $node->getAttribute(AttributeKey::PARENT_NODE);

$ifNode = new If_(new BooleanAnd(
new NotIdentical(new Variable(self::PATH), $this->createNull()),
$this->createFuncCall('file_exists', [new Variable(self::PATH)])
));

$templateAssignment = new Assign($parentNode->var, $this->createFuncCall(
'file_get_contents',
[new Variable(self::PATH)]
));
$ifNode->stmts[] = new Expression($templateAssignment);

$this->addNodeBeforeNode($ifNode, $node);
}
}
6 changes: 5 additions & 1 deletion stubs/Core/TypoScript/TemplateService.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,12 @@
class TemplateService
{
/**
* Passed to TypoScript template class and tells it to force template rendering
* @var bool
*/
public $forceTemplateParsing = false;

public function getFileName($file): void
{

}
}
24 changes: 8 additions & 16 deletions stubs/Frontend/ContentObject/ContentObjectRenderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,14 @@ final class ContentObjectRenderer
{
public function RECORDS(array $config): void
{
$this->cObjGetSingle('RECORDS', $config);
}

public function cObjGetSingle(string $string, array $config): void
{
}

public function enableFields($table, $show_hidden = false, array $ignore_array = [])
public function enableFields($table, $show_hidden = false, array $ignore_array = []): void
{
return GeneralUtility::makeInstance(PageRepository::class)->enableFields($table, $show_hidden ? true : -1, $ignore_array);
}

public function getSubpart($content, $marker): void
Expand All @@ -51,26 +49,20 @@ public function substituteMarkerArray($content, array $markContentArray, $wrap =
{
}

public function substituteMarkerInObject(&$tree, array $markContentArray)
public function substituteMarkerInObject(&$tree, array $markContentArray): void
{
GeneralUtility::logDeprecatedFunction();
if (is_array($tree)) {
foreach ($tree as $key => $value) {
$this->templateService->substituteMarkerInObject($tree[$key], $markContentArray);
}
} else {
$tree = $this->templateService->substituteMarkerArray($tree, $markContentArray);
}

return $tree;
}

public function substituteMarkerAndSubpartArrayRecursive($content, array $markersAndSubparts, $wrap = '', $uppercase = false, $deleteUnused = false): void
{
}

public function fillInMarkerArray(array $markContentArray, array $row, $fieldList = '', $nl2br = true, $prefix = 'FIELD_', $HSC = false)
public function fillInMarkerArray(array $markContentArray, array $row, $fieldList = '', $nl2br = true, $prefix = 'FIELD_', $HSC = false): void
{
return $this->templateService->fillInMarkerArray($markContentArray, $row, $fieldList, $nl2br, $prefix, $HSC, !empty($GLOBALS['TSFE']->xhtmlDoctype));
}

public function fileResource($file): void
{

}
}
10 changes: 1 addition & 9 deletions stubs/Frontend/Controller/TypoScriptFrontendController.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,11 @@
final class TypoScriptFrontendController
{
/**
* Doctype to use.
*
* Currently set via PageGenerator
*
* @var string
*/
public $xhtmlDoctype = '';

/**
* Page content render object.
*
* @var ContentObjectRenderer
*/
public $cObj = '';
Expand Down Expand Up @@ -59,14 +53,11 @@ final class TypoScriptFrontendController
public $showHiddenRecords = '';

/**
* Passed to TypoScript template class and tells it to force template rendering
* @var bool
*/
public $forceTemplateParsing = false;

/**
* The TypoScript template object. Used to parse the TypoScript template
*
* @var TemplateService
*/
public $tmpl;
Expand Down Expand Up @@ -123,6 +114,7 @@ public function __construct()
$this->language = new SiteLanguage();
$this->sys_language_isocode = 'ch';
$this->csConvObj = new CharsetConverter();
$this->cObj = new ContentObjectRenderer();
}

public function applyHttpHeadersToResponse(): void
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

declare(strict_types=1);

namespace Ssch\TYPO3Rector\Tests\Rector\v8\v5\ContentObjectRendererFileResource;

use Iterator;
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
use Ssch\TYPO3Rector\Rector\v8\v5\ContentObjectRendererFileResourceRector;
use Symplify\SmartFileSystem\SmartFileInfo;

final class ContentObjectRendererFileResourceRectorTest extends AbstractRectorTestCase
{
/**
* @dataProvider provideDataForTest()
*/
public function test(SmartFileInfo $fileInfo): void
{
$this->doTestFileInfo($fileInfo);
}

public function provideDataForTest(): Iterator
{
return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture');
}

protected function getRectorClass(): string
{
return ContentObjectRendererFileResourceRector::class;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

$template = $GLOBALS['TSFE']->cObj->fileResource('EXT:vendor/Resources/Private/Templates/Template.html');

?>
-----
<?php

$template = '';
$typoscriptFrontendController = $GLOBALS['TSFE'];
$path = $typoscriptFrontendController->tmpl->getFileName('EXT:vendor/Resources/Private/Templates/Template.html');
if ($path !== null && file_exists($path)) {
$template = file_get_contents($path);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?php

namespace Ssch\TYPO3Rector\Tests\Rector\v8\v5\ContentObjectRendererFileResource\Fixture;

use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;

class MyClass
{
/**
* @var string
*/
private $template = '';

/**
* @var ContentObjectRenderer
*/
private $contentObject;

public function __construct()
{
$this->contentObject = GeneralUtility::makeInstance(ContentObjectRenderer::class);
}

public function initialize(): void
{
$this->template = $this->contentObject->fileResource('EXT:vendor/Resources/Private/Templates/Template.html');
}
}

?>
-----
<?php

namespace Ssch\TYPO3Rector\Tests\Rector\v8\v5\ContentObjectRendererFileResource\Fixture;

use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;

class MyClass
{
/**
* @var string
*/
private $template = '';

/**
* @var ContentObjectRenderer
*/
private $contentObject;

public function __construct()
{
$this->contentObject = GeneralUtility::makeInstance(ContentObjectRenderer::class);
}

public function initialize(): void
{
$typoscriptFrontendController = $GLOBALS['TSFE'];
$path = $typoscriptFrontendController->tmpl->getFileName('EXT:vendor/Resources/Private/Templates/Template.html');
if ($path !== null && file_exists($path)) {
$this->template = file_get_contents($path);
}
}
}

?>

0 comments on commit c4fcbf4

Please sign in to comment.