1313
1414use  PHP_CodeSniffer \Exceptions \RuntimeException ;
1515use  PHP_CodeSniffer \Util ;
16+ use  stdClass ;
1617
1718class  Ruleset
1819{
@@ -960,6 +961,11 @@ private function processRule($rule, $newSniffs, $depth=0)
960961            if  (isset ($ rule ->properties ) === true 
961962                && $ this  ->shouldProcessElement ($ rule ->properties ) === true 
962963            ) {
964+                 $ propertyScope  = 'standard ' ;
965+                 if  ($ code  === $ ref  || substr ($ ref , -9 ) === 'Sniff.php ' ) {
966+                     $ propertyScope  = 'sniff ' ;
967+                 }
968+ 
963969                foreach  ($ rule ->properties ->property  as  $ prop ) {
964970                    if  ($ this  ->shouldProcessElement ($ prop ) === false ) {
965971                        continue ;
@@ -980,9 +986,9 @@ private function processRule($rule, $newSniffs, $depth=0)
980986                        $ values  = [];
981987                        if  (isset ($ prop ['extend ' ]) === true 
982988                            && (string ) $ prop ['extend ' ] === 'true ' 
983-                             && isset ($ this  ->ruleset [$ code ]['properties ' ][$ name ]) === true 
989+                             && isset ($ this  ->ruleset [$ code ]['properties ' ][$ name ][ ' value ' ] ) === true 
984990                        ) {
985-                             $ values  = $ this  ->ruleset [$ code ]['properties ' ][$ name ];
991+                             $ values  = $ this  ->ruleset [$ code ]['properties ' ][$ name ][ ' value ' ] ;
986992                        }
987993
988994                        if  (isset ($ prop ->element ) === true ) {
@@ -1017,7 +1023,10 @@ private function processRule($rule, $newSniffs, $depth=0)
10171023                            }
10181024                        }//end if 
10191025
1020-                         $ this  ->ruleset [$ code ]['properties ' ][$ name ] = $ values ;
1026+                         $ this  ->ruleset [$ code ]['properties ' ][$ name ] = [
1027+                             'value '  => $ values ,
1028+                             'scope '  => $ propertyScope ,
1029+                         ];
10211030                        if  (PHP_CODESNIFFER_VERBOSITY  > 1 ) {
10221031                            echo  str_repeat ("\t" , $ depth );
10231032                            echo  "\t\t=> array property  \"$ name \" set to  \"$ printValue \"" ;
@@ -1028,7 +1037,10 @@ private function processRule($rule, $newSniffs, $depth=0)
10281037                            echo  PHP_EOL ;
10291038                        }
10301039                    } else  {
1031-                         $ this  ->ruleset [$ code ]['properties ' ][$ name ] = (string ) $ prop ['value ' ];
1040+                         $ this  ->ruleset [$ code ]['properties ' ][$ name ] = [
1041+                             'value '  => (string ) $ prop ['value ' ],
1042+                             'scope '  => $ propertyScope ,
1043+                         ];
10321044                        if  (PHP_CODESNIFFER_VERBOSITY  > 1 ) {
10331045                            echo  str_repeat ("\t" , $ depth );
10341046                            echo  "\t\t=> property  \"$ name \" set to  \"" .(string ) $ prop ['value ' ].'" ' ;
@@ -1218,8 +1230,8 @@ public function populateTokenListeners()
12181230
12191231            // Set custom properties. 
12201232            if  (isset ($ this  ->ruleset [$ sniffCode ]['properties ' ]) === true ) {
1221-                 foreach  ($ this  ->ruleset [$ sniffCode ]['properties ' ] as  $ name  => $ value  ) {
1222-                     $ this  ->setSniffProperty ($ sniffClass , $ name , $ value  );
1233+                 foreach  ($ this  ->ruleset [$ sniffCode ]['properties ' ] as  $ name  => $ settings  ) {
1234+                     $ this  ->setSniffProperty ($ sniffClass , $ name , $ settings  );
12231235                }
12241236            }
12251237
@@ -1286,18 +1298,76 @@ public function populateTokenListeners()
12861298     * 
12871299     * @param string $sniffClass The class name of the sniff. 
12881300     * @param string $name       The name of the property to change. 
1289-      * @param string $value       The  new value of the property. 
1301+      * @param array  $settings    Array with the  new value of the property and the scope of the property being set . 
12901302     * 
12911303     * @return void 
1304+      * 
1305+      * @throws \PHP_CodeSniffer\Exceptions\RuntimeException When attempting to set a non-existent property on a sniff 
1306+      *                                                      which doesn't declare the property or explicitly supports 
1307+      *                                                      dynamic properties. 
12921308     */ 
1293-     public  function  setSniffProperty ($ sniffClass , $ name , $ value  )
1309+     public  function  setSniffProperty ($ sniffClass , $ name , $ settings  )
12941310    {
12951311        // Setting a property for a sniff we are not using. 
12961312        if  (isset ($ this  ->sniffs [$ sniffClass ]) === false ) {
12971313            return ;
12981314        }
12991315
1300-         $ name  = trim ($ name );
1316+         $ name          = trim ($ name );
1317+         $ propertyName  = $ name ;
1318+         if  (substr ($ propertyName , -2 ) === '[] ' ) {
1319+             $ propertyName  = substr ($ propertyName , 0 , -2 );
1320+         }
1321+ 
1322+         /* 
1323+          * BC-compatibility layer for $settings using the pre-PHPCS 3.8.0 format. 
1324+          * 
1325+          * Prior to PHPCS 3.8.0, `$settings` was expected to only contain the new _value_ 
1326+          * for the property (which could be an array). 
1327+          * Since PHPCS 3.8.0, `$settings` is expected to be an array with two keys: 'scope' 
1328+          * and 'value', where 'scope' indicates whether the property should be set to the given 'value' 
1329+          * for one individual sniff or for all sniffs in a standard. 
1330+          * 
1331+          * This BC-layer is only for integrations with PHPCS which may call this method directly 
1332+          * and will be removed in PHPCS 4.0.0. 
1333+          */ 
1334+ 
1335+         if  (is_array ($ settings ) === false 
1336+             || isset ($ settings ['scope ' ], $ settings ['value ' ]) === false 
1337+         ) {
1338+             // This will be an "old" format value. 
1339+             $ settings  = [
1340+                 'value '  => $ settings ,
1341+                 'scope '  => 'standard ' ,
1342+             ];
1343+ 
1344+             trigger_error (
1345+                 __FUNCTION__ .': the format of the $settings parameter has changed from (mixed) $value to array( \'scope \' =>  \'sniff|standard \',  \'value \' => $value). Please update your integration code. See PR #3629 for more information. ' ,
1346+                 E_USER_DEPRECATED 
1347+             );
1348+         }
1349+ 
1350+         $ isSettable   = false ;
1351+         $ sniffObject  = $ this  ->sniffs [$ sniffClass ];
1352+         if  (property_exists ($ sniffObject , $ propertyName ) === true 
1353+             || ($ sniffObject  instanceof  stdClass) === true 
1354+             || method_exists ($ sniffObject , '__set ' ) === true 
1355+         ) {
1356+             $ isSettable  = true ;
1357+         }
1358+ 
1359+         if  ($ isSettable  === false ) {
1360+             if  ($ settings ['scope ' ] === 'sniff ' ) {
1361+                 $ notice   = "Ruleset invalid. Property  \"$ propertyName \" does not exist on sniff  " ;
1362+                 $ notice  .= array_search ($ sniffClass , $ this  ->sniffCodes , true );
1363+                 throw  new  RuntimeException ($ notice );
1364+             }
1365+ 
1366+             return ;
1367+         }
1368+ 
1369+         $ value  = $ settings ['value ' ];
1370+ 
13011371        if  (is_string ($ value ) === true ) {
13021372            $ value  = trim ($ value );
13031373        }
@@ -1312,7 +1382,7 @@ public function setSniffProperty($sniffClass, $name, $value)
13121382        } else  if  ($ value  === 'false ' ) {
13131383            $ value  = false ;
13141384        } else  if  (substr ($ name , -2 ) === '[] ' ) {
1315-             $ name    = substr ( $ name ,  0 , - 2 ) ;
1385+             $ name    = $ propertyName  ;
13161386            $ values  = [];
13171387            if  ($ value  !== null ) {
13181388                foreach  (explode (', ' , $ value ) as  $ val ) {
@@ -1328,7 +1398,7 @@ public function setSniffProperty($sniffClass, $name, $value)
13281398            $ value  = $ values ;
13291399        }
13301400
1331-         $ this -> sniffs [ $ sniffClass ] ->$ name  = $ value ;
1401+         $ sniffObject  ->$ name  = $ value ;
13321402
13331403    }//end setSniffProperty() 
13341404
0 commit comments