Provide links to further documentation for reported errors
I've heard from some users that error messages they get from Plugin Check are not always very useful and lack further explanation.
I think it would be helpful to point to resources such as https://developer.wordpress.org/plugins and https://learn.wordpress.org/ where applicable. In some cases new documentation might need to be written and error messages expanded a bit.
Hello, We are already doing that in our check reviews. We can provide that info if we have some place to do it. The best way would be an accordion with all information about the check.
That sounds great! The more pre-existing documentation we can use, the better. Let's start assembling that in a spreadsheet or so? 1 description/documentation/explanation per check class. Ideally the text itself is relatively short and links to the plugin handbook for further information.
Every check class could then have a new get_description() method. Then we need to come up with a good way to show this description in both the admin UI and when using via WP-CLI. Ideally not to repetitive.
Maybe in the admin a <details> block below the error message is an OK start as a proof of concept?
Hello, it's an HTML content. It would be a work to move it in the excel, and then to the plugin. I think it's better to say where is going to be saved, and we can pass all explanations when we have time.
I see. Well, my suggestion would be for every check to have a get_description() method (and that method to be defined in the Check interface. That can contain HTML, no problem. I'd just suggest that this description should be relatively short (1 paragraph) and a longer version (if there is one) should live in the plugin handbook. Does that make sense?
No, they are some long with links and documentation. That gives the user all the information to explain it and solve it. So, that's why I suggest an accordion or something similar.
If the long form documentation lives in the handbook or some other website, it's much easier to update and share, without having to release a new plugin version every time you fix a typo. It also makes it easier to read the documentation without first having to run the checks :)
But if you prefer to have all of that in the plugin we can figure something out as well, be it an accordion or something else.
Let's start by assembling the content here — in whatever form you prefer — and we can go from there.
I can give you some example:
## Generic function/class/define/namespace/option names
All plugins must have unique function names, namespaces, defines, class and option names. This prevents your plugin from conflicting with other plugins or themes. We need you to update your plugin to use more unique and distinct names.
A good way to do this is with a prefix. For example, if your plugin is called "Easy Custom Post Types" then you could use names like these:
function ecpt_save_post()
define( 'ECPT_LICENSE', true );
class ECPT_Admin{}
namespace ECPT;
update_option( 'ecpt_settings', $settings );
Don't try to use two (2) or three (3) letter prefixes anymore. We host nearly 100-thousand plugins on WordPress.org alone. There are tens of thousands more outside our servers. Believe us, you’re going to run into conflicts.
You also need to avoid the use of __ (double underscores), wp_ , or _ (single underscore) as a prefix. Those are reserved for WordPress itself. You can use them inside your classes, but not as stand-alone function.
Please remember, if you're using _n() or __() for translation, that's fine. We're only talking about functions you've created for your plugin, not the core functions from WordPress. In fact, those core features are why you need to not use those prefixes in your own plugin! You don't want to break WordPress for your users.
Related to this, using if (!function_exists('NAME')) { around all your functions and classes sounds like a great idea until you realize the fatal flaw. If something else has a function with the same name and their code loads first, your plugin will break. Using if-exists should be reserved for shared libraries only.
Remember: Good prefix names are unique and distinct to your plugin. This will help you and the next person in debugging, as well as prevent conflicts.
Analysis result:
or another:
## Variables and options must be escaped when echo'd
Much related to sanitizing everything, all variables that are echoed need to be escaped when they're echoed, so it can't hijack users or (worse) admin screens. There are many esc_*() functions you can use to make sure you don't show people the wrong data, as well as some that will allow you to echo HTML safely.
At this time, we ask you escape all $-variables, options, and any sort of generated data when it is being echoed. That means you should not be escaping when you build a variable, but when you output it at the end. We call this 'escaping late.'
Besides protecting yourself from a possible XSS vulnerability, escaping late makes sure that you're keeping the future you safe. While today your code may be only outputted hardcoded content, that may not be true in the future. By taking the time to properly escape when you echo, you prevent a mistake in the future from becoming a critical security issue.
This remains true of options you've saved to the database. Even if you've properly sanitized when you saved, the tools for sanitizing and escaping aren't interchangeable. Sanitizing makes sure it's safe for processing and storing in the database. Escaping makes it safe to output.
Also keep in mind that sometimes a function is echoing when it should really be returning content instead. This is a common mistake when it comes to returning JSON encoded content. Very rarely is that actually something you should be echoing at all. Echoing is because it needs to be on the screen, read by a human. Returning (which is what you would do with an API) can be json encoded, though remember to sanitize when you save to that json object!
There are a number of options to secure all types of content (html, email, etc). Yes, even HTML needs to be properly escaped.
https://developer.wordpress.org/apis/security/escaping/
Remember: You must use the most appropriate functions for the context. There is pretty much an option for everything you could echo. Even echoing HTML safely.
Example(s) from your plugin:
..
Note: The functions _e and _ex outputs the translation without escaping, please use an alternative function that escapes the output.
An alternative to _e would be esc_html_e , esc_attr_e or simply using __ wrapped by a escaping function and inside an echo .
An alternative to _ex would be using _x wrapped by a escaping function and inside an echo .
Examples:
<h2><?php esc_html_e('Settings page', 'plugin-slug'); ?></h2>
<h2><?php echo esc_html(__('Settings page', 'plugin-slug')); ?></h2>
<h2><?php echo esc_html(_x('Settings page', 'Settings page title', 'plugin-slug')); ?></h2>
Example(s) from your plugin:
..
So, you can see how they are.
These are perfect for putting them on a web page somewhere. Makes it easier to update them.
I created a quick POC over at #461.
See also related discussion in #448.
We have discussed in our Team yesterday and we were agree to make a section in the Developer HandBook for our checks. The PR gives the solution to give context for the Checks, but not individually. We should work on that.
Related with PR in Developer Documentation #21
We have to work where to show the description and URL in admin and cli.
Related #562
Solved #563