* @copyright Copyright (c) 2008-9 TypeOneError Studios (http://www.typeoneerror.com) * @license MIT ~ http://www.opensource.org/licenses/mit-license.php * @version $Id$ * @link http://typeoneerror.com/asra * @category Asra * @package Core */ /** * @see Asra_Constants_Lang */ require_once "Asra/Constants/Lang.php"; /** * @see Asra_Utils_String */ require_once "Asra/Utils/Strings.php"; /** * Acts as the interface between user-defined controllers * and the API itself. This is the class you should extend * to create more custom API exports. * * @todo add arbitrary get params to url rewrite (zend-style) * * @author Ben Borowski * @copyright Copyright (c) 2008-9 TypeOneError Studios (http://www.typeoneerror.com) * @license MIT ~ http://www.opensource.org/licenses/mit-license.php * @link http://typeoneerror.com/asra * @category Asra * @package Core */ abstract class Asra_Core_Controller { //--------------------------------------- // PRIVATE VARIABLES //--------------------------------------- /** * The controller uses this reference to access the API * * @var API api */ private $__api; //--------------------------------------- // PROTECTED VARIABLES //--------------------------------------- /** * Define some simple table dependencies * * @var array */ protected $_hasMany = array(); /** * Which table does this controller use? * * @var string */ protected $_uses; /** * Define some validation methods * * @var array */ protected $_validate; //--------------------------------------- // PUBLIC VARIABLES //--------------------------------------- /** * Will be set to a post array if a request was sent * * @var array */ public $data; /** * Store validation errors while looping * * @var array */ public $errors; /** * Stored GET params from request * * @var array */ public $varsGet; /** * Stored POST params from request * * @var array */ public $varsPost; //--------------------------------------- // CALL OVERLOAD //--------------------------------------- /** * Handles the controller subclasses calls to the API * * @param string method The name of the method * @param array args The arguments passed to the method * @return void */ public function __call($method, $args) { return call_user_func_array(array($this->__api, $method), $args); } //--------------------------------------- // CONSTRUCTOR //--------------------------------------- /** * Controller init * * @return void */ public function __construct() { $this->_parseRequest(); } /** * Converts class names to table names (PostTypes = post_types) * * @return void */ protected function _approxTableName() { if (!isset($this->_uses)) { $class = get_class($this); $this->_uses = Asra_Utils_Strings::underscore($class); } } /** * Count and export a number * * @param string $table Table to count * @param bool $print Whether to display or return the count; * if true, prints the result with printOut. * @return void */ public function count($table = null, $print = true) { if (is_null($table)) { if (isset($this->_uses)) $table = $this->_uses; else return; } return $this->__api->count($table, $print); } /** * Curl helper. Makes it a bit quicker to use * the curl library without remembering the functions. * * @param string $uri Resource to get * @param array $options Additional curl options * @return string Result of curl transfter * @link http://us.php.net/manual/en/function.curl-setopt.php */ public function curl($uri, $options = null) { $ch = curl_init(); $curlOpts = array( CURLOPT_URL => $uri, CURLOPT_HEADER => false, CURLOPT_RETURNTRANSFER => true, ); if (!is_null($options)) { $curlOpts = array_merge($curlOpts, $options); } curl_setopt_array($ch, $curlOpts); $transfer = curl_exec($ch); curl_close($ch); return $transfer; } /** * Dumps the table to the export with no fancy stuff * * @return void */ public function dump() { if (isset($this->_uses)) { $this->__api->dump($this->_uses); } } /** * Short-hand version of API::query by params * * @param mixed (array|string) $params Params to build query with * @return void */ public function find($params = null) { if (isset($this->_uses)) { $this->__api->find($this->_uses, $params); } } /** * Returns a reference to the database layer. * * @return Asra_Db_MySQL reference. */ public function getDb() { return $this->__api->db; } /** * Objectify the GET vars and return * * @return stdClass Get var array as stdClass */ public function getGetVars() { return (object) $this->varsGet; } /** * Get a list of params based on the URL * * @return array An associative array of params */ public function getParams() { //TODO implement this function } /** * Objectify the POST vars and return * * @return stdClass Post var array as stdClass */ public function getPostVars() { return (object) $this->varsPost; } /** * Check if request is GET * * @return bool True if request method is GET */ public function isGet() { return $_SERVER['REQUEST_METHOD'] == 'GET'; } /** * Check if request is POST * * @return bool True if request method is POST */ public function isPost() { return $_SERVER['REQUEST_METHOD'] == 'POST'; } /** * Selects paginated results based on a page id. * *

* This is a proxy call to API::paginate so it can automatically pull in the * correct table that the controller subclass is using. *

* * @param int $page Page to start from * @param int $perPage Number of results per page * @param array $params Params to apply to find method * @return void */ public function paginate($page = 0, $perPage = 10, $params = null) { if (isset($this->_uses)) { $this->__api->paginate($this->_uses, $page, $perPage, $params); } } /** * If a post request was sent to the API it gets placed in the $data array * * @return void */ protected function _parseRequest() { if ($this->isPost()) { foreach($_POST as $var => $val) { if (!is_array($val)) $val = trim($val); $this->data[$var] = $val; $this->varsPost[$var] = $val; } } else if ($this->isGet()) { foreach($_GET as $var => $val) { if (!is_array($val)) $val = trim($val); $this->varsGet[$var] = $val; } } } /** * Save some data to the database table this control uses * * @param array $data Data to save keyed by fields * @param string $table Table this controller uses * @param bool $output Whether to output the results of the save operation * @return bool Success of insert */ protected function save($data, $table = null, $output = true) { if (is_null($table)) $table = $this->_uses; return $this->__api->save($data, $table, $output); } /** * Passes the api by reference. This is called by the controller that is initialized. * * @param api $api Reference to the api * @return void */ final public function setAPI(&$api) { $this->__api = $api; $this->_approxTableName(); if ($api->getLogQueries()) { $this->__api->log('ASRA_Acesss::' . $_SERVER['REQUEST_URI']); } } /** * Return a single result from this controller's table * * @param int $id The id of the result to grab * @param bool $return Return the result instead of printing it out * @return If $return is true, return an array, otherwise, void */ public function single($id = null, $return = false) { if ($id != null && isset($this->_uses)) { $id = (int) $id; $query = "SELECT * FROM {$this->_uses} WHERE id = " . Asra_Utils_Strings::makesafe($id); $result = $this->__api->run($query); if (!$return) $this->__api->printOut($result); else return $result; } } /** * Check the data against the fields you want to validate - taken from CakePHP * * @return bool * @link http://www.cakephp.org */ public function validates() { $validates = true; $data = $this->data; if (!isset($this->_validate)) return $validates; foreach ($this->_validate as $field_name => $validator) { if (!isset($data[$field_name]) || !preg_match($validator, $data[$field_name])) { $validates = false; if (!is_array($this->errors)) $this->errors = array(); $this->errors[$field_name] = 1; } } return count($this->errors) == 0; } }