Skip to content
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

WP Plugin Review #3

Closed
HardeepAsrani opened this issue Aug 16, 2024 · 0 comments
Closed

WP Plugin Review #3

HardeepAsrani opened this issue Aug 16, 2024 · 0 comments
Assignees
Labels
enhancement Propose enhancement to a feature

Comments

@HardeepAsrani
Copy link
Member

Hello,

Thanks for uploading your plugin, we can begin with the review. We are a group of volunteers who help you identify common issues so that you can make your plugin more secure, compatible, reliable and compliant with the guidelines.

There are issues with your plugin code preventing it from being approved immediately. We have pended your submission in order to help you correct all issues so that it may be approved and published.

We ask you read this email in its entirety, address all listed issues, and reply to this email after uploading a corrected version of your code. Failure to do so will result in your review being delayed or even rejected.

We know this email can be long, but we kindly ask you to be meticulous in fixing the issues we mention so that we can make the best use of our volunteer time and get your plugin approved as soon as possible.

Remember that in addition to code quality, security and functionality, we require all plugins to adhere to our guidelines. If you have not yet, please read them: https://developer.wordpress.org/plugins/wordpress-org/detailed-plugin-guidelines/

Finally, should you at any time wish to alter your permalink (aka the plugin slug), you must explicitly tell us what you want it to be. Just changing the display name is not sufficient, and we require to you clearly state your desired permalink. Remember, permalinks cannot be altered after approval.

Be aware that you will not be able to submit another plugin while this one is being reviewed.

Incorrect Stable Tag

In your readme, your 'Stable Tag' does not match the Plugin Version as indicated in your main plugin file.

ERROR: Stable tag shall not be trunk
hyve-lite.php - Version: 1.1.0

Your Stable Tag is meant to be the stable version of your plugin, not of WordPress. For your plugin to be properly downloaded from WordPress.org, those values need to be the same. If they're out of sync, your users won't get the right version of your code.

We recommend you use Semantic Versioning (aka SemVer) for managing versions:

https://en.wikipedia.org/wiki/Software_versioning
https://semver.org/

Please note: While currently using the stable tag of trunk currently works in the Plugin Directory, it's not actually a supported or recommended method to indicate new versions and has been known to cause issues with automatic updates.

We ask you please properly use tags and increment them when you release new versions of your plugin, just like you update the plugin version in the main file. Having them match is the best way to be fully forward supporting.

Using composer but could not find composer.json file

We noticed that your plugin is using Composer to handle library dependencies, that's great as it will help maintaining and updating your plugin in the future while avoiding collisions with other plugins that are using same libraries.

The composer.json file describes the dependencies of your project and may contain other metadata as well. It's a small file that typically can be found in the top-most directory of your plugin.

As one of the strengths of open source is the ability to review, observe, and adapt code, we would like to ask you to include that file in your plugin, even if it is only used for development purposes. This will allow others to exercise the open source freedoms from which we all benefit.

From your plugin:

composer.json file not found in "hyve-lite/composer.json"

Not permitted files

A plugin typically consists of files related to the plugin functionality (php, js, css, txt, md) and maybe some multimedia files (png, svg, jpg) and / or data files (json, xml).

We have detected files that are not among of the files normally found in a plugin, are they necessary? If not, then those won't be allowed.

Example(s) from your plugin:

hyve-lite/.browserslintrc

No publicly documented resource for your compressed content

In reviewing your plugin, we cannot find a non-compiled version of your javascript and/or css related source code.

In order to comply with our guidelines of human-readable code, we require you to include the source code and / or a link to the non-compressed, developer libraries you’ve included in your plugin. If you include a link, this may be in your source code, however we require you to also have it in your readme.

https://developer.wordpress.org/plugins/wordpress-org/detailed-plugin-guidelines/#4-code-must-be-mostly-human-readable

We strongly feel that one of the strengths of open source is the ability to review, observe, and adapt code. By maintaining a public directory of freely available code, we encourage and welcome future developers to engage with WordPress and push it forward.

That said, with the advent of larger and larger plugins using more complex libraries, people are making good use of build tools (such as composer or npm) to generate their distributed production code. In order to balance the need to keep plugin sizes smaller while still encouraging open source development, we require plugins to make the source code to any compressed files available to the public in an easy to find location, by documenting it in the readme.

For example, if you’ve made a Gutenberg plugin and used npm and webpack to compress and minify it, you must either include the source code within the published plugin or provide access to a public maintained source that can be reviewed, studied, and yes, forked.

We strongly recommend you include directions on the use of any build tools to encourage future developers.

From your plugin:

