Your experience is one reason that it’s generally encouraged to never include or require core files, even wp-blog-header or wp-load. I’m not sure the exact issue with multisite, only that it’s bad practice and you shouldn’t do that. With single site doing so makes your code non-portable because you cannot know where the needed file is relative to your code page. It sounds like this has happened to you for multisite.
Which begs the question “If I can’t do that, how do I initiate the WP environment?” Instead of explaining the answer, I refer you to this article.
Oh, thanks a lot for the link. Looks like what I was searching. And yes, I understand that include native wp functions into the file that can be launched externally is a bad practice, but this is unavoidable for my plugin’s purpose, since it should execute data automatically from time to time, and it is possible to do only by CRON job on the server, since quite often the hostings do not allow to launch any other process that do the same that CRON.
Not really CRON, but might work: Function Reference/wp schedule event
Or perhaps WP-CLI will give CRON access to admin-post.php as mentioned in the previously linked article.
There’s also XML-RPC WordPress API .
I feel that you have opened in front of me a huge library with infinite possibilities (happy as a child). Thank you so much for the information!
Probably, this is not related to the topic of the post, generally. But still. Since to launch wp environment in the script, which can be called from outside is a bad practice and distribute this plugin is a crime. May be here is an opportunity for example to assign a function-handler for specific incoming request?
For example, plugin adds the http form to the page, and when the site visitor sends this form – the request is sending to some wp api endpoint, and it can redirect the request to the assigned function-handler.
In other words:
Can I set in html form action something like “http//mysite.org/wp-api-endpoint?action=myaction” or can I hook incoming post/get request event to the wordpress and set for this particular incoming request function-handler?
Otherwise, I’m forced to use a “bad approach”, and I’m just wondering what in this case is a good way?
You’re still on topic IMO. Even if not, as OP I don’t see why you couldn’t wander about as long as it’s WP related. “distribute this plugin is a crime” – lol, you’re too funny!
Anyway, you are seeing the light, but haven’t yet connected all the pieces. I think I can help. The form action end point you want is /wp-admin/admin-post.php?action=myaction . There’s no cute permalink to this, but a rewrite rule will fix that if you want. Naturally “myaction” can be any name you want, the rest is ordained.
Then your plugin hooks these actions: “admin_post_myaction” and “admin_post_nopriv_myaction”. If you’ve used AJAX correctly in WP these will look somewhat familiar, one is for logged in users and the other for non-logged in. In some cases one or the other is all you need. Your action callback function can do whatever is needed. By going through admin-post.php the environment is loaded for you, you don’t have to worry about where wp-load.php is relative to your plugin file.
If your plugin generates the page’s form, then it knows how to get to /wp-admin/ with admin_url(). Otherwise external scripts can’t really know where WP is installed and some sort of redirect could be needed.
You can add any other URL parameters you need and your callback can get them from $_GET. If your form uses POST method, then you would have a hidden input field with the name “action” and a value “myaction”. In this case your callback would get other field values from $_POST. Though it’s tempting, I do not recommend using $_REQUEST, it has a slight security issue.
I suspect you already know some of this, but I wanted to provide complete information. FWIW, all of this is covered in the first link I provided. I’m not trying to say you should RTFM, it’s just that the article may have more complete information than I’ve provided here. Granted, its example of dynamic CSS does not apply, but the technique of running WP script from an external request is the same. Using admin-post.php
Apparently, I explained my goal not clearly.
The admin-post is the great opportunity, but it works only for admin (or maybe also for users) that already logged in on the site. But I’m interested in the same opportunity for any site visitor that does not require being logged in on the site.
For example, WP has those opportunity with AJAX:
1. Ajax on the Administration Side.
2. Ajax on the Viewer-Facing Side.
And it would be great, if here is an opportunity to have something like:
viewer-facing-post.php instead of admin-post.php.
But, as I can see – here is not way to do that, isn’t it?
And may be it will be more clearly to understand, why I need this:
This plugin must be available to receive data as POST request from a service server whenever this service dicided to make that request. I already solved this task, but I used that “bad approach”, and it bothers me a little.
In any way, the including wp-load works gracefully, and you really helped me. Thank you for all!
When used for your own purposes, you may do whatever you wish with your server within what’s legal for the server’s locale, including wp-load.php is one. You can even distribute it, it’s not a crime 🙂 But it will not be allowed in the ww.wp.xz.cn repository because of that practice. I know you don’t care about that.
FWIW, admin-post.php will work for both logged in and not logged in visitors. Like with AJAX, you must hook a different action in each case, that is the only difference. The request can even be a GET request. Any server can POST a request via HTTP at anytime as long as “action” name field is defined. For that reason your code must take appropriate security measures, such as checking referer header and using a nonce or similar security token. By use of rewrites, the public endpoint can be whatever you like, as long as it eventually ends up at admin-post.php.
About “admin-post.php will work for both logged in and not logged in visitors.”
The fact is that I tested it for both logged in and not logged in; and it works only for logged in.
How I did that:
I set handler-function accordingly for tutorial. And when I’m logged in one browser in one tab, and was trying to type target url (like …./admin-post.php?action=myaction) it works and I saw the result in browser (string “hello!”).
But when I logged out and tried again – it just show empty web page (without result string “hello!”). Logged in – and it worked again.
But in tutorial it is not mentioned that it works only for logged in users.
Did you hook both “admin_post_myaction” and “admin_post_nopriv_myaction” actions? It is intended to work for both visitor types, but a different action fires for each case. Relevant code is here:
https://core.trac.ww.wp.xz.cn/browser/tags/4.3.1/src/wp-admin/admin-post.php#L33
I’m in shock. That’s exactly what I was searching! Thank you. Even the short “admin_post_nopriv” could help. It is really amazing, because it provides all necessary opportunities.
Now, I can see the completed set:
AJAX:
– wp_ajax_
– wp_ajax_nopriv_
HTTP requests:
– admin_post_
– admin_post_nopriv_
You are really WP expert!
Thank you so much.
You’re welcome! I’m so glad you were finally able to understand, it makes my efforts worthwhile.