$conf, $runtime; function_exists('chdir') AND chdir(APP_PATH); $r = 'mysql' == $conf['cache']['type'] ? website_set('runtime', $runtime) : cache_set('runtime', $runtime); } function runtime_truncate() { global $conf; 'mysql' == $conf['cache']['type'] ? website_set('runtime', '') : cache_delete('runtime'); } register_shutdown_function('runtime_save'); ?>php - Accessing the database from a plugin outside of action hooks|Programmer puzzle solving
最新消息:Welcome to the puzzle paradise for programmers! Here, a well-designed puzzle awaits you. From code logic puzzles to algorithmic challenges, each level is closely centered on the programmer's expertise and skills. Whether you're a novice programmer or an experienced tech guru, you'll find your own challenges on this site. In the process of solving puzzles, you can not only exercise your thinking skills, but also deepen your understanding and application of programming knowledge. Come to start this puzzle journey full of wisdom and challenges, with many programmers to compete with each other and show your programming wisdom! Translated with DeepL.com (free version)

php - Accessing the database from a plugin outside of action hooks

matteradmin8PV0评论

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?

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?

Share Improve this question edited Jun 15, 2020 at 8:21 CommunityBot 1 asked Nov 16, 2016 at 20:35 Hugh StimsonHugh Stimson 134 bronze badges 2
  • You should look into a custom endpoint using rewrite rules, and wrapping your code in template_redirect hook, like here wordpress.stackexchange/questions/193888/dynamic-endpoints/… – czerspalace Commented Nov 16, 2016 at 21:59
  • 1 This should get you what you need: v2.wp-api/extending/adding – Jeremy Ross Commented Nov 16, 2016 at 23:30
Add a comment  | 

1 Answer 1

Reset to default 1

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/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/?custom_action=1

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

Post a comment

comment list (0)

  1. No comments so far