Skip to content

Instantly share code, notes, and snippets.

@eyedol
Created October 22, 2010 17:55
Show Gist options
  • Save eyedol/641031 to your computer and use it in GitHub Desktop.
Save eyedol/641031 to your computer and use it in GitHub Desktop.
<?php defined('SYSPATH') or die('No direct script access allowed');
/**
* Api_Service
*
* This class runs the API service. It abstracts the details of handling of the API
* requests from the API controller. All task switching and routing is handled by
* this class.
*
* The API routing works through inversion of control (IoC). The name of the library
* that services the api request is inferred from the name of the task. Not all API
* requests have their own libraries. As such, this service makes use of a
* "task routing table". This table is a key=>value array with the key being the
* name of the api task and the value the name of the implementing library
*
* PHP version 5
* LICENSE: This source file is subject to LGPL license
* that is available through the world-wide-web at the following URI:
* http://www.gnu.org/copyleft/lesser.html
* @author Ushahidi Team <team@ushahidi.com>
* @package Ushahidi - http://source.ushahididev.com
* @module API Controller
* @copyright Ushahidi - http://www.ushahidi.com
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License (LGPL)
*/
final class Api_Service {
private $request = array();
private $response; // Response to be returned to the calling controller
private $response_type;
private $api_task_routing_table; // Routing table for api tasks
public function __construct()
{
// Set the request data
$this->request = ($_SERVER['REQUEST_METHOD'] == 'POST')
? $_POST
: $_GET;
// Initialize the API routing table
$this->_init_routing_table();
}
/**
* Runs the API service
*/
public function run_service()
{
// Route the API task
$this->_route_api_task();
}
public function get_request()
{
return $this->request;
}
/**
* Sets the response type
* @param $response_type New value for $this->response_type
*/
public function set_response_type($response_type)
{
$this->response_type = $response_type;
}
/**
* Returns the response type
*/
public function get_response_type()
{
return $this->response_type;
}
public function get_response()
{
return $this->response;
}
private function _route_api_task()
{
$task = null;
// Make sure we have a task to work with
if (! $this->verify_array_index($this->request, 'task'))
{
$this->set_response($this->get_error_msg(002));
return;
}
else
{
$task = $this->request['task'];
}
$library_file_name = ucfirst($task).'_Api_Object';
// Load the base API library
require_once Kohana::find_file('libraries/api', 'Api_Object');
if (Kohana::find_file('libraries/api',
Kohana::config('config.extension_prefix').$library_file_name)) // Library file exists
{
include Kohana::find_file('libraries/api', Kohana::config('config.extension_prefix').$library_file_name);
// Create instance of the implementing library/class
$api_object = new $library_file_name(&$this);
// Perform the requested task
$api_object->perform_task();
// Set the response data
$this->response = $api_object->get_response_data();
}
else // Library file doesn't exist therefore lookup the task from routing table
{
$task_handler = $this->_get_task_handler($task);
if (isset($task_handler))
{
// Check if the handler is an array
if (is_array($task_handler))
{
// Load the library for the specified class
include Kohana::find_file('libraries/api', Kohana::config('config.extension_prefix').$task_handler["class"]);
// Create instance of the implementing library/class
$api_object = new $task_handler["class"](&$this);
// Execute the callback function
call_user_func(array($api_object, $task_handler["method"]));
// Set the response data
$this->response = $api_object->get_response_data();
}
else
{
// Load the library specified in $task_handler
include Kohana::find_file('libraries/api', Kohana::config('config.extension_prefix').$task_handler);
// Create an instance of the implementing library/class
$api_object = new $task_handler(&$this);
// Perform the requested task
$api_object->perform_task();
// Set the response data
$this->response = $api_object->get_response_data();
}
}
else // No handler exists therefore return not found error
{
$this->response = json_encode(array(
"error" => $this->get_error_msg(999)
));
}
}
}
/**
* Sets the response data
*/
public function set_response($response_data)
{
$this->response = $response_data;
}
/**
* Makes sure the appropriate key is there in a given
* array (POST or GET) and that it is set
* @param ar Array - The given array.
* @param index String - The index array
*
* @return Boolean
*/
public function verify_array_index(&$arr, $index)
{
if (isset($arr[$index]) AND array_key_exists($index, $arr))
{
return true;
}
else
{
return false;
}
}
/**
* Displays Error codes with their corresponding messages.
* returns an array error - array("code" => "CODE",
* "message" => "MESSAGE") based on the given code
*
* @param errcode String - The error code to be displayed.
* @param param String - The missing parameter.
* @param message String - The error message to be displayed.
*
* @return - Array
*/
public function get_error_msg($errcode, $param = '', $message='')
{
switch($errcode)
{
case 0:
return array("code" => "0", "message" =>
Kohana::lang('ui_admin.no_error'));
case 001:
return array("code" => "001",
"message" => Kohana::lang('ui_admin.missing_parameter')." - $param."
);
case 002:
return array("code" => "002", "message" =>
Kohana::lang('ui_admin.invalid_parameter'));
case 003:
return array("code" => "003", "message" => $message );
case 004:
return array("code" => "004", "message" =>
Kohana::lang('ui_admin.post_method_not_used'));
case 005:
return array("code" => "005", "message" =>
Kohana::lang('ui_admin.access_denied_credentials'));
case 006:
return array("code" => "006", "message" =>
Kohana::lang('ui_admin.access_denied_others'));
default:
return array("code" => "999", "message" =>
Kohana::lang('ui_admin.not_found'));
}
}
/**
* Initializes the API task routing table
* ------
* NOTES
* ------
* The task routing table faciliates handling of api tasks that don't have independent
* their own handling libraries. The format of the table is as follows:
* $task => $library_name
* Where:
* $task - The name of the API task
* $library - Name of the library in which the task is to be handled or an associative array
* specifying the library name and method to be executed
*/
private function _init_routing_table()
{
$this->api_task_routing_table = array(
"version" => array(
"class" => "System_Api_Object",
"method" => "get_version_number"
),
"mhienabled" => array(
"class" => "System_Api_Object",
"method" => "get_mhi_enabled"
),
"mapcenter" => array(
"class" => "System_Api_Object",
"method" => "get_map_center"
),
"country" => "Countries_Api_Object",
"location" => "Locations_Api_Object",
"3dkml" => "Kml_Api_Object",
"geographicmidpoint" => array(
"class" => "Incidents_Api_Object",
"method" => "get_geographic_midpoint"
),
"incidentcount" => array(
"class" => "Incidents_Api_Object",
"method" => "get_incident_count"
),
"apikeys" => "Api_Key_Object"
);
}
/**
* Looks up the task routing table for the library that handles the task
* specified in @param $task
*
* $task - Task whose handling library is to be retrieved
*/
private function _get_task_handler($task)
{
return (array_key_exists($task, $this->api_task_routing_table))
? $this->api_task_routing_table[$task]
: NULL;
}
}
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment