0

I'm trying to create an API endpoint in a Wordpress site that can receive AWS Simple Notification Service notification. I have this working now, but on the front end, the site does not load. Here are excerpts of the code:

require_once MY_PLUGIN_DIR . '/libs/aws/aws-autoloader.php';

use Aws\Sns\Message;
use Aws\Sns\MessageValidator;

function sns_endpoint() {

   add_rewrite_tag( '%apitest%', '([^&]+)' );
   add_rewrite_rule( 'test/([^&]+)/?', 'index.php?apitest=$matches[1]', 'top' );

}
add_action( 'init', 'sns_endpoint' );

function sns_endpoint_data() {    
    // this line caused the site not to load
    $message = Message::fromRawPostData();
    /* additional code follows... */
}

add_action( 'template_redirect', 'sns_endpoint_data' );

Nothing is written to the debug.log.

Update: There is an error written to the error log: SNS message type header not provided Any ideas of how this could be resolved?

  • Increasing the memory limit does not help. – AlanP Sep 17 '18 at 23:00
  • Have you tried checking the servers PHP error log rather than using the WP_DEBUG_LOG? Are you sure it's actually a PHP error and not something else? I notice your code eamples are incomplete, if there is a cause there's a very high chance you've removed it from your example, and an even higher chance you consider it irrelevant and thus left it out. Also, which file does that code appear in? Is it a plugin? functions.php? Page template? – Tom J Nowell Sep 18 '18 at 2:58
  • I have provided enough code as the problem shows up with just $message = Message::fromRawPostData();. It runs in a plugin. – AlanP Sep 18 '18 at 9:59
  • It's not enough to replicate or understand. Remember, this is your plugin, you're intimately familiar. Just because you don't think those parts are relevant doesn't mean they aren't. Afterall if you knew which parts were needed you wouldn't have needed to ask here. It isn't clear to me what the file being included is, there's no opening PHP tag, and there's no indication if there's any code that happens before the line mentioned =/ Context!! It's incredibly important, and you've removed a lot of it :( E.g. I would expect a template_redirect filter to start with a test condition – Tom J Nowell Sep 18 '18 at 13:12
  • I found out that the endpoint code runs when the site loads even though a notification has not been sent. Either I need modify the rewrite rule or else test the post data for an SNS notification before the call to the fromRawPostData() function. This is what I would like to know how to do. – AlanP Sep 18 '18 at 18:50
1

The root cause is this:

function sns_endpoint_data() {    
    // this line caused the site not to load
    $message = Message::fromRawPostData();
    /* additional code follows... */
}

add_action( 'template_redirect', 'sns_endpoint_data' );

There is no if condition checking if this is indeed the URL you desired to do this on. As a result, the Message::fromRawPostData() will load on every page that uses a template regardless of the URL.

This is because you never checked to see which page you were on, and you tried to do work in the wrong hook.

Handling the Rule

add_rewrite_tag( '%apitest%', '([^&]+)' );
add_rewrite_rule( 'test/([^&]+)/?', 'index.php?apitest=$matches[1]', 'top' );

Here we see apitest is added as a rewrite tag, but it's never tested.

So instead, lets modify the template_redirect action to do what it's supposed to: redirect the template, say something similar to this:

function sns_apitest_template_redirect() {    
    global $wp_query;
    if ( !empty( $wp_query->query_vars['apitest'] ) ) {
        $apitest= $wp_query->query_vars['apitest'];
        sns_handle_apitest_endpoint( $apitest );
        exit;
}
add_action( 'template_redirect', 'sns_apitest_template_redirect' );

Note that it attempts to detect the apitest tag and if it is not empty, it calls a function then exits. This way the code for your endpoints logic isn't muddled up with template_redirect.

So now we need that function:

function sns_handle_apitest_endpoint( $apitest ) {
    $message = Message::fromRawPostData();
    // etc...
}
  • I've tried this out, but 'apitest' does not show up in the query_vars. Adding it with the 'query_vars' filter does not seem to help. Any other ideas? – AlanP Sep 19 '18 at 15:01
  • Are you 100% sure your regular expression actually works? Have you tested it with known values? What kind of values are you trying to match? Did you remember flush/regenerate the rewrite rules? – Tom J Nowell Sep 19 '18 at 15:18
  • The regular expression'([^&]+)' seems to be ok and I have flushed the permalinks, but no change. – AlanP Sep 19 '18 at 17:22
  • It has started working. 'apitest' is now in the query_vars. I'm able to use is capture the API call and the site it now loading. – AlanP Sep 19 '18 at 23:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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