0

.Net developer here trying to learn some of the basics of wordpress. I have a basic question but I guess there's so much that I don't know that I can't even get a relevant result when searching here or via Google.

If I create a plugin and activate it, and run flush_rewrite_rules(); in my activation code, should I be able to put the path to a page in my plugin into the address bar of a browser and get the results of the script in my plugin page?

For example, say my plugin is named my-plugin. The path to my-plugin is of course wp-content/plugins/my-plugin. I create the file wp-content/plugins/my-plugin/my-page.php.

The contents of my-page.php are:

<?php

if (!isset($returnVal))
    $returnVal = new stdClass();

$returnVal->status = "success";
$returnVal->info = "seems to work";

echo json_encode($returnVal);

Should I be able to access that by entering this in the browser:

https://my-site/wp-content/plugins/my-plugin/my-page.php

I'm asking this b/c I always get a 404 when I do that.

I've been beating my head against this for awhile now and I've come to the conclusion that there's just something I'm missing about the way wordpress works.

More details: I'm using the Avada theme (v7.6.1) Form builder. It has an option to POST to a url when the user clicks a submit button. I need it to POST the form data to the page in my plugin. Then my plugin page needs to return success or error to the frontend page.

I figured I would start at the bottom and work my way up to accomplish this, so I decided to see if I can even get my plugin to return the success/error object. This is what I'm stuck on.

If I get this to work then then next step would be putting the url to my plugin page in the Avada Form Builder options for what happens when the user clicks the submit button. I haven't got to that point b/c I'm stuck on the above.

Here's a post on s/o I made regarding the bigger picture.

UPDATE: SOME PROGRESS MADE @kero's comment pointed me in the direction of custom REST endpoints and I was able to make a GET request work in the browser to https://my-site.com/wp-json/my-plugin/v1/my-endpoint and it returns this:

{"status":"success","info":"seems to work"}

Now I'm stuck trying to get the Avada form to call that endpoint. I'v tried the following urls:

  1. wp-json/my-plugin/v1/my-endpoint
  2. /wp-json/my-plugin/v1/my-endpoint
  3. https://my-site.com/wp-json/my-plugin/v1/my-endpoint

Both 1 & 2 result in this:

{"status":"error","info":"url_failed"}

#3 returns simply a -1

return message

Any ideas on how to get the Avada form to call that endpoint and get the result?

UDPATE: Requested details provided:

Here's the REST endpoint code from my main plugin file:

add_action('rest_api_init', function () {
    register_rest_route('my-plugin/v1', '/my-page', array(
        'methods' => 'GET', 
        'callback' => 'my_awesome_func',
    ));
});

function my_awesome_func()
{
    
    if (!isset($returnVal))
        $returnVal = new stdClass();

    $returnVal->status = "success";
    $returnVal->info = "seems to work";

    return $returnVal;
}

The methods in the snippet above is set to "GET" but I also tried it set to "POST" and the Avada form has a setting where you choose GET/POST and I tested it both ways. Neither the GET nor the POST would work for me.

The Avada form is POSTing to wp-admin/admin-ajax.php with the following key:values. Interestingly it gets a 200 from the POST but still returns the same values mentioned above.

action:fusion_form_submit_form_to_url
fusionAction: wp-json/my-plugin/v1/my-page
formData: email=&main_license_number=&credit_card_last_four=&fusion_privacy_store_ip_ua=false&fusion_privacy_expiration_interval=48&privacy_expiration_action=anonymize&fusion-form-nonce-1808=3d676aef78&fusion-fields-hold-private-data=
5
  • Accessing PHP files directly is not recommended in WordPress. You can create a custom REST endpoint for this purpose.
    – kero
    Jan 20, 2022 at 16:32
  • 1
    You should be able to access the file under that path since what you are doing is just accessing a plain PHP file completely bypassing WordPress. (Actually adding a virtual page via WordPress is a way more complex process than what you are trying.) Is the 404 styled like the rest of the site, so coming from WordPress or a plain 404 from the webserver? In the end I think we have a XY problem here. What is it you are trying to achieve in the end?
    – kraftner
    Jan 20, 2022 at 16:33
  • Thanks @kraftner for the information. What I'm trying to do is quite a bit more complicated than that but I figured if that if I can't make that work then no point in going into more details. I'll edit the post to give more details.
    – agileMike
    Jan 20, 2022 at 16:44
  • Can you share how you defined the REST endpoint? Maybe POST is not allowed? Can you see in the browser console, how Avada is actually doing the request?
    – kero
    Jan 20, 2022 at 18:11
  • @kero I added those details to the post.
    – agileMike
    Jan 20, 2022 at 19:23

