-
-
Notifications
You must be signed in to change notification settings - Fork 494
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
Full property visibility/staticness review & fixing of custom property merging #841
Conversation
…set with an existing array. This method is specifically intended to handle PHPCS custom properties. This function allows for resetting as follows: * If a custom property is changed during a PHPCS run, the base array will be reset to its original value before the new custom property value is merged in. * If both a `$base` as well as a `$custom` parameter are passed and the `$custom` property value is boolean (`false`/`true`), the $base property will be returned. This is especially useful during unit testing where you want to be able to add some custom functions and then reset to the original base array afterwards. This is now possible by passing `false`. * Sometimes you want to just take advantage of the handling of comma delimited lists this function provides and overwrite the original value with the value returned by this function. That's why the `$base` parameter is optional and defaults to an empty array. If it was not, you could only add to the `$base` array and never overwrite it properly.
…ustom list merge handling.
* Change standard WP function list properties from static to non-static and change visibility to protected. * Change `$addedCustomFunctions` property to non-static and change to array format. * Split off the list merging to a separate function * Use new `merge_custom_array()` utility function * Move the list merging to a later point in time just before the lists are used. No need to do this earlier.
* Add two more custom function properties. This sniff uses the `is_only_sanitized()` method which calls the `is_sanitized()` method which uses the sanitization function lists, but there was no way to enhance them. * Change standard WP function list properties from static to non-static and change visibility to protected. * Change `$addedCustomFunctions` property to non-static, change visibility to protected and change to array format. * Split off the list merging to a separate function * Use new `merge_custom_array()` utility function * Move the list merging to a later point in time just before the lists are used. No need to do this earlier.
* Change standard WP function list properties from static to non-static and change visibility to protected. * Change `$addedCustomFunctions` property to non-static, change visibility to protected and change to array format. * Split off the list merging to a separate function * Use new `merge_custom_array()` utility function
* Extend the WordPress_Sniff * Revert the addition of the private list properties which was part of an earlier version of this fix (unreleased). * Change standard WP function list properties from static to non-static and change visibility to protected. * Change `$addedCustomFunctions` to array format. * Change `$methods` property to non-static. * Split off the list merging to a separate function * Use new `merge_custom_array()` utility function * Move the list merging to a later point in time just before the lists are used. No need to do this earlier.
* Change visibility for `$whitelisted_mixed_case_member_var_names` property to `protected`. * Copy in `merge_custom_array()` as this class extends an upstream sniff and therefore can't use the version include in `WordPress_Sniff`. * Use new `merge_custom_array()` utility function * Move the list merging to a later point in time just before the lists are used. No need to do this earlier.
Sniff properties which are `public` can be overruled via a custom ruleset. Sniff properties should therefore only be `public` if that is the intended behaviour. Otherwise a more restrictive visibility should be used. Changes to the visibility of properties *may* break backward compatibility for some users, but only if they were **_doing_it_wrong_** in the first place, so I'm not concerned about this. Notes: * Changed the visibility of some properties which shouldn't be changeable through the ruleset from `public` to `protected`. * Corrected the default value of one property - was float, should have been string. This property is used in a `version_compare()`, so string is the expected value type anyway. * Reviewed the internal handling of properties. - ControlStructureSpacing / `blank_line_check` and `blank_line_after_check`: PHPCS handles the casting to boolean already. For the compares, made sure they are done against "our" defaults, so that even if incorrectly set, the additional boolean cast is not necessary. - ControlStructureSpacing / `spaces_before_closure_open_paren`: moved the cast to int up instead of doing it three times. * Implemented use of the `exclude` property in the WPCS rulesets, includes correcting an invalid (outdated) exclusion in the `Extra` ruleset. * Removed the `$supportedTokenizers` property in the `WordPress_Sniffs_WhiteSpace_ControlStructureSpacingSniff` as it was set to the default value used by PHPCS anyway.
Why do we need to change from |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good.
Yes, I did a performance check. The merge_custom_array()
method might add a slight time hit. Potentially also a < 1 MB memory increase (2%) from these changes. I'm not worried by it. 😄
@@ -182,3 +182,27 @@ _deprecated_hook( 'some_filter', '1.3.0', esc_html__( 'The $arg is deprecated.' | |||
_deprecated_hook( "filter_{$context}", '1.3.0', __( 'The $arg is deprecated.' ), sprintf( __( 'Some parsed message %s', $variable ) ) ); // Bad. | |||
|
|||
echo add_filter( get_the_excerpt( get_the_ID() ) ; // Bad, but ignored as code contains a parse error. | |||
|
|||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Extra blank line here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
* | ||
* @var array | ||
*/ | ||
public $errorForSuperGlobals = array( '$_POST', '$_FILE' ); | ||
protected $errorForSuperGlobals = array( '$_POST', '$_FILE' ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I originally made these public so that they could be modified in custom rulesets. I don't know if anybody is using that feature, but it was intentional. The reason for letting them be completely overridden rather than just merging custom settings with the default lists is so that values could be removed and not just added. I haven't actually used that feature though, and I doubt anybody else has, so it is fine with me if we change these to protected
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got it. Thanks for explaining the history. I'm open to leaving these public
and adding them to the upcoming wiki page if you prefer.
I should probably have changed this already in #814. The errorcodes for these specific messages have changed, so the "old" codes won't work anymore. |
@@ -6,4 +6,10 @@ | |||
<rule ref="WordPress-Docs"/> | |||
<rule ref="WordPress-Extra"/> | |||
<rule ref="WordPress-VIP"/> | |||
|
|||
<rule ref="WordPress.PHP.DiscouragedPHPFunctions"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would add a comment here explaining why we are adding an exception or referencing to that they have been excluded from their respective rulesets.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point. Done.
@GaryJones Have you got an opinion on this PR or should I remove you as a reviewer ? |
Reviewed and approved. |
@GaryJones Great! Thanks. |
Primarily, this PR is a review of all sniff class properties and their handling.
I've broken up the PR into a number of isolated commits for easier review & having a clearer history for the various affected files.
tl;dr
This PR fixes/addresses a number of issues:
WordPress_Sniff
class #765 - static class properties in theWP_Sniff
classWordPress_Sniff
class #765 threadpublic
, but really should be madeprotected
as changing these from the ruleset would break the sniff or at the very least break the intention of the sniff.Pre-amble
Sniff properties which are
public
can be overruled via a custom ruleset.Sniff properties should therefore only be
public
if that is the intended behaviour. Otherwise a more restrictive visibility should be used.Changes to the visibility of properties may break backward compatibility for some users, but only if they were doing_it_wrong in the first place, so I'm not concerned about this.
Properties set via the ruleset will be handled by PHPCS as follows:
type=array
attribute - will be converted to arrays. PHPCS has the ability to handle key/value arrays if the property is set using the following syntax:key=>value,key2=>value2
true
orfalse
, the property value will be cast to a boolean value before it's set.What this PR changes/fixes
This helper function is a little bit "magical".
type=array
bit when adding a property in a custom ruleset.base
array to merge the custom property with is passed, it expects the base array to be set up asvalue => true
to allow for usingisset()
instead ofin_array()
. Only one existing array needed to be changed to allow for this$test_class_whitelist
.false
as the third param).false
. This has no impact when usingisset()
, but allows us to filter out anything added for a previous custom property value if the custom property would be overruled inline in a file. This in turn allows us to unit test the custom properties.$added_custom_properties
setting to keep track of whether the custom properties had been merged in. Some of these static pre-set properties however would be used by several sniffs and could therefore be using a "contaminated" value. Also, the fact that the custom properties were only merged in once, prevented changing these values inline using the@codingStandardsChangeSetting
syntax, which prevented unit testing them.I've fixed this by:
$added_custom_properties
property into an array to keep track of the previous merged in value(s) instead of being a true/false toggle.Additional notes:
array_fill_keys()
function which was only introduced in PHP 5.2. This means that the minimum PHP requirement for WPCS has to go up to PHP 5.2. Considering that's an ancient version, I don't think this will cause any issues. Just to be sure, I have added this info to the requirements section of the readme.$minimum_supported_version
in WP/DeprecatedFunctions). This property is used in aversion_compare()
, so string is the expected value type anyway and would be the type if the property is overruled from the ruleset as well.blank_line_check
andblank_line_after_check
: PHPCS handles the casting to boolean already. For the compares, made sure they are done against "our" defaults, so that even if incorrectly set, the additional boolean cast is not necessary.spaces_before_closure_open_paren
: moved the cast to int up instead of doing it three times.exclude
property in the WPCS rulesets, includes correcting an invalid (outdated) exclusion in theExtra
ruleset.$supportedTokenizers
property in theWordPress_Sniffs_WhiteSpace_ControlStructureSpacingSniff
as it was set to the default value used by PHPCS anyway.is_only_sanitized()
method which calls theis_sanitized()
method which uses the sanitization function lists, but there was no way to enhance them. Added the relevant custom properties to enable enhancing them for that specific sniff.WP_Sniff
class, but should do so within the new structure. Changed the sniff to leverage the properties of theWP_Sniff
class as well.The PR includes unit tests for all custom properties which weren't unit tested before now.
Question:
$errorForSuperGlobals
and$warnForSuperGlobals
properties public ? That was the one set of properties I was in doubt about changing the visibility for.Open issue/question:
What should be the value for the
exclude
property in the overallWordPress
ruleset for theWordPress.PHP.DiscouragedPHPFunctions
sniff ? Or should nothing be excluded ?The
Extra
ruleset excludescreate_function
, theVIP
ruleset excludesobfuscation
. Based on that, I would suggest adding them both to theWordPress
ruleset to maintain the same behaviour as before.Technical details:
Previously, the excludes were done via the
<exclude..
syntax, not by using theexclude
property. As theWordPress
ruleset includes both these ruleset, both excludes where set for the overall ruleset.With this PR, the excludes will be done via the
exclude
property instead. The properties in ruleset are not cumulative, but overrule each other. That means that in effect theWordPress
ruleset would now only exclude theobfuscation
group as that's the value set in the last ruleset included (VIP).Setting the
exclude
property to both from within theWordPress
ruleset will maintain the old behaviour.However, a case could be made to exclude nothing if the overall
WordPress
ruleset is used, which is why I'm making a point of putting this up for discussion.Closes #765
Closes #839