Skip to content

Commit a7a82f9

Browse files
committed
AC-681: Create phpcs static check for PhtmlTemplateTest
1 parent dc56f12 commit a7a82f9

File tree

6 files changed

+346
-0
lines changed

6 files changed

+346
-0
lines changed
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
<?php
2+
3+
namespace Magento2\Sniffs\Legacy;
4+
5+
use PHP_CodeSniffer\Files\File;
6+
use PHP_CodeSniffer\Sniffs\Sniff;
7+
8+
class PhtmlTemplateSniff implements Sniff
9+
{
10+
private const WARNING_CODE = 'PhtmlTemplateObsolete';
11+
12+
private const OBSOLETE_REGEX_IN_SPECIFIC_PHTML_TEMPLATES = [
13+
'/(["\'])jquery\/ui\1/' => 'Please do not use "jquery/ui" library in templates. Use needed jquery ' .
14+
'ui widget instead.',
15+
'/data-mage-init=(?:\'|")(?!\s*{\s*"[^"]+")/' => 'Please do not initialize JS component in php. Do ' .
16+
'it in template.',
17+
'@x-magento-init.>(?!\s*+{\s*"[^"]+"\s*:\s*{\s*"[\w/-]+")@i' => 'Please do not initialize JS component ' .
18+
'in php. Do it in template.',
19+
];
20+
21+
/**
22+
* @inheritdoc
23+
*/
24+
public function register(): array
25+
{
26+
return [
27+
T_OBJECT_OPERATOR,
28+
T_INLINE_HTML,
29+
T_HEREDOC
30+
];
31+
}
32+
33+
/**
34+
* @inheritdoc
35+
*/
36+
public function process(File $phpcsFile, $stackPtr)
37+
{
38+
$tokens = $phpcsFile->getTokens();
39+
if ($tokens[$stackPtr]['code'] === T_OBJECT_OPERATOR) {
40+
$this->checkBlockVariable($phpcsFile, $stackPtr, $tokens);
41+
$this->checkThisVariable($phpcsFile, $stackPtr, $tokens);
42+
}
43+
if ($tokens[$stackPtr]['code'] === T_INLINE_HTML || $tokens[$stackPtr]['code'] === T_HEREDOC) {
44+
$this->checkHtml($phpcsFile, $stackPtr);
45+
46+
$file = $phpcsFile->getFilename();
47+
48+
if (strpos($file, '/view/frontend/templates/') !== false
49+
|| strpos($file, '/view/base/templates/') !== false
50+
) {
51+
$this->checkHtmlSpecificFiles($phpcsFile, $stackPtr);
52+
}
53+
}
54+
}
55+
56+
/**
57+
* @param File $phpcsFile
58+
* @param int $stackPtr
59+
* @param array $tokens
60+
*/
61+
private function checkBlockVariable(File $phpcsFile, int $stackPtr, array $tokens): void
62+
{
63+
$varPos = $phpcsFile->findPrevious(T_VARIABLE, $stackPtr - 1);
64+
if ($tokens[$varPos]['content'] !== '$block') {
65+
return;
66+
}
67+
$stringPos = $phpcsFile->findNext(T_STRING, $stackPtr + 1);
68+
if (strpos($tokens[$stringPos]['content'], '_') === 0) {
69+
$phpcsFile->addWarning(
70+
'Access to protected and private members of Block class is ' .
71+
'obsolete in phtml templates. Use only public members.',
72+
$stringPos,
73+
self::WARNING_CODE
74+
);
75+
}
76+
}
77+
78+
/**
79+
* @param File $phpcsFile
80+
* @param int $stackPtr
81+
* @param array $tokens
82+
*/
83+
private function checkThisVariable(File $phpcsFile, int $stackPtr, array $tokens): void
84+
{
85+
$varPos = $phpcsFile->findPrevious(T_VARIABLE, $stackPtr - 1);
86+
if ($tokens[$varPos]['content'] !== '$this') {
87+
return;
88+
}
89+
$stringPos = $phpcsFile->findNext(T_STRING, $stackPtr + 1);
90+
if (strpos($tokens[$stringPos]['content'], 'helper') === false) {
91+
$phpcsFile->addWarning(
92+
'Access to members and methods of Block class through $this is ' .
93+
'obsolete in phtml templates. Use only $block instead of $this.',
94+
$stringPos,
95+
self::WARNING_CODE
96+
);
97+
}
98+
}
99+
100+
/**
101+
* @param File $phpcsFile
102+
* @param int $stackPtr
103+
*/
104+
private function checkHtml(File $phpcsFile, int $stackPtr): void
105+
{
106+
$content = $phpcsFile->getTokensAsString($stackPtr, 1);
107+
108+
if (preg_match('/type="text\/javascript"/', $content)) {
109+
$phpcsFile->addWarning(
110+
'Please do not use "text/javascript" type attribute.',
111+
$stackPtr,
112+
self::WARNING_CODE
113+
);
114+
}
115+
}
116+
117+
/**
118+
* @param File $phpcsFile
119+
* @param int $stackPtr
120+
*/
121+
private function checkHtmlSpecificFiles(File $phpcsFile, int $stackPtr): void
122+
{
123+
$content = $phpcsFile->getTokensAsString($stackPtr, 1);
124+
125+
foreach (self::OBSOLETE_REGEX_IN_SPECIFIC_PHTML_TEMPLATES as $obsoleteRegex => $errorMessage) {
126+
if (preg_match($obsoleteRegex, $content)) {
127+
$phpcsFile->addWarning(
128+
$errorMessage,
129+
$stackPtr,
130+
self::WARNING_CODE
131+
);
132+
}
133+
}
134+
}
135+
136+
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento2\Tests\Legacy;
7+
8+
use DirectoryIterator;
9+
use PHP_CodeSniffer\Tests\Standards\AbstractSniffUnitTest;
10+
use RecursiveDirectoryIterator;
11+
use RecursiveIteratorIterator;
12+
13+
class PhtmlTemplateUnitTest extends AbstractSniffUnitTest
14+
{
15+
/**
16+
* @inheritdoc
17+
*/
18+
protected function getTestFiles($testFileBase): array
19+
{
20+
$testFiles = [];
21+
22+
$dir = __DIR__.'/_files/PhtmlTemplateUnitTest';
23+
$di = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir));
24+
25+
/**
26+
* @var DirectoryIterator $file
27+
*/
28+
foreach ($di as $file) {
29+
if ($file->isDir()) {
30+
continue;
31+
}
32+
$path = $file->getPathname();
33+
if ($path !== $testFileBase.'php' && substr($path, -5) !== 'fixed' && substr($path, -4) !== '.bak') {
34+
$testFiles[] = $path;
35+
}
36+
}
37+
38+
// Put them in order.
39+
sort($testFiles);
40+
41+
return $testFiles;
42+
}
43+
44+
/**
45+
* @inheritdoc
46+
*/
47+
public function getErrorList()
48+
{
49+
return [];
50+
}
51+
52+
/**
53+
* @inheritdoc
54+
*/
55+
public function getWarningList($testFile = '')
56+
{
57+
if ($testFile === 'PhtmlTemplateUnitTest.1.phtml' || $testFile === 'PhtmlTemplateUnitTest.2.phtml') {
58+
return [
59+
7 => 1,
60+
9 => 1,
61+
13 => 1,
62+
20 => 1,
63+
22 => 1,
64+
23 => 1,
65+
27 => 1,
66+
33 => 1,
67+
39 => 1
68+
];
69+
}
70+
if ($testFile === 'PhtmlTemplateUnitTest.3.phtml')
71+
{
72+
return [
73+
9 => 1,
74+
20 => 1,
75+
22 => 1,
76+
23 => 1,
77+
27 => 1,
78+
];
79+
}
80+
return [];
81+
}
82+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
?>
7+
<script type="text/x-magento-init">
8+
</script>
9+
<script type="text/javascript">
10+
</script>
11+
<div id="block-testing"
12+
class="block shipping"
13+
data-mage-init='{}'
14+
>
15+
<?php
16+
function _testing()
17+
{
18+
return true;
19+
}
20+
$_productCollection = $block->_getTestFunction();
21+
$block->getTestFunction();
22+
$_something = $this->something();
23+
$block->_getTest();
24+
$block = _testing();
25+
?>
26+
<?php
27+
$block->_getTestAnotherFunction();
28+
?>
29+
30+
<?php $scriptString = <<<script
31+
require([
32+
"jquery",
33+
"jquery/ui",
34+
], function ($, Confirm) {
35+
});
36+
script;
37+
$this->helper();
38+
?>
39+
<script type="jquery/ui">
40+
</script>
41+
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
?>
7+
<script type="text/x-magento-init">
8+
</script>
9+
<script type="text/javascript">
10+
</script>
11+
<div id="block-testing"
12+
class="block shipping"
13+
data-mage-init='{}'
14+
>
15+
<?php
16+
function _testing()
17+
{
18+
return true;
19+
}
20+
$_productCollection = $block->_getTestFunction();
21+
$block->getTestFunction();
22+
$_something = $this->something();
23+
$block->_getTest();
24+
$block = _testing();
25+
?>
26+
<?php
27+
$block->_getTestAnotherFunction();
28+
?>
29+
30+
<?php $scriptString = <<<script
31+
require([
32+
"jquery",
33+
"jquery/ui",
34+
], function ($, Confirm) {
35+
});
36+
script;
37+
$this->helper();
38+
?>
39+
<script type="jquery/ui">
40+
</script>
41+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
?>
7+
<script type="text/x-magento-init">
8+
</script>
9+
<script type="text/javascript">
10+
</script>
11+
<div id="block-testing"
12+
class="block shipping"
13+
data-mage-init='{}'
14+
>
15+
<?php
16+
function _testing()
17+
{
18+
return true;
19+
}
20+
$_productCollection = $block->_getTestFunction();
21+
$block->getTestFunction();
22+
$_something = $this->something();
23+
$block->_getTest();
24+
$block = _testing();
25+
?>
26+
<?php
27+
$block->_getTestAnotherFunction();
28+
?>
29+
30+
<?php $scriptString = <<<script
31+
require([
32+
"jquery",
33+
"jquery/ui",
34+
], function ($, Confirm) {
35+
});
36+
script;
37+
$this->helper();
38+
?>
39+
<script type="jquery/ui">
40+
</script>
41+

Magento2/ruleset.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,11 @@
302302
<severity>8</severity>
303303
<type>warning</type>
304304
</rule>
305+
<rule ref="Magento2.Legacy.PhtmlTemplate">
306+
<include-pattern>*\.phtml$</include-pattern>
307+
<severity>8</severity>
308+
<type>warning</type>
309+
</rule>
305310

306311
<!-- Severity 7 warnings: General code issues. -->
307312
<rule ref="Generic.Arrays.DisallowLongArraySyntax">

0 commit comments

Comments
 (0)