Question

I am working on a plugin that provides an endpoint for handling OAuth2 authorization against a remote server, on successful authorization stores some information from that server in the Wordpress database, and redirects the user to a page on the Wordpress site.

In order to store the data the plugin makes use of the wpdb function, which I understand to be recommended practice.

E.g.:

# Require wp-load.php in order to access $wpdb.
require_once(dirname(dirname(dirname(dirname(__FILE__)))) . DIRECTORY_SEPARATOR . 'wp-load.php');

global $wpdb;
$table_name = $wpdb->prefix . 'placespeak';
$query_array = [$app_id];
$client_info = $wpdb->get_row(
    $wpdb->prepare(
        "SELECT * FROM " . $table_name . " WHERE id = %d",
        $query_array
    )
);

The current version of the plugin is hosted on github here.

However, when I submitted the plugin to the Wordpress plugin directory, I received this response:

Calling core loading files directly

Including wp-config.php, wp-blog-header.php, wp-load.php, or pretty much any other WordPress core file that you have to call directly via an include is not a good idea and we cannot approve a plugin that does so unless it has a very good reason to load the file(s). It is prone to failure since not all WordPress installs have the exact same file structure.

Usually plugins will include wp-config.php or wp-load.php in order to gain access to core WordPress functions, but there are much better ways to do this. It's best if you tie your processing functions (the ones that need but don't have access to core functions) into an action hook, such as "init" or "admin_init".

That's entirely sensible, but I'm not sure how to proceed.

Because the endpoint is not part of the Wordpress admin interface, there are no hooks to wrap it in (I think?).

I tried requiring the "stripped down" version of wp-load, e.g.

define( 'SHORTINIT', true );
require_once(dirname(dirname(dirname(dirname(__FILE__)))) . DIRECTORY_SEPARATOR . 'wp-load.php');

but that produced a Call to undefined function trailingslashit() error when I perform a database query using wpdb as above, which appears to be a known limitation of using the SHORTINIT version of wp-load.

Is there another method for accessing the database, which should work in this context, and which will be acceptable to the plugin directory maintainers?

Was it helpful?

Solution

Bootstrapping WordPress from a direct PHP file hit is not a good idea in general, the repository maintainers are right. It is pretty simple to add a custom endpoint using the Rewrite API, so there's no reason you shouldn't.

add_action( 'init', function() {
    /** Add a custom path and set a custom query argument. */
    add_rewrite_rule( '^your/custom/path/?$', 'index.php?custom_action=1', 'top' );
} );

add_filter( 'query_vars', function( $query_vars ) {
    /** Make sure WordPress knows about this custom action. */
    $query_vars []= 'custom_action';
    return $query_vars;
} );

add_action( 'wp', function() {
    /** This is an call for our custom action. */
    if ( get_query_var( 'custom_action' ) ) {
        // your code here
    }
} );

Now hit https://yoursite.com/your/custom/path/ WordPress will load and call your code.

An even simpler way would be to use a $_GET parameter.

add_action( 'init', function() {
    if ( !empty( $_GET['custom_action'] ) ) {
        // your code here
    }
} );

And then hit https://yoursite.com/?custom_action=1

Your pick, depending on whether you want a nice URL or you're satisfied with a less beautiful GET parameter.

Licensed under: CC-BY-SA with attribution
Not affiliated with wordpress.stackexchange
scroll top