-
Notifications
You must be signed in to change notification settings - Fork 160
AC-663 PHPCS classes test #274
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
Merged
magento-devops-reposync-svc
merged 34 commits into
magento:develop
from
svera:AC-663_phpcs-ClassesTest
Oct 14, 2021
Merged
Changes from 26 commits
Commits
Show all changes
34 commits
Select commit
Hold shift + click to select a range
56e2de8
AC-663: Create phpcs static check for ClassesTest::testPhpCode
svera c9703a6
AC-663: Create phpcs static check for ClassesTest::testPhpCode
svera 5a83385
AC-663: Create phpcs static check for ClassesTest::testPhpCode
svera 5b40712
AC-663: Create phpcs static check for ClassesTest::testPhpCode
svera 4fe226e
Merge branch 'develop' of github.com:magento/magento-coding-standard …
svera 9d542d9
AC-663: Create phpcs static check for ClassesTest::testPhpCode
svera 2c5c076
AC-663: Create phpcs static check for ClassesTest::testPhpCode
svera 3636e9d
AC-663: Create phpcs static check for ClassesTest::testPhpCode
svera 0293560
AC-663: Create phpcs static check for ClassesTest::testPhpCode
svera b91d0d4
AC-663: Create phpcs static check for ClassesTest::testPhpCode
svera 717c998
AC-663: Create phpcs static check for ClassesTest::testPhpCode
svera 5810c6e
AC-663: Create phpcs static check for ClassesTest::testPhpCode
svera 0bc42a6
AC-663: Create phpcs static check for ClassesTest::testPhpCode
svera 19bb57b
AC-663: Create phpcs static check for ClassesTest::testPhpCode
svera 48a5816
AC-663: Create phpcs static check for ClassesTest::testPhpCode
svera b10df58
AC-663: Create phpcs static check for ClassesTest::testPhpCode
svera 64fa0cc
AC-663: Create phpcs static check for ClassesTest::testPhpCode
svera 5aa5721
AC-663: Create phpcs static check for ClassesTest::testPhpCode
svera 389d7ca
Update Magento2/Sniffs/Legacy/ClassReferencesInConfigurationFilesSnif…
svera c480100
Update Magento2/Sniffs/Legacy/ClassReferencesInConfigurationFilesSnif…
svera c0ead7c
Update Magento2/Sniffs/Legacy/ClassReferencesInConfigurationFilesSnif…
svera 7b38922
Update Magento2/Sniffs/Legacy/ClassReferencesInConfigurationFilesSnif…
svera 9a69638
Update Magento2/ruleset.xml
svera 936c28c
AC-663: Create phpcs static check for ClassesTest::testPhpCode
svera fbe2c1c
AC-663: Create phpcs static check for ClassesTest::testPhpCode
svera 34169b2
AC-663: Create phpcs static check for ClassesTest::testPhpCode
svera 6558e29
Merge branch 'develop' of github.com:magento/magento-coding-standard …
svera 36776b8
AC-663: Create phpcs static check for ClassesTest::testPhpCode
svera 39267ba
Update Magento2/Sniffs/Legacy/ClassReferencesInConfigurationFilesSnif…
svera 8402f7d
AC-663: Create phpcs static check for ClassesTest::testPhpCode
svera 1338211
Merge branch 'AC-663_phpcs-ClassesTest' of github.com:svera/magento-c…
svera ee4c7d6
AC-663: Create phpcs static check for ClassesTest::testPhpCode
svera 08ed34b
Update Magento2/Sniffs/Legacy/ClassReferencesInConfigurationFilesSnif…
svera c9ca788
AC-663: Create phpcs static check for ClassesTest::testPhpCode
svera File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
296 changes: 296 additions & 0 deletions
296
Magento2/Sniffs/Legacy/ClassReferencesInConfigurationFilesSniff.php
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,296 @@ | ||
<?php | ||
/** | ||
* Copyright © Magento, Inc. All rights reserved. | ||
* See COPYING.txt for license details. | ||
*/ | ||
|
||
namespace Magento2\Sniffs\Legacy; | ||
|
||
use DOMDocument; | ||
use PHP_CodeSniffer\Sniffs\Sniff; | ||
use PHP_CodeSniffer\Files\File; | ||
use SimpleXMLElement; | ||
|
||
class ClassReferencesInConfigurationFilesSniff implements Sniff | ||
{ | ||
private const ERROR_MESSAGE_CONFIG = 'Incorrect format of PHP class reference'; | ||
private const ERROR_CODE_CONFIG = 'IncorrectClassReference'; | ||
private const ERROR_MESSAGE_MODULE = 'Incorrect format of module reference'; | ||
private const ERROR_CODE_MODULE = 'IncorrectModuleReference'; | ||
|
||
/** | ||
* @inheritdoc | ||
*/ | ||
public function register() | ||
{ | ||
return [ | ||
T_INLINE_HTML, | ||
]; | ||
} | ||
|
||
/** | ||
* @inheritdoc | ||
*/ | ||
public function process(File $phpcsFile, $stackPtr) | ||
{ | ||
if ($stackPtr > 0) { | ||
return; | ||
} | ||
|
||
// We need to format the incoming XML to avoid tags split into several lines. In that case, PHP's DOMElement | ||
// returns the position of the closing /> as the position of the tag, and we need the position of < | ||
// instead, as it is the one we compare with $stackPtr later on. | ||
$xml = simplexml_load_string($this->getFormattedXML($phpcsFile)); | ||
if ($xml === false) { | ||
$phpcsFile->addError( | ||
sprintf( | ||
"Couldn't parse contents of '%s', check that they are in valid XML format", | ||
$phpcsFile->getFilename(), | ||
), | ||
$stackPtr, | ||
self::ERROR_CODE_CONFIG | ||
); | ||
} | ||
|
||
$classes = $this->collectClassesInConfig($xml); | ||
$this->assertNonFactoryName($phpcsFile, $classes); | ||
|
||
$modules = $this->getValuesFromXmlTagAttribute($xml, '//@module', 'module'); | ||
$this->assertNonFactoryNameModule($phpcsFile, $modules); | ||
|
||
$layouts = $this->collectClassesInLayout($xml); | ||
$this->assertNonFactoryName($phpcsFile, $layouts); | ||
|
||
$layoutTabs = $this->collectClassesInLayoutTabs($xml); | ||
$this->assertNonFactoryNameTab($phpcsFile, $layoutTabs); | ||
} | ||
|
||
/** | ||
* Check whether specified class names are right according PSR-1 Standard. | ||
* | ||
* @param File $phpcsFile | ||
* @param array $elements | ||
*/ | ||
private function assertNonFactoryName(File $phpcsFile, array $elements) | ||
{ | ||
foreach ($elements as $element) { | ||
if (stripos($element['value'], 'Magento') === false) { | ||
continue; | ||
} | ||
if (preg_match('/^([A-Z][a-z\d\\\\]+)+$/', $element['value']) !== 1) { | ||
$phpcsFile->addError( | ||
self::ERROR_MESSAGE_CONFIG, | ||
$element['lineNumber'], | ||
self::ERROR_CODE_CONFIG, | ||
); | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* Check whether specified class names in modules are right according PSR-1 Standard. | ||
* | ||
* @param File $phpcsFile | ||
* @param array $classes | ||
*/ | ||
private function assertNonFactoryNameModule(File $phpcsFile, array $classes) | ||
{ | ||
foreach ($classes as $element) { | ||
if (preg_match('/^([A-Z][A-Za-z\d_]+)+$/', $element['value']) !== 1) { | ||
$phpcsFile->addError( | ||
self::ERROR_MESSAGE_MODULE, | ||
$element['lineNumber'], | ||
self::ERROR_CODE_MODULE, | ||
); | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* Check whether specified class names in layout tabs are right according PSR-1 Standard. | ||
* | ||
* @param File $phpcsFile | ||
* @param array $elements | ||
*/ | ||
private function assertNonFactoryNameTab(File $phpcsFile, array $elements) | ||
{ | ||
foreach ($elements as $element) { | ||
if (preg_match('/\//', $element['value']) !== false) { | ||
$phpcsFile->addError( | ||
self::ERROR_MESSAGE_CONFIG, | ||
$element['lineNumber'], | ||
self::ERROR_CODE_CONFIG, | ||
); | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* Format the incoming XML to avoid tags split into several lines. | ||
* | ||
* @param File $phpcsFile | ||
* @return false|string | ||
*/ | ||
private function getFormattedXML(File $phpcsFile) | ||
{ | ||
$doc = new DomDocument('1.0'); | ||
$doc->formatOutput = true; | ||
$doc->loadXML($phpcsFile->getTokensAsString(0, 999999)); | ||
return $doc->saveXML(); | ||
} | ||
|
||
/** | ||
* Parse an XML for references to PHP class names in selected tags or attributes | ||
* | ||
* @param SimpleXMLElement $xml | ||
* @return array | ||
*/ | ||
private function collectClassesInConfig(SimpleXMLElement $xml): array | ||
{ | ||
$classes = $this->getValuesFromXmlTagContent( | ||
$xml, | ||
' | ||
/config//resource_adapter | /config/*[not(name()="sections")]//class[not(ancestor::observers)] | ||
| //model[not(parent::connection)] | //backend_model | //source_model | //price_model | ||
| //model_token | //writer_model | //clone_model | //frontend_model | //working_model | ||
| //admin_renderer | //renderer', | ||
); | ||
$classes = array_merge( | ||
$classes, | ||
$this->getValuesFromXmlTagAttribute( | ||
$xml, | ||
'//@backend_model', | ||
'backend_model' | ||
) | ||
); | ||
$classes = array_merge( | ||
$classes, | ||
$this->getValuesFromXmlTagAttribute( | ||
$xml, | ||
'/config//preference', | ||
'type' | ||
) | ||
); | ||
$classes = array_merge( | ||
$classes, | ||
$this->getValuesFromXmlTagName( | ||
$xml, | ||
'/logging/*/expected_models/* | /logging/*/actions/*/expected_models/*', | ||
) | ||
); | ||
svera marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
$classes = array_map( | ||
function (array $extendedNode) { | ||
$extendedNode['value'] = explode('::', trim($extendedNode['value']))[0]; | ||
return $extendedNode; | ||
}, | ||
$classes | ||
); | ||
|
||
return $classes; | ||
} | ||
|
||
/** | ||
* Parse an XML for references to PHP class names in selected tags or attributes | ||
* | ||
* @param SimpleXMLElement $xml | ||
* @return array | ||
*/ | ||
private function collectClassesInLayout(SimpleXMLElement $xml): array | ||
{ | ||
$classes = $this->getValuesFromXmlTagAttribute( | ||
$xml, | ||
'/layout//@helper', | ||
svera marked this conversation as resolved.
Show resolved
Hide resolved
|
||
'helper' | ||
); | ||
$classes = array_map( | ||
function (array $extendedNode) { | ||
$extendedNode['value'] = explode('::', trim($extendedNode['value']))[0]; | ||
return $extendedNode; | ||
}, | ||
$classes | ||
); | ||
$classes = array_merge( | ||
$classes, | ||
$this->getValuesFromXmlTagAttribute( | ||
$xml, | ||
'/layout//@module', | ||
'module' | ||
) | ||
); | ||
|
||
return $classes; | ||
} | ||
|
||
/** | ||
* Extract class references from layout tabs | ||
* | ||
* @param SimpleXMLElement $xml | ||
* @return array | ||
*/ | ||
private function collectClassesInLayoutTabs(SimpleXMLElement $xml): array | ||
{ | ||
return $this->getValuesFromXmlTagContent( | ||
$xml, | ||
'/layout//action[@method="addTab"]/block', | ||
svera marked this conversation as resolved.
Show resolved
Hide resolved
|
||
); | ||
} | ||
|
||
/** | ||
* Extract value from tag contents which exist in the XML path | ||
* | ||
* @param SimpleXMLElement $xml | ||
* @param string $xPath | ||
* @return array | ||
*/ | ||
private function getValuesFromXmlTagContent(SimpleXMLElement $xml, string $xPath): array | ||
{ | ||
$nodes = $xml->xpath($xPath) ?: []; | ||
return array_map(function ($item) { | ||
return [ | ||
'value' => (string)$item, | ||
'lineNumber' => dom_import_simplexml($item)->getLineNo()-1, | ||
]; | ||
}, $nodes); | ||
} | ||
|
||
/** | ||
* Extract value from tag names which exist in the XML path | ||
* | ||
* @param SimpleXMLElement $xml | ||
* @param string $xPath | ||
* @return array | ||
*/ | ||
private function getValuesFromXmlTagName(SimpleXMLElement $xml, string $xPath): array | ||
{ | ||
$nodes = $xml->xpath($xPath) ?: []; | ||
return array_map(function ($item) { | ||
return [ | ||
'value' => $item->getName(), | ||
'lineNumber' => dom_import_simplexml($item)->getLineNo()-1, | ||
]; | ||
}, $nodes); | ||
} | ||
|
||
/** | ||
* Extract value from tag attributes which exist in the XML path | ||
* | ||
* @param SimpleXMLElement $xml | ||
* @param string $xPath | ||
* @param string $attr | ||
* @return array | ||
*/ | ||
private function getValuesFromXmlTagAttribute(SimpleXMLElement $xml, string $xPath, string $attr): array | ||
{ | ||
$nodes = $xml->xpath($xPath) ?: []; | ||
return array_map(function ($item) use ($attr) { | ||
$nodeArray = (array)$item; | ||
if (isset($nodeArray['@attributes'][$attr])) { | ||
return [ | ||
'value' => $nodeArray['@attributes'][$attr], | ||
'lineNumber' => dom_import_simplexml($item)->getLineNo()-1, | ||
]; | ||
} | ||
}, $nodes); | ||
} | ||
} |
45 changes: 45 additions & 0 deletions
45
Magento2/Tests/Legacy/ClassReferencesInConfigurationFilesUnitTest.1.xml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
<?xml version="1.0"?> | ||
<!-- | ||
/** | ||
* Copyright © Magento, Inc. All rights reserved. | ||
* See COPYING.txt for license details. | ||
*/ | ||
--> | ||
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd"> | ||
<system> | ||
<section id="payment" type="text" sortOrder="400" showInDefault="1" showInWebsite="1" showInStore="1"> | ||
<group id="checkmo" translate="label" type="text" sortOrder="30" showInDefault="1" showInWebsite="1" showInStore="1"> | ||
<label>Check / Money Order</label> | ||
<field id="active" translate="label" type="select" sortOrder="1" showInDefault="1" showInWebsite="1" canRestore="1"> | ||
<label>Enabled</label> | ||
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model> | ||
</field> | ||
</group> | ||
<group id="purchaseorder" translate="label" type="text" sortOrder="32" showInDefault="1" showInWebsite="1" showInStore="1"> | ||
<label>Purchase Order</label> | ||
<field id="active" translate="label" type="select" sortOrder="1" showInDefault="1" showInWebsite="1" canRestore="1"> | ||
<label>Enabled</label> | ||
<source_model>Magento\CONFIG\Model\Config\Source\Yesno</source_model> | ||
</field> | ||
</group> | ||
<group id="banktransfer" translate="label" type="text" sortOrder="30" showInDefault="1" showInWebsite="1" showInStore="1"> | ||
<label>Bank Transfer Payment</label> | ||
<field id="active" translate="label" type="select" sortOrder="1" showInDefault="1" showInWebsite="1" canRestore="1"> | ||
<label>Enabled</label> | ||
<source_model>Config\Model\Config\Source\Yesno</source_model> | ||
</field> | ||
<field id="title" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1"> | ||
<label>Title</label> | ||
</field> | ||
<field id="order_status" translate="label" type="select" sortOrder="20" showInDefault="1" showInWebsite="1" canRestore="1"> | ||
<label>New Order Status</label> | ||
<source_model>Sales\MODEL\Config\Source\Order\Status\NewStatus</source_model> | ||
</field> | ||
<field id="allowspecific" translate="label" type="allowspecific" sortOrder="50" showInDefault="1" showInWebsite="1" canRestore="1"> | ||
<label>Payment from Applicable Countries</label> | ||
<source_model>MAGENTO\Payment\Model\Config\Source\Allspecificcountries</source_model> | ||
</field> | ||
</group> | ||
</section> | ||
</system> | ||
</config> |
52 changes: 52 additions & 0 deletions
52
Magento2/Tests/Legacy/ClassReferencesInConfigurationFilesUnitTest.2.xml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
<?xml version="1.0"?> | ||
<!-- | ||
/** | ||
* Copyright © Magento, Inc. All rights reserved. | ||
* See COPYING.txt for license details. | ||
*/ | ||
--> | ||
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd"> | ||
<system> | ||
<section id="payment" type="text" sortOrder="400" showInDefault="1" showInWebsite="1" showInStore="1"> | ||
<group id="checkmo" translate="label" type="text" sortOrder="30" showInDefault="1" showInWebsite="1" showInStore="1"> | ||
<label>Check / Money Order</label> | ||
<field id="active" translate="label" type="select" sortOrder="1" showInDefault="1" showInWebsite="1" canRestore="1"> | ||
<label>Enabled</label> | ||
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model> | ||
</field> | ||
</group> | ||
<group id="purchaseorder" translate="label" type="text" sortOrder="32" showInDefault="1" showInWebsite="1" showInStore="1"> | ||
<label>Purchase Order</label> | ||
<field id="active" translate="label" type="select" sortOrder="1" showInDefault="1" showInWebsite="1" canRestore="1"> | ||
<label>Enabled</label> | ||
<source_model> | ||
Magento\CONFIG\Model\Config\Source\Yesno | ||
</source_model> | ||
</field> | ||
</group> | ||
<group id="banktransfer" translate="label" type="text" sortOrder="30" showInDefault="1" showInWebsite="1" showInStore="1"> | ||
<label>Bank Transfer Payment</label> | ||
<field id="active" translate="label" type="select" sortOrder="1" showInDefault="1" showInWebsite="1" canRestore="1"> | ||
<label>Enabled</label> | ||
<source_model>Config\Model\Config\Source\Yesno</source_model> | ||
</field> | ||
<field id="title" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1"> | ||
<label>Title</label> | ||
</field> | ||
<field id="order_status" translate="label" type="select" sortOrder="20" showInDefault="1" showInWebsite="1" canRestore="1"> | ||
<label>New Order Status</label> | ||
<source_model>Sales\MODEL\Config\Source\Order\Status\NewStatus</source_model> | ||
</field> | ||
<field id="allowspecific" translate="label" type="allowspecific" sortOrder="50" showInDefault="1" showInWebsite="1" canRestore="1"> | ||
<label>Payment from Applicable Countries</label> | ||
<source_model> | ||
|
||
|
||
MAGENTO\Payment\Model\Config\Source\Allspecificcountries | ||
|
||
</source_model> | ||
</field> | ||
</group> | ||
</section> | ||
</system> | ||
</config> |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.