2 Answers 2

1

Generally you do not want to access your PHP files directly within WordPress because you lose a lot of "juice", meaning all WP functionality would have to be re-imported (and might break). WP is setup in a way that all requests to the CMS get routed to index.php and some mechanisms then decide what to do with the request.

From what you write, it sounds like a custom REST endpoint might serve you well.

Expanding your code to the following should already show some results:

add_action('rest_api_init', function () {
    register_rest_route('my-plugin/v1', '/my-page', [
        'methods' => [\Requests::POST],
        'callback' => 'my_awesome_func',
    ]);
});

function my_awesome_func()
{   
    if (!isset($returnVal))
        $returnVal = new stdClass();

    $returnVal->status = "success";
    $returnVal->info = "seems to work";

    return $returnVal;
}

(using short array syntax and) changed

'methods' => 'GET',

to

'methods' => [\Requests::POST],

which references the Requests' class const (my preferred style - you can also use 'POST' directly).

Most likely you want to do something with the form data, so change your my_awesome_func() to something like this

function my_awesome_func(\WP_REST_Request $request)
{
    if ($request->get_param('main_license_number') !== 'something') {
        return new WP_Error('Invalid license number!');
    }

    return [
        'status' => 'success',
        'info' => 'hello',
    ];
}

Now there is only one problem left: everybody can call this endpoint, they don't have to come through the form. Your request contains a fusion-form-nonce-1808 and I assume this can be used to verify that it was indeed submitted from the form - but seems very Avada/FusionForm/some third party plugin specific - which I have no knowledge of and is out of scope for this site. But you should try contacting them and ask how to verify it, something along the lines of:

add_action('rest_api_init', function () {
    register_rest_route('my-plugin/v1', '/my-page', [
        'methods' => [\Requests::POST],
        'callback' => 'my_awesome_func',
        'permission_callback' => function () {
            return magic_validate_my_nonce_please();
        },
    ]);
});

or with the fancy arrow function added in PHP 7.4:

add_action('rest_api_init', function () {
    register_rest_route('my-plugin/v1', '/my-page', [
        'methods' => [\Requests::POST],
        'callback' => 'my_awesome_func',
        'permission_callback' => fn () => magic_validate_my_nonce_please(),
    ]);
});
1
  • 1
    I ended up using a custom REST endpoint, thanks for your help @kero!
    – agileMike
    Jan 23, 2022 at 20:56
0

Welcome to WordPress and WPSE!

Plugins are meant to alter or add functionality to what is already provided by WordPress Core. They are not meant to be accessed directly. So for example, a plugin might add links to the most recent posts on your site, to the end of every post.

It sounds like the best path forward for you is to learn more about how WordPress works. The Plugin Handbook will help you specifically with plugins. Learn WordPress is an excellent place to learn about the basics overall. Once you have a stronger foundation, Developer Resources should help with additional information on WordPress functions, the Editor, themes, etc.

As a quick overview, WordPress Core creates two main post types: the Post and the Page. Posts are frequently-changing or frequently-added content, like news articles. There are Categories built in so you can group related types of Posts, and Tags so you can make smaller groups of related content. Pages are more static resources - say your About Page. They don't natively include Categories but they are hierarchical, meaning one Page can be the parent of another Page, so your About Page could have a child Page of History and another child Page of Contact Us.

Plugins will often add meta fields to these existing post types, or create new post types altogether - like Portfolio, or Jobs, or all sorts of other things. A plugin can also add functionality to the "back end" - the /wp-admin/ area - for example, there are Google Analytics plugins that both add the tracking code to the front end and also add a dashboard widget that will display some of those statistics to logged-in users. But all this plugin data gets output somewhere native - i.e. in wp-admin, or within Posts. It doesn't output directly when you try to visit the plugin URL in your browser.

3
  • (As kraftner noted, it is usually possible to access a plugin PHP file directly in the browser, but that's not something you typically do in WP.)
    – WebElaine
    Jan 20, 2022 at 16:40
  • Thanks @WebElaine. In general, how does code in plugins get triggered based on submissions of form data in the front end? I've tried using add_rewrite_rule as in this s/o post but once again there's such a steep learning curve that I'm not getting the results I need.
    – agileMike
    Jan 20, 2022 at 16:54
  • You can POST directly to a PHP file in your plugin, which processes the data and then might redirect to a confirmation page. Instead of a rewrite rule (this handles the first load) you can use wp_redirect() with a relative URL. I tend to use one with a query string, and then whatever page it redirects to, the template looks for a ?success parameter or something similar, so the confirmation page can only be viewed after a successful submission.
    – WebElaine
    Jan 20, 2022 at 20:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.