Integrating WordPress with External Systems

Wapuu  Franklin

WordCamp Philly, 2015
Slides: https://adcwp.me/wcphilly2015

Aaron D. Campbell

Aaron D. Campbell – http://AaronDCampbell.com/
aaron@ithemes.com – @AaronCampbell
http://profiles.wordpress.org/aaroncampbell/

WordPress

WordPress logo

WordPress does an awful lot!

But not everything

api-logos

API Documentation

  • Fact: Documenting something is the bane of a coders existence
  • Fact: This results in horrible, incomplete, out of date, and generally wrong API documentation
  • Fact: Bad API documentation is also the bane of a coders existence

How to read API
documenation

  • As if it’s out of date or wrong
  • Because it likely is

API Code Libraries

Many popular APIs offer pre-made libraries in several languages – scrutinize these

Often best documentation

For JavaScript libraries, PLEASE use wp_enqueue_script()

The “application”

Many APIs require you to register in advance

Most are free, but some require a credit card or SMS verification to prove you’re a real person

The keys

Once you register you usually get an API key of some kind. Often you get a key as well as an application identifier.

These are yours and are often tied to your site. Do not distribute them with your plugin and be aware that you probably need a new one if you move the plugin to a new domain.

Now for the fun part!

Your Friends

  • wp_safe_remote_request()
  • wp_safe_remote_get()
  • wp_safe_remote_post()
  • wp_safe_remote_head()
  • wp_remote_retrieve_headers()
  • wp_remote_retrieve_header()
  • wp_remote_retrieve_response_code()
  • wp_remote_retrieve_response_message()
  • wp_remote_retrieve_body()
  • wp_http_supports()

Making the request

Just choose your method. The default for wp_safe_remote_request() is GET.

$response = wp_safe_remote_request( $url, $args );
$response = wp_safe_remote_get( $url, $args );
$response = wp_safe_remote_post( $url, $args );
$response = wp_safe_remote_head( $url, $args );

Retrieving the response

Just choose what data you are wanting to retrieve. Usually what you want is the body. The response code is often useful too.

$data = wp_remote_retrieve_body( $response );
$data = wp_remote_retrieve_headers( $response );
$data = wp_remote_retrieve_header( $response, $header );
$data = wp_remote_retrieve_response_code( $response );
$data = wp_remote_retrieve_response_message( $response );

Can you do what you want?

if ( wp_http_supports( array( 'ssl' ) ) ) {
	// Yay!
}

The code

$args = array( 'my-param' => 'my-value' );
$params = array(
	'body'      => $args,
	'sslverify' => false,
	'timeout'   => 5,
);
	
// Send the request
$resp = wp_safe_remote_post( $endpoint, $params );
$resp = wp_remote_retrieve_body( $resp );
// $resp is NVP (something=this&something2=that)
return wp_parse_args( $resp );

What you get

Array (
    [PROFILEID] => ***
    [STATUS] => Active
    [AUTOBILLOUTAMT] => NoAutoBill
    [DESC] => Annual Subscription
    [SUBSCRIBERNAME] => Example Man
    [PROFILESTARTDATE] => 2013-02-10T06:00:00Z
    [NEXTBILLINGDATE] => 2013-02-10T10:00:00Z
    [AMT] => 49.00
	...
)

Caching – Do It!

Thoughts on caching

Sample with TLC Transients

$key = 'twp_' . md5( $url );
return tlc_transient( $key )
	->expires_in( 300 ) // cache for 5 minutes
	->updates_with( 'parseFeed', array( $o ) )
	->get();

That’s it. It’s like cache-magic

Pushed data

Some APIs will push information to you without you sending a request (or the request was sent some time ago). PayPal’s IPNs are a good example. They can tell you that a recurring payment has been canceled or that a card being automatically charged every month was declined.

So how do you process data that you didn’t request? Where does it go?

Build a Listener

add_action( 'wp_ajax_nopriv_pp_listener', 'listener' );
public function listener() {
	$_POST = stripslashes_deep($_POST);
	if ($this->_validateMessage()) {
		$this->_processMessage();
	}

	exit; // Stop WordPress entirely
}

We use admin-ajax to process incoming requests to
wp-admin/admin-ajax.php?action=pp_listener.

To do what?

You can process the message right there (update user record, add updated info to database, etc). But what if you’re building this for other people to use? Why not fire actions that other people can hook into?

function _processMessage() {
	do_action( 'paypal-ipn', $_POST );
	if ( !empty($_POST['txn_type']) )
		do_action( "paypal-{$_POST['txn_type']}", $_POST );
}

Here, the ‘paypal-ipn’ action always fires and if there is a transaction type, then a more specific ‘paypal-{transaction-type}’ action is also fired.

Final Thoughts

Don’t reinvent the wheel. Check if WordPress does what you want.

If WordPress has it, USE IT! Otherwise don’t complain when you have to rewrite it because the latest version of WordPress broke it.

Everyone else is _doing_it_wrong(). That doesn’t make it OK.

Code samples adapted from PayPal Framework and Twitter Widget Pro – You can find other good examples in core as well as most of the importers.

Q & A

Aaron D. Campbell – http://AaronDCampbell.com/
aaron@ithemes.com – @AaronCampbell
http://profiles.wordpress.org/aaroncampbell/

Slides: https://adcwp.me/wcphilly2015

This presentation is running on WordPress using the Presenter plugin