WordPress a propojení s externími službami přes REST API

Stále více klientů se na mě obrací s požadavky na propojení WordPress / WooCommerce s jinými weby nebo službami přes REST API. Jako příklad mohu uvést napojení na Drip (služba pro emilové kampaně), FastSpring (online prodejní systém), Vyfakturuj (online fakturační nástroj) a spousta dalších.

Pro zjednodušení celého procesu propojení jsem si připravil wrapper, který je možné využít pro jednoduché posílání požadavků na externí API a získávání odpovědí. Použítím tohoto (nebo podobného) wrapperu je možné výrazně zrychlit a zjednodušit propojení WordPress s jinými službami.

<?php
namespace WP_Programator;

class Api {
	/**
	 * API URL
	 * @var string
	 */
	protected $api_url = '';

	/**
	 * Request args
	 * @var array
	 */
	protected $args = [];

	/**
	 * Request response
	 * @var
	 */
	protected $response;

	/**
	 * Request method
	 * @var
	 */
	protected $method;

	/**
	 * Request endpoint
	 * @var
	 */
	protected $endpoint;

	/**
	 * JSON encode body in the request
	 * @var bool
	 */
	protected $json_encode_body = false;


	/**
	 * Api constructor.
	 */
	function __construct()
	{
	}

	/**
	 * Set the API URL
	 * @param $url
	 */
	function set_api_url (string $url) {
		$this->api_url = $url;
	}

	/**
	 * Set the default args
	 * @param array $args
	 */
	function set_args(array $args) {
		$this->args = $args;
	}

	/**
	 * Add args
	 * @param array $args
	 */
	function add_args(array $args) {
		$args = array_merge($args,$this->args);
		$this->set_args($args);
	}

	/**
	 * Set the request method
	 * @param string $method
	 */
	function set_method (string $method) {
		$this->method = $method;
	}

	/**
	 * Set the request method
	 * @param string $endpoint
	 */
	function set_endpoint (string $endpoint) {
		$this->endpoint = $endpoint;
	}

	/**
	 * Call the API with GET Method
	 * @return array|bool|mixed|object|\WP_Error
	 */
	function _get() {
		$this->set_method('get');
		return $this->_call();
	}

	/**
	 * Call the API with POST Method
	 * @return array|bool|mixed|object|\WP_Error
	 */
	function _post() {
		$this->set_method('post');
		return $this->_call();
	}

	/**
	 * Call the API with DELETE Method
	 * @return array|bool|mixed|object|\WP_Error
	 */
	function _delete() {
		$this->set_method('delete');
		return $this->_call();
	}

	/**
	 * Call the API with DELETE Method
	 * @return array|bool|mixed|object|\WP_Error
	 */
	function _put() {
		$this->set_method('put');
		return $this->_call();
	}

	/**
	 * Call the API
	 *
	 * @return array|mixed|object|\WP_Error
	 */
	function _call()
	{
		// Set the request method
		$this->args['method'] = $this->method;

		// JSON Encode the body if asked to
		if (isset($this->args['body']) && is_array($this->args['body']) && $this->json_encode_body) {
			$args['body'] = json_encode($this->args['body']);
		}

		// Set the endpoint
		$url = $this->get_request_url();

		$response = false;

		// Perform the request
		$this->response = wp_remote_request($url, $this->args);

		if (!$this->response)
			return new \WP_Error(400,'Error when sending request', $response);

		// Return error or success response
		if (!$this->response_is_success()) {
			return $this->prepare_response_error();
		}

		return $this->prepare_response_success();
	}

	/**
	 * Get the request URL
	 * @return string
	 */
	function get_request_url() {
		return $this->api_url. $this->endpoint;
	}

	/**
	 * Check if the response was successful
	 * To be overridden by sub-classes
	 * @return bool
	 */
	function response_is_success() {
		$response_code = wp_remote_retrieve_response_code($this->response);
		return  $response_code >= 200 && $response_code < 300;
	}

	/**
	 * Prepare the error response return
	 * To be overridden by sub-classes
	 * @return \WP_Error
	 */
	function prepare_response_error() {
		$errors = [];
		$body = $this->get_response_body();
		foreach ($body->error as $error) {
			$errors[] = $error;
		}

		return new \WP_Error(wp_remote_retrieve_response_code($this->response),implode(',',$errors), $body);
	}


	/**
	 * Prepare the success response return
	 * To be overridden by sub-classes
	 * @return string
	 */
	function prepare_response_success() {
		return $this->get_response_body();
	}

	/**
	 * Get the response body
	 * @return string
	 */
	function get_response_body() {
		return wp_remote_retrieve_body($this->response);
	}
}

Pro propojení WordPress s externí službou pak stačí vytvořit třídu, která wrapper rozšíří, jako např.:

<?php
/**
 * Test API example
 */
namespace Test_API;
use WP_Programator\Api;

class TestMethod extends Api {

	/**
	 * TestMethod constructor.
	 */
	function __construct() {
		// Set the endpoing
		$this->set_endpoint('https://myapiurl.com');

		// Set the default args
		$this->set_args(array(
			'timeout' => 45,
			'redirection' => 5,
			'httpversion' => '1.0',
			'blocking' => true,
			'headers' => array(),
			'body' => array( 'username' => 'bob', 'password' => '1234xyz' ),
			'cookies' => array()
		));

		parent::__construct( );
	}

	/**
	 * Example function to get some data from example API
	 * @return array|bool|mixed|object|\WP_Error
	 */
	function get_some_data() {
		$args['body'] = [
			'some_param' => 'some_value',
			'another_param' => 'another_value'
		];

		$this->add_args($args);
		$this->set_endpoint('some-endpoint');
		
		return $this->_get();
	}
}

$api_method = new TestMethod();
$result = $api_method->get_some_data();

// Do something with the result

Kód je dostupný také na Githubu a nainstalovat ho můžete pomocí composeru [code]composer require wpprogramator/wp-api-wrapper[/code]

Pokud budete potřeboval propojit WordPress s aplikacemi třetích stran, neváhejte se na mě obrátit.

Přidat komentář