Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save phillipwilhelm/83883894b0b7fe1f4e07ee0d030261ae to your computer and use it in GitHub Desktop.
Save phillipwilhelm/83883894b0b7fe1f4e07ee0d030261ae to your computer and use it in GitHub Desktop.
Wordpress endpoint aggregator with Cache
<?php
/**
* Requires PHP 5.6+ due to the use of the splat operator and the [] "array declaration".
*/
class Rest_Aggregator {
/**
* Page number to fetch.
*
* @var integer
*/
private $page = 1;
/**
* Array of generated posts.
*
* @var array
*/
private $posts = [];
/**
* List of endpoints to fetch from.
*
* @var array
*/
private $endpoints = [];
/**
* Disable cache.
*
* @var boolean
*/
public $disable_cache = false;
/**
* Constructor.
*
* @param array $endpoints array of endpoint url.
*/
public function __construct( array $endpoints ) {
$this->endpoints = $endpoints;
}
/**
* Get the posts wether it was cached or not.
*
* @see get_cache()
* @see merge()
*
* @param integer $page the page to show.
* @return array
*/
public function get_posts( int $page = 1 ) {
$this->page = $page;
if ( ! $this->disable_cache ) {
$this->get_cache();
}
if ( isset( $this->posts[ $page ] ) ) {
return $this->posts[ $page ];
} else {
$this->merge();
if ( ! empty( $this->posts ) ) {
return $this->posts[ $page ];
}
}
return [];
}
/**
* Merge posts based off endpoints into 1 single array and
* sort it by posted date this also set the cache.
*
* @see get_remote()
* @see sort()
* @see set_cache()
*
* @return void
*/
private function merge() {
$endpoints = $this->endpoints;
$tmp_posts = [];
if ( ! empty( $endpoints ) && is_array( $endpoints ) ) {
foreach ( $endpoints as $endpoint ) {
$value = $this->get_remote( $endpoint );
if ( is_array( $value ) ) {
$tmp_posts[] = $value;
} elseif ( is_object( $value ) ) {
$tmp_posts[][] = $value;
}
}
/**
* Splat Operator
*
* @see https://blog.programster.org/php-splat-operator
*/
$tmp_posts = array_merge( ...$tmp_posts );
$this->posts[ $this->page ] = $this->sort( $tmp_posts );
}
if ( ! $this->disable_cache ) {
$this->set_cache();
}
}
/**
* Fetch reponse from provided endpoint url.
*
* @see wp_remote_get()
* @see wp_remote_retrieve_response_code()
* @see wp_remote_retrieve_body()
*
* @param string $endpoint The URL of the endpoint.
* @return array
*/
private function get_remote( $endpoint ) {
$url = add_query_arg( 'page', $this->page, $endpoint );
$request = wp_remote_get( $url );
$response = wp_remote_retrieve_response_code( $request );
if ( ! is_wp_error( $request ) && 200 === $response ) {
return json_decode( wp_remote_retrieve_body( $request ) );
}
// TODO: Add error reporting if failed to connect.
return [];
}
/**
* Get Cache.
*
* @see get_transient()
* @see get_cache_key()
*
* @return void
*/
private function get_cache() {
$posts = get_transient( $this->get_cache_key() );
if ( is_array( $posts ) ) {
$this->posts[ $this->page ] = $posts;
}
}
/**
* Sets cache.
*
* @see get_field()
* @see set_transient()
* @see get_cache_key()
*
* @return void
*/
private function set_cache() {
$exp_option = get_field( 'cache_expiration', 'rest_options' );
$expiration = ( ! empty( $exp_option ) ) ? (int) $exp_option : 15;
if ( ! empty( $this->posts ) ) {
set_transient( $this->get_cache_key(), $this->posts[ $this->page ], $expiration * MINUTE_IN_SECONDS );
}
}
/**
* Clear cache.
*
* @see delete_transient()
* @see get_cache_key()
*
* @return void
*/
public function clear_cache() {
delete_transient( $this->get_cache_key() );
}
/**
* Get unique hashed key based on the array of endpoints.
*
* @return string Hashed key
*/
private function get_cache_key() {
$prefix = $this->page . '_';
$infix = implode( '_', $this->endpoints );
$infix = str_replace( array( 'http://', 'https://' ), '', $infix );
$suffix = '_endpoint_transient';
return md5( $prefix . $infix . $suffix );
}
/**
* Sorts final array by date.
*
* @param array $posts array of posts to sort.
* @return array $posts array of posts sorted.
*/
private function sort( array $posts ) {
usort( $posts, function ( $a, $b ) {
return strtotime( $a->date ) - strtotime( $b->date );
} );
$posts = array_reverse( $posts );
return $posts;
}
}
<?php
require_once 'class-aggregator.php';
$endpoints = new CU_Rest_Aggregator([
'https://website.com/wp-json/wp/v2/posts',
'https://website.com/wp-json/wp/v2/posts',
]);
$posts = $endpoints->get_posts();
/**
* Available public functions to use.
*/
$endpoints->disable_cache = true;
$endpoints->clear_cache = true;
foreach ( $posts as $post ) {
echo esc_url( $post->link );
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment