Skip to content

Ruleset: remove support for the deprecated ruleset.xml array property string-based syntax #976

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 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
33 changes: 12 additions & 21 deletions src/Ruleset.php
Original file line number Diff line number Diff line change
Expand Up @@ -1199,6 +1199,17 @@ private function processRule($rule, $newSniffs, $depth=0)
if (isset($prop['type']) === true
&& (string) $prop['type'] === 'array'
) {
if (isset($prop['value']) === true) {
$message = 'Passing an array of values to a property using a comma-separated string'.PHP_EOL;
$message .= 'is no longer supported since PHP_CodeSniffer 4.0.0.'.PHP_EOL;
$message .= "The unsupported syntax was used for property \"$name\"".PHP_EOL;
$message .= "for sniff \"$code\".".PHP_EOL;
$message .= 'Pass array values via <element [key="..." ]value="..."> nodes instead.';
$this->msgCache->add($message, MessageCollector::ERROR);

continue;
}

$values = [];
if (isset($prop['extend']) === true
&& (string) $prop['extend'] === 'true'
Expand Down Expand Up @@ -1226,27 +1237,7 @@ private function processRule($rule, $newSniffs, $depth=0)
}

$printValue = rtrim($printValue, ',');
} else if (isset($prop['value']) === true) {
$message = 'Passing an array of values to a property using a comma-separated string'.PHP_EOL;
$message .= 'was deprecated in PHP_CodeSniffer 3.3.0. Support will be removed in PHPCS 4.0.0.'.PHP_EOL;
$message .= "The deprecated syntax was used for property \"$name\"".PHP_EOL;
$message .= "for sniff \"$code\".".PHP_EOL;
$message .= 'Pass array values via <element [key="..." ]value="..."> nodes instead.';
$this->msgCache->add($message, MessageCollector::DEPRECATED);

$value = (string) $prop['value'];
$printValue = $value;
if ($value !== '') {
foreach (explode(',', $value) as $val) {
list($k, $v) = explode('=>', $val.'=>');
if ($v !== '') {
$values[trim($k)] = trim($v);
} else {
$values[] = trim($k);
}
}
}
}//end if
}

$this->ruleset[$code]['properties'][$name] = [
'value' => $values,
Expand Down
5 changes: 3 additions & 2 deletions tests/Core/Ruleset/ExplainTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -184,9 +184,9 @@ public function testExplainWithDeprecatedSniffs()
$ruleset = new Ruleset($config);

$expected = PHP_EOL;
$expected .= 'The ShowSniffDeprecationsTest standard contains 11 sniffs'.PHP_EOL.PHP_EOL;
$expected .= 'The ShowSniffDeprecationsTest standard contains 12 sniffs'.PHP_EOL.PHP_EOL;

$expected .= 'TestStandard (11 sniffs)'.PHP_EOL;
$expected .= 'TestStandard (12 sniffs)'.PHP_EOL;
$expected .= '------------------------'.PHP_EOL;
$expected .= ' TestStandard.Deprecated.WithLongReplacement *'.PHP_EOL;
$expected .= ' TestStandard.Deprecated.WithoutReplacement *'.PHP_EOL;
Expand All @@ -198,6 +198,7 @@ public function testExplainWithDeprecatedSniffs()
$expected .= ' TestStandard.SetProperty.AllowedViaStdClass'.PHP_EOL;
$expected .= ' TestStandard.SetProperty.NotAllowedViaAttribute'.PHP_EOL;
$expected .= ' TestStandard.SetProperty.PropertyTypeHandling'.PHP_EOL;
$expected .= ' TestStandard.SetProperty.PropertyTypeHandlingOldArrayFormat'.PHP_EOL;
$expected .= ' TestStandard.ValidSniffs.RegisterEmptyArray'.PHP_EOL.PHP_EOL;

$expected .= '* Sniffs marked with an asterix are deprecated.'.PHP_EOL;
Expand Down
4 changes: 0 additions & 4 deletions tests/Core/Ruleset/Fixtures/PropertyTypeHandlingInline.inc
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,4 @@
// phpcs:set TestStandard.SetProperty.PropertyTypeHandling expectsArrayWithKeysAndValues[] string=>string,10=>10,float=>1.5,null=>null,true=>true,false=>false
// phpcs:set TestStandard.SetProperty.PropertyTypeHandling expectsEmptyArray[]

// phpcs:set TestStandard.SetProperty.PropertyTypeHandling expectsOldSchoolArrayWithOnlyValues[] string, 10, 1.5, null, true, false
// phpcs:set TestStandard.SetProperty.PropertyTypeHandling expectsOldSchoolArrayWithKeysAndValues[] string=>string,10=>10,float=>1.5,null=>null,true=>true,false=>false
// phpcs:set TestStandard.SetProperty.PropertyTypeHandling expectsOldSchoolEmptyArray[]

echo 'hello!';
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?php
/**
* Test fixture.
*
* @see \PHP_CodeSniffer\Tests\Core\Ruleset\PropertyTypeHandlingOldArrayFormatTest
*/

namespace Fixtures\TestStandard\Sniffs\SetProperty;

use PHP_CodeSniffer\Files\File;
use PHP_CodeSniffer\Sniffs\Sniff;

final class PropertyTypeHandlingOldArrayFormatSniff implements Sniff
{

/**
* Used to verify that array properties passed as a string is no longer supported since PHPCS 4.0.0.
*
* @var array<mixed>
*/
public $expectsOldSchoolArrayWithOnlyValues;

/**
* Used to verify that array properties passed as a string is no longer supported since PHPCS 4.0.0.
*
* @var array<string, mixed>
*/
public $expectsOldSchoolArrayWithKeysAndValues;

/**
* Used to verify that array properties passed as a string is no longer supported since PHPCS 4.0.0.
*
* @var array<string, mixed>
*/
public $expectsOldSchoolArrayWithExtendedValues;

/**
* Used to verify that array properties passed as a string is no longer supported since PHPCS 4.0.0.
*
* @var array<string, mixed>
*/
public $expectsOldSchoolArrayWithExtendedKeysAndValues;

/**
* Used to verify that array properties passed as a string is no longer supported since PHPCS 4.0.0.
*
* @var array<mixed>
*/
public $expectsOldSchoolEmptyArray;

public function register()
{
return [T_ECHO];
}

public function process(File $phpcsFile, $stackPtr)
{
// Do something.
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -143,41 +143,6 @@ final class PropertyTypeHandlingSniff implements Sniff
*/
public $expectsEmptyArray;

/**
* Used to verify that array properties passed as a string get parsed to a proper array.
*
* @var array<mixed>
*/
public $expectsOldSchoolArrayWithOnlyValues;

/**
* Used to verify that array properties passed as a string with keys get parsed to a proper array.
*
* @var array<string, mixed>
*/
public $expectsOldSchoolArrayWithKeysAndValues;

/**
* Used to verify that array properties passed as a string can get extended.
*
* @var array<string, mixed>
*/
public $expectsOldSchoolArrayWithExtendedValues;

/**
* Used to verify that array properties passed as a string can get extended.
*
* @var array<string, mixed>
*/
public $expectsOldSchoolArrayWithExtendedKeysAndValues;

/**
* Used to verify that array properties passed as a string allow for setting a property to an empty array.
*
* @var array<mixed>
*/
public $expectsOldSchoolEmptyArray;

public function register()
{
return [T_ECHO];
Expand Down
1 change: 1 addition & 0 deletions tests/Core/Ruleset/ProcessRulesetTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ public function testAutoExpandSniffsDirectory()
"$std.SetProperty.AllowedViaStdClass" => "$sniffDir\SetProperty\AllowedViaStdClassSniff",
"$std.SetProperty.NotAllowedViaAttribute" => "$sniffDir\SetProperty\NotAllowedViaAttributeSniff",
"$std.SetProperty.PropertyTypeHandling" => "$sniffDir\SetProperty\PropertyTypeHandlingSniff",
"$std.SetProperty.PropertyTypeHandlingOldArrayFormat" => "$sniffDir\SetProperty\PropertyTypeHandlingOldArrayFormatSniff",
"$std.ValidSniffs.RegisterEmptyArray" => "$sniffDir\ValidSniffs\RegisterEmptyArraySniff",
];

Expand Down
54 changes: 54 additions & 0 deletions tests/Core/Ruleset/PropertyTypeHandlingOldArrayFormatTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php
/**
* Tests for the handling of properties being set via the ruleset.
*
* @author Juliette Reinders Folmer <phpcs_nospam@adviesenzo.nl>
* @copyright 2025 PHPCSStandards and contributors
* @license https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
*/

namespace PHP_CodeSniffer\Tests\Core\Ruleset;

use PHP_CodeSniffer\Ruleset;
use PHP_CodeSniffer\Tests\ConfigDouble;
use PHP_CodeSniffer\Tests\Core\Ruleset\AbstractRulesetTestCase;

/**
* Test the handling of an array property value using the PHPCS < 4.0 format set via the ruleset.
*
* @covers \PHP_CodeSniffer\Ruleset::setSniffProperty
*/
final class PropertyTypeHandlingOldArrayFormatTest extends AbstractRulesetTestCase
{


/**
* Verify an error is thrown when an array property is set from the ruleset using a comma-separated string.
*
* Support for this format was (soft) deprecated in PHPCS 3.3.0 and removed in PHPCS 4.0.0.
*
* @return void
*/
public function testUsingOldSchoolArrayFormatThrowsError()
{
$regex = '`^(';
$regex .= 'ERROR: Passing an array of values to a property using a comma-separated string\R';
$regex .= 'is no longer supported since PHP_CodeSniffer 4\.0\.0\.\R';
$regex .= 'The unsupported syntax was used for property "expectsOldSchool(?:EmptyArray|ArrayWith(?:Extended|Only)?(?:KeysAnd)?Values)"\R';
$regex .= 'for sniff "';
$regex .= '(?:\./tests/Core/Ruleset/Fixtures/TestStandard/Sniffs/SetProperty/PropertyTypeHandlingOldArrayFormatSniff\.php|TestStandard\.SetProperty\.PropertyTypeHandlingOldArrayFormat)';
$regex .= '"\.\R';
$regex .= 'Pass array values via <element \[key="\.\.\." \]value="\.\.\."> nodes instead\.\R';
$regex .= '){14}\R$`';

$this->expectRuntimeExceptionRegex($regex);

// Set up the ruleset.
$standard = __DIR__.'/PropertyTypeHandlingOldArrayFormatTest.xml';
$config = new ConfigDouble(["--standard=$standard"]);
new Ruleset($config);

}//end testUsingOldSchoolArrayFormatThrowsError()


}//end class
19 changes: 19 additions & 0 deletions tests/Core/Ruleset/PropertyTypeHandlingOldArrayFormatTest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?xml version="1.0"?>
<ruleset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="PropertyTypeHandlingOldArrayFormatTest" xsi:noNamespaceSchemaLocation="https://raw.githubusercontent.com/PHPCSStandards/PHP_CodeSniffer/master/phpcs.xsd">

<rule ref="./tests/Core/Ruleset/Fixtures/TestStandard/Sniffs/SetProperty/PropertyTypeHandlingOldArrayFormatSniff.php">
<properties>
<property name="expectsOldSchoolArrayWithOnlyValues" type="array" value="string, 10, 1.5, null, true, false" />

<property name="expectsOldSchoolArrayWithKeysAndValues" type="array" value="string=>string,10=>10,float=>1.5,null=>null,true=>true,false=>false" />

<property name="expectsOldSchoolArrayWithExtendedValues" type="array" value="string" />
<property name="expectsOldSchoolArrayWithExtendedValues" type="array" extend="true" value="15,another string" />

<property name="expectsOldSchoolArrayWithExtendedKeysAndValues" type="array" value="10=>10,string=>string" />
<property name="expectsOldSchoolArrayWithExtendedKeysAndValues" type="array" extend="true" value="15=>15,another string=>another string" />

<property name="expectsOldSchoolEmptyArray" type="array" value=""/>
</properties>
</rule>
</ruleset>
64 changes: 6 additions & 58 deletions tests/Core/Ruleset/PropertyTypeHandlingTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,35 +38,6 @@ final class PropertyTypeHandlingTest extends TestCase
const SNIFF_CLASS = 'Fixtures\\TestStandard\\Sniffs\\SetProperty\\PropertyTypeHandlingSniff';


/**
* Verify a deprecation notice is shown when an array property is set from the ruleset using a comma-separated string.
*
* Support for this format was (soft) deprecated in PHPCS 3.3.0.
*
* @return void
*/
public function testUsingOldSchoolArrayFormatShowsDeprecationNotice()
{
$regex = '`^(';
$regex .= 'DEPRECATED: Passing an array of values to a property using a comma-separated string\R';
$regex .= 'was deprecated in PHP_CodeSniffer 3\.3\.0\. Support will be removed in PHPCS 4\.0\.0\.\R';
$regex .= 'The deprecated syntax was used for property "expectsOldSchool(?:EmptyArray|ArrayWith(?:Extended|Only)?(?:KeysAnd)?Values)"\R';
$regex .= 'for sniff "';
$regex .= '(?:\./tests/Core/Ruleset/Fixtures/TestStandard/Sniffs/SetProperty/PropertyTypeHandlingSniff\.php|TestStandard\.SetProperty\.PropertyTypeHandling)';
$regex .= '"\.\R';
$regex .= 'Pass array values via <element \[key="\.\.\." \]value="\.\.\."> nodes instead\.\R';
$regex .= '){14}\R$`';

$this->expectOutputRegex($regex);

// Set up the ruleset.
$standard = __DIR__.'/PropertyTypeHandlingTest.xml';
$config = new ConfigDouble(["--standard=$standard"]);
new Ruleset($config);

}//end testUsingOldSchoolArrayFormatShowsDeprecationNotice()


/**
* Test the value type handling for properties set via a ruleset.
*
Expand Down Expand Up @@ -186,30 +157,18 @@ public static function dataTypeHandling()
'propertyName' => 'expectsBooleanFalseTrimmed',
'expected' => false,
],
'Array with only values (new style)' => [
'Array with only values' => [
'propertyName' => 'expectsArrayWithOnlyValues',
'expected' => $expectedArrayOnlyValues,
],
'Array with keys and values (new style)' => [
'Array with keys and values' => [
'propertyName' => 'expectsArrayWithKeysAndValues',
'expected' => $expectedArrayKeysAndValues,
],
'Empty array (new style)' => [
'Empty array' => [
'propertyName' => 'expectsEmptyArray',
'expected' => [],
],
'Array with only values (old style)' => [
'propertyName' => 'expectsOldSchoolArrayWithOnlyValues',
'expected' => $expectedArrayOnlyValues,
],
'Array with keys and values (old style)' => [
'propertyName' => 'expectsOldSchoolArrayWithKeysAndValues',
'expected' => $expectedArrayKeysAndValues,
],
'Empty array (old style)' => [
'propertyName' => 'expectsOldSchoolEmptyArray',
'expected' => [],
],
];

}//end dataTypeHandling()
Expand Down Expand Up @@ -239,22 +198,14 @@ public static function dataArrayPropertyExtending()
];

return [
'Array with only values extended (new style)' => [
'Array with only values extended' => [
'propertyName' => 'expectsArrayWithExtendedValues',
'expected' => $expectedArrayOnlyValuesExtended,
],
'Array with keys and values extended (new style)' => [
'Array with keys and values extended' => [
'propertyName' => 'expectsArrayWithExtendedKeysAndValues',
'expected' => $expectedArrayKeysAndValuesExtended,
],
'Array with only values extended (old style)' => [
'propertyName' => 'expectsOldSchoolArrayWithExtendedValues',
'expected' => $expectedArrayOnlyValuesExtended,
],
'Array with keys and values extended (old style)' => [
'propertyName' => 'expectsOldSchoolArrayWithExtendedKeysAndValues',
'expected' => $expectedArrayKeysAndValuesExtended,
],
];

}//end dataArrayPropertyExtending()
Expand All @@ -263,9 +214,6 @@ public static function dataArrayPropertyExtending()
/**
* Test Helper.
*
* Note: the deprecations for using comma-separated string to pass an array, are silenced in this helper
* as that's not what's being tested here.
*
* @see self::testTypeHandlingWhenSetViaRuleset()
*
* @return \PHP_CodeSniffer\Sniffs\Sniff
Expand All @@ -277,7 +225,7 @@ private function getSniffObjectForRuleset()
if (isset($sniffObject) === false) {
// Set up the ruleset.
$standard = __DIR__.'/PropertyTypeHandlingTest.xml';
$config = new ConfigDouble(["--standard=$standard", '-q']);
$config = new ConfigDouble(["--standard=$standard"]);
$ruleset = new Ruleset($config);

// Verify that our target sniff has been registered.
Expand Down
12 changes: 0 additions & 12 deletions tests/Core/Ruleset/PropertyTypeHandlingTest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -59,18 +59,6 @@
</property>

<property name="expectsEmptyArray" type="array"/>

<property name="expectsOldSchoolArrayWithOnlyValues" type="array" value="string, 10, 1.5, null, true, false" />

<property name="expectsOldSchoolArrayWithKeysAndValues" type="array" value="string=>string,10=>10,float=>1.5,null=>null,true=>true,false=>false" />

<property name="expectsOldSchoolArrayWithExtendedValues" type="array" value="string" />
<property name="expectsOldSchoolArrayWithExtendedValues" type="array" extend="true" value="15,another string" />

<property name="expectsOldSchoolArrayWithExtendedKeysAndValues" type="array" value="10=>10,string=>string" />
<property name="expectsOldSchoolArrayWithExtendedKeysAndValues" type="array" extend="true" value="15=>15,another string=>another string" />

<property name="expectsOldSchoolEmptyArray" type="array" value=""/>
</properties>
</rule>

Expand Down