hyve-lite/build/backend/index.js:1 ...,2:[function(I,G,l){(function(I,G,b,Z,W,c,N,d,Y){!function(I){"use strict";var G="undefined"!=typeof Uint8Array?Uint8Array:Array,l="+".charCodeAt(0),b="/".charCodeAt(0),Z="0".charCodeAt(0),W="a".charC...
hyve-lite/build/frontend/frontend.js:1 ...a.o(e,i)&&e[i]&&e[i]0,e[i]=0;return a.O(l)},s=globalThis.webpackChunkhyve_lite=globalThis.webpackChunkhyve_lite||[];s.forEach(t.bind(null,0)),s.push=t.bind(null,s.push.bind(s))})();var o=a.O(void ...

Use wp_enqueue commands

Your plugin is not correctly including JS and/or CSS. You should be using the built in functions for this:

When including JavaScript code you can use:
wp_register_script() and wp_enqueue_script() to add JavaScript code from a file.
wp_add_inline_script() to add inline JavaScript code to previous declared scripts.

When including CSS you can use:
wp_register_style() and wp_enqueue_style() to add CSS from a file.
wp_add_inline_style() to add inline CSS to previously declared CSS.

Note that as of WordPress 5.7, you can pass attributes like async, nonce, and type by using new functions and filters: https://make.wordpress.org/core/2021/02/23/introducing-script-attributes-related-functions-in-wordpress-5-7/

If you're trying to enqueue on the admin pages you'll want to use the admin enqueues.

https://developer.wordpress.org/reference/hooks/admin_enqueue_scripts/
https://developer.wordpress.org/reference/hooks/admin_print_scripts/
https://developer.wordpress.org/reference/hooks/admin_print_styles/

Example(s) from your plugin:

hyve-lite/inc/Main.php:269 <script>

Undocumented use of a 3rd Party or external service

We permit plugins to require the use of 3rd party (i.e. external) services, provided they are properly documented in a clear manner.

We require plugins that reach out to other services to disclose this, in clear and plain language, so users are aware of where data is being sent. This allows them to ensure that any legal issues with data transmissions are covered. This is true even if you are the 3rd party service.

In order to do so, you must update your readme to do the following:
Clearly explain that your plugin is relying on a 3rd party as a service and under what circumstances
Provide a link to the service .
Provide a link to the service terms of use and/or privacy policies.
Remember, this is for your own legal protection. Use of services must be upfront and well documented.

Example(s) from your plugin:

Domain(s) not mentioned in the readme file.

hyve-lite/inc/OpenAI.php:21 private static $base_url = 'https://api.openai.com/v1/';

Internationalization: Text domain does not match plugin slug.

In order to make a string translatable in your plugin you are using a set of special functions. These functions collectively are known as "gettext".

These functions have a parameter called "text domain", which is a unique identifier for retrieving translated strings.

This "text domain" must be the same as your plugin slug so that the plugin can be translated by the community using the tools provided by the directory. As for example, if this plugin slug is penfold-macrame the Internationalization functions should look like:
esc_html__('Hello', 'penfold-macrame');

From your plugin, you have set your text domain as follows:

This plugin is using the domain "hyve" for 36 element(s).

However, the current plugin slug is this:

hyve-lite

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()
class ECPT_Admin{}
namespace ECPT;
update_option( 'ecpt_settings', $settings );
define( 'ECPT_LICENSE', true );
global $ecpt_options;

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:

This plugin is using the prefix "themeisle_hyvelite" for 1 element(s).

This plugin is using the prefix "hyve" for 19 element(s).

Looks like there are elements not using common prefixes.

hyve-lite/inc/Main.php:259 apply_filters('product_hyve_license_status', false);
hyve-lite/inc/DB_Table.php:85 update_option($this->table_name . '_db_version', $this->version);
hyve-lite/inc/DB_Table.php:362 set_transient($chunk_key, $chunk, $expiration);

↳ Detected name: _

hyve-lite/inc/DB_Table.php:365 set_transient($key . '_total', $total, $expiration);

Allowing Direct File Access to plugin files

Direct file access is when someone directly queries your file. This can be done by simply entering the complete path to the file in the URL bar of the browser but can also be done by doing a POST request directly to the file. For files that only contain a PHP class the risk of something funky happening when directly accessed is pretty small. For files that contain procedural code, functions and function calls, the chance of security risks is a lot bigger.

You can avoid this by putting this code at the top of all PHP files that could potentially execute code if accessed directly :
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly

Example(s) from your plugin:

hyve-lite/build/block/render.php:10

Unsafe SQL calls

When making database calls, it's highly important to protect your code from SQL injection vulnerabilities. You need to update your code to use wpdb calls and prepare() with your queries to protect them.

Please review the following:
https://developer.wordpress.org/reference/classes/wpdb/#protect-queries-against-sql-injection-attacks
https://codex.wordpress.org/Data_Validation#Database
https://make.wordpress.org/core/2012/12/12/php-warning-missing-argument-2-for-wpdb-prepare/
https://ottopress.com/2013/better-know-a-vulnerability-sql-injection/
Example(s) from your plugin:

hyve-lite/inc/DB_Table.php:234 $query = $wpdb->prepare( "SELECT * FROM {$this->table_name} WHERE post_status = %s LIMIT %d", $status, $limit ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared

hyve-lite/inc/DB_Table.php:236 $results = $wpdb->get_results( $query ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
-----> $wpdb->get_results($query)

  • There is a call to a wpdb::prepare() function, that's correct.
  • You cannot add variables like "$this->table_name" directly to the SQL query.
  • Using wpdb::prepare($query, $args) you will need to include placeholders for each variable within the query and include the variables in the second parameter.

hyve-lite/inc/DB_Table.php:295 $query = "SELECT COUNT(*) FROM {$this->table_name}";
hyve-lite/inc/DB_Table.php:297 $count = $wpdb->get_var( $query ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
-----> $wpdb->get_var($query)

  • You cannot add variables like "$this->table_name" directly to the SQL query. You need to use wpdb::prepare.
  • Remember that using wpdb::prepare($query, $args) you will need to include placeholders for each variable within the query and include the variables in the second parameter.
  • The SQL query needs to be included in a wpdb::prepare($query, $args) function.
@HardeepAsrani HardeepAsrani added the enhancement Propose enhancement to a feature label Aug 16, 2024
@HardeepAsrani HardeepAsrani self-assigned this Aug 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Propose enhancement to a feature
Projects
None yet
Development

No branches or pull requests

1 participant