Skip to content

✨ New WordPress.WP.OptionAutoload sniff #2520

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

Open
wants to merge 8 commits into
base: develop
Choose a base branch
from

Conversation

rodrigoprimo
Copy link
Collaborator

This sniff warns users about missing $autoload parameter when calling relevant WordPress option functions.

It includes tests and sniff documentation in the XML format.

Closes #2473

Sniff behavior

The sniff runs when the following functions are found in the code:

  • add_option( $option, $value = '', $deprecated = '', $autoload = null)
  • update_option( $option, $value, $autoload = null )
  • wp_set_options_autoload( $options, $autoload )
  • wp_set_option_autoload( $option, $autoload )
  • wp_set_option_autoload_values( $options )

For add_option() and update_option(), if the $autoload parameter is not passed, it simply recommends passing it. For the other three functions, the $autoload parameter (or $options parameter in the case of wp_set_option_autoload_values()) is mandatory, so it is not needed to check if the parameter is omitted.

If the $autoload parameter is passed and is true|false|null for add_option() and update_option() or true|false for wp_set_options_autoload(), wp_set_option_autoload() and wp_set_option_autoload_values(), the sniff stays silent as those are valid values.

If the $autoload parameter is passed and is 'yes'|'no', the sniff flags as discouraged parameter values and auto-fixes to true|false.

For the internal-use only values of the $autoload parameter, if the value is 'auto'|'auto-on'|'auto-off' the sniff flags it as unsupported without auto-fixing. If the value is 'on'|'off', the sniff flags it as unsupported and auto-fixes to true|false.

Any other value passed is flagged as unsupported, and a list of supported values is provided.

Open questions

I'm unsure about a few choices that I made in the XML documentation and could use some feedback on the following:

  • I opted to include a link to a document explaining how to decide which value to use for the $autoload parameter. Since I could not find something wp.org, I ended up linking to a post written by a core committer in their blog. I'm not sure if this is a problem or not.
  • Maybe combining the <standard> blocks for invalid, deprecated, and internal-only values in a single block would be better? I created a block for each, but there is some repetition in the block description and the valid examples.
  • I added a <standard> block without code examples at the top with a general description of what the sniff does before creating blocks for each of the warnings generated by the sniff.

This sniff warns users about missing `$autoload` parameter when calling relevant WordPress option functions.

The sniff runs when the following functions are found in the code:
  - add_option( $option, $value = '', $deprecated = '', $autoload = null)
  - update_option( $option, $value, $autoload = null )
  - wp_set_options_autoload( $options, $autoload )
  - wp_set_option_autoload( $option, $autoload )
  - wp_set_option_autoload_values( $options )

For `add_option()` and `update_option()`, if the `$autoload` parameter is not passed, it simply recommends passing it. For the other three functions, the `$autoload` parameter (or `$options` parameter in the case of `wp_set_option_autoload_values()`) is mandatory, so it is not needed to check if the parameter is omitted.

If the `$autoload` parameter is passed and is `true|false|null` for `add_option()` and `update_option()` or `true|false` for `wp_set_options_autoload()`, `wp_set_option_autoload()` and `wp_set_option_autoload_values()`, the sniff stays silent as those are valid values.

If the `$autoload` parameter is passed and is `'yes'|'no'`, the sniff flags as discouraged parameter values and auto-fixes to `true|false`.

For the internal-use only values of the `$autoload` parameter, if the value is `'auto'|'auto-on'|'auto-off'` the sniff flags it as unsupported without auto-fixing. If the value is `'on'|'off'`, the sniff flags it as unsupported and auto-fixes to `true|false`.

Any other value passed is flagged as an unsupported value and a list of supported values is provided.

The sniff ignores the function call when it is not able to determine the value of the `$autoload` parameter. For example, when a variable or a constant is passed.
@dingo-d
Copy link
Member

dingo-d commented Feb 27, 2025

I opted to include a link to a document explaining how to decide which value to use for the $autoload parameter. Since I could not find something wp.org, I ended up linking to a post written by a core committer in their blog. I'm not sure if this is a problem or not.

The only problem is that that is not official documentation. And if their site goes down, you have a dead link in the documentation.

I added a block without code examples at the top with a general description of what the sniff does before creating blocks for each of the warnings generated by the sniff.

Does the validation passes against the phpcsdocs.xsd?

Copy link
Member

@jrfnl jrfnl left a comment

Choose a reason for hiding this comment

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

@rodrigoprimo Thank you for working on this.

I've so far only done a first pass reading through it (without running the sniff/docs etc), but seeing the amount of remarks I've already left, I figured I should give you the chance to iterate on the current state before continuing my review.

$this->phpcsFile->recordMetric( $stackPtr, self::METRIC_NAME, 'param missing' );

// Only display a warning for the functions in which the `$autoload` parameter is optional.
if ( in_array( $function_name, self::$autoload_is_optional, true ) ) {
Copy link
Member

Choose a reason for hiding this comment

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

  1. Function names are case-insensitive. Without the change in the docblock, it is not immediately apparent this will be handled correctly.
  2. Please change the $autoload_is_optional array to 'name' => true format and check using isset() for a small performance improvement.
    ☝🏻 This second point should be fixed in quite a few places in this sniff.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Good point. I believe we discussed this already in the past and I failed to take it into account while creating this sniff. I will think a bit more about how to implement this in the other places and get back to you.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Please change the $autoload_is_optional array to 'name' => true format and check using isset() for a small performance improvement.
☝🏻 This second point should be fixed in quite a few places in this sniff.

I implemented this change in all the places that seemed relevant to me. For $valid_values_add_and_update and $valid_values_other_functions, I used the same format as what is used in the \PHPCSUtils\Tokens\Collections properties and repeated the value in the index of each element of the array. I opted to do this to avoid calling array_keys() when passing $valid_values to array_map():

$valid_values = array_map(
function ( $value ) {
return '`' . $value . '`';
},
$valid_values
);

Copy link
Member

Choose a reason for hiding this comment

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

These tests could probably use some more variation in whitespace and comments/annotations in unexpected places.
Some more tests with function name case variations (especially for the "okay"/ignored tests) would also not go amiss.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I will create more tests and push a new commit in the next few days.

Copy link
Member

Choose a reason for hiding this comment

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

I don't think you need more tests. Probably just updating some of the existing tests to include those variations would be enough.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I updated some of the tests to add more variation in whitespace, comments/annotations in unexpected places, and function names using different cases.

rodrigoprimo and others added 2 commits February 28, 2025 17:47
@rodrigoprimo
Copy link
Collaborator Author

Thanks for your review, @dingo-d and @jrfnl! I believe I addressed all of your comments except two that are still pending, and I will need a bit more time (#2520 (comment) and #2520 (comment)).

The only problem is that that is not official documentation. And if their site goes down, you have a dead link in the documentation.

That makes sense. As @jrfnl suggested, I removed the paragraph that included this link.

Does the validation passes against the phpcsdocs.xsd?

I believe so. This is how I tested:

$ xmllint --schema phpcsdocs.xsd WordPress/Docs/WP/OptionAutoloadStandard.xml --noout 
WordPress/Docs/WP/OptionAutoloadStandard.xml validates

Let me know if I'm missing something.

@rodrigoprimo
Copy link
Collaborator Author

@jrfnl, I addressed the two points that were pending. Could you please take another look at this PR when you get a chance?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add sniff to warn about missing $autoload parameter when calling relevant WordPress option functions
3 participants