Last active
July 2, 2020 04:37
-
-
Save gabrielcatellier/b6b9b0b3f6a3658cdd04da530ec61c72 to your computer and use it in GitHub Desktop.
Wordpress endpoint aggregator with Cache
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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