Skip to content

Instantly share code, notes, and snippets.

@paulslugocki
Created July 14, 2014 19:55
Show Gist options
  • Save paulslugocki/abee90986dda1f269d57 to your computer and use it in GitHub Desktop.
Save paulslugocki/abee90986dda1f269d57 to your computer and use it in GitHub Desktop.
<?php
class CachedTourCMS {
// General settings
protected $marketp_id = 0;
protected $private_key = "";
protected $result_type = "";
// Cache settings
public $cache_dir = 'cache';
public $cache_rules = array(
"search_tours" => array("time" => 1800),
"show_tour" => array("time" => 3600),
"show_tour_datesanddeals" => array("time" => 900),
"list_channels" => array("time" => 3600),
"show_channel" => array("time" => 3600),
"show_supplier" => array("time" => 3600)
);
// TourCMS object
protected $tourcms;
/**
* __construct
*
* @author Paul Slugocki
* @param $mp Marketplace ID
* @param $k API Private Key
* @param $res Result type, defaults to raw
* @param $cache_rules
*/
public function __construct($mp, $k, $res = "raw", $cache_rules = null) {
$this->marketp_id = $mp;
$this->private_key = $k;
$this->result_type = $res;
if($cache_rules != null)
$this->cache_rules = $cache_rules;
$this->tourcms = new TourCMS($mp, $k, $res);
}
// Overload function
public function __call($name, $arguments) {
// Request is cachable if we have settings for this method
$cachable_request = array_key_exists($name, $this->cache_rules);
// If request is cachable, try loading
if($cachable_request) {
$cached_content = $this->get_cache($name, $arguments);
if($cached_content != "") {
if($this->result_type == "simplexml")
return simplexml_load_string($cached_content);
else
return $cached_content;
}
}
// No cache, outdated cache or uncacheable request
// Call TourCMS object to get response
$response = call_user_func_array(array($this->tourcms, $name), $arguments);
// Set cache
if($cachable_request) {
$this->set_cache($name, $arguments, $response);
}
// Return
return $response;
}
// Get the cache for a given API query
private function get_cache($name, $arguments) {
$filename = $this->get_filename($name, $arguments);
// Check the file exists
if(file_exists($filename)) {
// Check it's not outdated
$file_time = filemtime($filename);
$cache_time = $this->cache_rules[$name]["time"];
$file_outdated = $file_time + $cache_time < time();
if(!$file_outdated) {
return file_get_contents($filename);
}
}
// If we got this far, just return an empty cache
return '';
}
// Set the cache for a given API query
private function set_cache($name, $arguments, $data) {
// If data is empty, return
if($data == '')
return;
$filename = $this->get_filename($name, $arguments);
// Create the method specific directory if it doesn't already exist
if(!is_dir($this->cache_dir . DIRECTORY_SEPARATOR . $name))
mkdir($this->cache_dir . DIRECTORY_SEPARATOR . $name);
// Make sure we have SimpleXML so we can check for errors
if($this->result_type != "simplexml")
$data = simplexml_load_string($data);
// As long as there's no errors, store the cache
if($data->error == "OK") {
$data = $data->asXml();
file_put_contents($filename, $data);
}
}
// Returns the full path to the cache file
private function get_filename($name, $arguments) {
return $this->cache_dir . DIRECTORY_SEPARATOR . $name . DIRECTORY_SEPARATOR . $this->array_to_filename($arguments) . ".xml";
}
// Convert an array into a filename
private function array_to_filename($arr) {
return base64_encode(serialize($arr));
}
}
@paulslugocki
Copy link
Author

Cache TourCMS API requests

A quick, minimal code change, solution to enable caching of TourCMS API requests.

Speeds up website response and helps avoid hitting API rate limits.

If you are using a framework or CMS that provides caching functions, you may be better placed using those. Similarly those running high volume sites will likely require something more powerful than a basic file cache.

More on caching TourCMS API requests.

Installation / configuration

(Assumes you are already using the TourCMS PHP API wrapper, tourcms.php, if not you may want to get that working now, with a single API request at least )

1. Download tourcms-cache-file.php alongside wherever you have tourcms.php

2. Include tourcms-cache-file.php in your PHP script

3. Find wherever you create a new TourCMS object, replace the call with one to create a new CachedTourCMS object.

Your existing code for creating a new TourCMS wrapper object will look something like:

$tourcms = new TourCMS($marketplace_account_id, $api_private_key, "simplexml");

Change new TourCMS to be new CachedTourCMS, giving something like:

$tourcms = new CachedTourCMS($marketplace_account_id, $api_private_key, "simplexml");

4. Set the cache directory. [IMPORTANT]

By default this is set to cache, however it should likely be somewhere not accessible by a web browser. The directory must exist and be writeable by PHP.

$tourcms->cache_directory = '/your/cache/directory/';

5. Set the cache times (in seconds). [OPTIONAL]

The defaults are suggested for production websites. To exclude any methods from caching just configure them with 0 times, or leave them out of the config that you pass.

E.g. to only cache 'Tour Show' for 30 minutes and 'Tour Search' for 15, leaving all other methods uncached:

$tourcms->cache_rules = array(
    "show_tour" => 900,
    "search_tours" => 1800,
);

Or to disable caching, perhaps for testing:

$tourcms->cache_rules = array();

As mentioned, you can likely use the default, skipping this step.

Full example

<?php

// Include the regular TourCMS wrapper
include_once('tourcms.php');

// Include the cache wrapper
include_once('tourcms-cache-file.php');

// Create a new cached TourCMS object
$marketplace_id = 0;
$api_key = "";
$tourcms = new CachedTourCMS($marketplace_id, $api_key, "simplexml");

// Set the cache directory
$tourcms->cache_dir = '../cache';

// Call "Search Tours"
$channel_id = 0;
$result = $tourcms->search_tours('', $channel_id);

// Display results;
print "<pre>";
print_r($result);
print "</pre>";

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment