Skip to content

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
Merged
Show file tree
Hide file tree
Changes from 11 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 Sep 6, 2021
c9703a6
AC-663: Create phpcs static check for ClassesTest::testPhpCode
svera Sep 6, 2021
5a83385
AC-663: Create phpcs static check for ClassesTest::testPhpCode
svera Sep 9, 2021
5b40712
AC-663: Create phpcs static check for ClassesTest::testPhpCode
svera Sep 9, 2021
4fe226e
Merge branch 'develop' of github.com:magento/magento-coding-standard …
svera Sep 15, 2021
9d542d9
AC-663: Create phpcs static check for ClassesTest::testPhpCode
svera Sep 16, 2021
2c5c076
AC-663: Create phpcs static check for ClassesTest::testPhpCode
svera Sep 16, 2021
3636e9d
AC-663: Create phpcs static check for ClassesTest::testPhpCode
svera Sep 16, 2021
0293560
AC-663: Create phpcs static check for ClassesTest::testPhpCode
svera Sep 16, 2021
b91d0d4
AC-663: Create phpcs static check for ClassesTest::testPhpCode
svera Sep 16, 2021
717c998
AC-663: Create phpcs static check for ClassesTest::testPhpCode
svera Sep 16, 2021
5810c6e
AC-663: Create phpcs static check for ClassesTest::testPhpCode
svera Sep 16, 2021
0bc42a6
AC-663: Create phpcs static check for ClassesTest::testPhpCode
svera Sep 16, 2021
19bb57b
AC-663: Create phpcs static check for ClassesTest::testPhpCode
svera Sep 16, 2021
48a5816
AC-663: Create phpcs static check for ClassesTest::testPhpCode
svera Sep 16, 2021
b10df58
AC-663: Create phpcs static check for ClassesTest::testPhpCode
svera Sep 17, 2021
64fa0cc
AC-663: Create phpcs static check for ClassesTest::testPhpCode
svera Sep 17, 2021
5aa5721
AC-663: Create phpcs static check for ClassesTest::testPhpCode
svera Sep 17, 2021
389d7ca
Update Magento2/Sniffs/Legacy/ClassReferencesInConfigurationFilesSnif…
svera Sep 20, 2021
c480100
Update Magento2/Sniffs/Legacy/ClassReferencesInConfigurationFilesSnif…
svera Sep 20, 2021
c0ead7c
Update Magento2/Sniffs/Legacy/ClassReferencesInConfigurationFilesSnif…
svera Sep 20, 2021
7b38922
Update Magento2/Sniffs/Legacy/ClassReferencesInConfigurationFilesSnif…
svera Sep 20, 2021
9a69638
Update Magento2/ruleset.xml
svera Sep 20, 2021
936c28c
AC-663: Create phpcs static check for ClassesTest::testPhpCode
svera Sep 20, 2021
fbe2c1c
AC-663: Create phpcs static check for ClassesTest::testPhpCode
svera Sep 21, 2021
34169b2
AC-663: Create phpcs static check for ClassesTest::testPhpCode
svera Sep 21, 2021
6558e29
Merge branch 'develop' of github.com:magento/magento-coding-standard …
svera Oct 13, 2021
36776b8
AC-663: Create phpcs static check for ClassesTest::testPhpCode
svera Oct 13, 2021
39267ba
Update Magento2/Sniffs/Legacy/ClassReferencesInConfigurationFilesSnif…
svera Oct 13, 2021
8402f7d
AC-663: Create phpcs static check for ClassesTest::testPhpCode
svera Oct 13, 2021
1338211
Merge branch 'AC-663_phpcs-ClassesTest' of github.com:svera/magento-c…
svera Oct 13, 2021
ee4c7d6
AC-663: Create phpcs static check for ClassesTest::testPhpCode
svera Oct 13, 2021
08ed34b
Update Magento2/Sniffs/Legacy/ClassReferencesInConfigurationFilesSnif…
svera Oct 14, 2021
c9ca788
AC-663: Create phpcs static check for ClassesTest::testPhpCode
svera Oct 14, 2021
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
215 changes: 215 additions & 0 deletions Magento2/Sniffs/Legacy/ClassesConfigurationSniff.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,215 @@
<?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 ClassesConfigurationSniff implements Sniff
{
private const ERROR_MESSAGE_CONFIG = 'Attribute does not follow expected format';
private const ERROR_CODE_CONFIG = 'WrongXML';
private const ERROR_MESSAGE_MODULE = 'Attribute does not follow expected format in module';
private const ERROR_CODE_MODULE = 'WrongXMLModule';

/**
* @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->getXmlAttributeValues($xml, '//@module', 'module');
$this->assertNonFactoryNameModule($phpcsFile, $modules);
}

/**
* Check whether specified classes or module names correspond to a file according PSR-1 Standard.
*
* @param File $phpcsFile
* @param ExtendedNode[] $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->element->getLineNo() - 1,
self::ERROR_CODE_CONFIG,
);
}
}
}

/**
* Check whether specified classes or module names correspond to a file according PSR-1 Standard.
*
* @param File $phpcsFile
* @param ExtendedNode[] $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->element->getLineNo() - 1,
self::ERROR_CODE_MODULE,
);
}
}
}

/**
* 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->getXmlNode(
$xml,
'
/config//resource_adapter | /config/*[not(name()="sections")]//class[not(ancestor::observers)]
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This regexp must be updated almost certainly, as I think some of these paths are no longer accurate. Could you please check them out @sivaschenko ?

| //model[not(parent::connection)] | //backend_model | //source_model | //price_model
| //model_token | //writer_model | //clone_model | //frontend_model | //working_model
| //admin_renderer | //renderer | /config/*/di/preferences/*'
);
$classes = array_merge($classes, $this->getXmlAttributeValues($xml, '//@backend_model', 'backend_model'));
$classes = array_merge(
$classes,
$this->getXmlNodeNames(
$xml,
'/logging/*/expected_models/* | /logging/*/actions/*/expected_models/* | /config/*/di/preferences/*'
)
);

$classes = array_map(
function (ExtendedNode $extendedNode) {
$extendedNode->value = explode('::', trim($extendedNode->value))[0];
return $extendedNode;
},
$classes
);
$classes = array_filter(
$classes,
function ($value) {
return !empty($value);
}
);

return $classes;
}

/**
* Get XML node text values using specified xPath
*
* The node must contain specified attribute
*
* @param SimpleXMLElement $xml
* @param string $xPath
* @return array
*/
private function getXmlNode(SimpleXMLElement $xml, string $xPath): array
{
$result = [];
$nodes = $xml->xpath($xPath) ?: [];
foreach ($nodes as $node) {
$result[] = new ExtendedNode((string)$node, $node);
}
return $result;
}

/**
* Get XML node names using specified xPath
*
* @param SimpleXMLElement $xml
* @param string $xpath
* @return array
*/
private function getXmlNodeNames(SimpleXMLElement $xml, string $xpath): array
{
$result = [];
$nodes = $xml->xpath($xpath) ?: [];
foreach ($nodes as $node) {
$result[] = new ExtendedNode($node->getName(), $node);
}
return $result;
}

/**
* Get XML node attribute values using specified xPath
*
* @param SimpleXMLElement $xml
* @param string $xPath
* @param string $attributeName
* @return array
*/
private function getXmlAttributeValues(SimpleXMLElement $xml, string $xPath, string $attributeName): array
{
$result = [];
$nodes = $xml->xpath($xPath) ?: [];
foreach ($nodes as $node) {
$nodeArray = (array)$node;
if (isset($nodeArray['@attributes'][$attributeName])) {
$result[] = new ExtendedNode($nodeArray['@attributes'][$attributeName], $node);
}
}
return $result;
}
}
33 changes: 33 additions & 0 deletions Magento2/Sniffs/Legacy/ExtendedNode.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/

namespace Magento2\Sniffs\Legacy;

use DOMElement;
use SimpleXMLElement;

class ExtendedNode
{
/**
* @var string
*/
public $value;

/**
* @var DOMElement
*/
public $element;

/**
* @param string $value
* @param SimpleXMLElement $element
*/
public function __construct(string $value, SimpleXMLElement $element)
{
$this->value = $value;
$this->element = dom_import_simplexml($element);
}
}
45 changes: 45 additions & 0 deletions Magento2/Tests/Legacy/ClassesConfigurationUnitTest.1.xml
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>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about this line? Should it work?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jcuerdo is not in the Magento namespace, thus it is ignored

</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 Magento2/Tests/Legacy/ClassesConfigurationUnitTest.2.xml
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>
13 changes: 13 additions & 0 deletions Magento2/Tests/Legacy/ClassesConfigurationUnitTest.3.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?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_Backend:etc/menu.xsd">
<menu>
<add id="Magento_CatalogRule::promo" title="Promotions" translate="title" module="Magento CatalogRule" parent="Magento_Backend::marketing" sortOrder="10" resource="Magento_CatalogRule::promo"/>
<add id="Magento_CatalogRule::promo_catalog" title="Catalog Price Rule" translate="title" sortOrder="10" module="Magento_CatalogRule" parent="Magento_CatalogRule::promo" action="catalog_rule/promo_catalog/" dependsOnModule="Magento_Catalog" resource="Magento_CatalogRule::promo_catalog"/>
</menu>
</config>
Loading