You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

113 lines
3.5 KiB
PHP

<?php
namespace BSR\Webservice;
use BSR\Webservice\Exception\UsageException;
use BSR\Webservice\Exception\WebException;
use BSR\Utils\Configuration\Configuration;
use BSR\Utils\Logger\Logger;
abstract class WebService
{
private $func = null;
private $status = 200;
private $version = null;
public function __construct($version) {
$this->version = $version;
}
/**
* Treat the current request and output the result. This is the only
* method that should be called on the webservice directly !
* @param bool $sendSession needed for testing
*/
public function run($sendSession = true)
{
Logger::start(array('version' => $this->version));
$rendererClass = Configuration::get('renderer.class', __NAMESPACE__ . '\Renderer');
$renderer = new $rendererClass;
$data = array();
try {
$result = $this->call($sendSession);
$data["result"][$this->func] = $result;
// Logger::log(print_r($result, true));
} catch (WebException $e) {
$data["error"]["code"] = $e->getCode();
$data["error"]["reason"] = $e->getMessage();
$data["error"]["name"] = $e->getName();
$data['extra'] = Help::exception($e, $this, $this->func);
$this->status = 400;
Logger::info($e->getName(), 'error');
} catch (\Exception $e) {
$data["failure"]["code"] = $e->getCode();
$data["failure"]["reason"] = $e->getMessage();
$this->status = 500;
Logger::info($e->getMessage(), 'error');
}
Logger::stop(array('status' => $this->status));
$renderer->render($this->status, $data);
}
/**
* Determines which method to call based on GET or POST parameters and
* call it before returning the result.
*
* @param bool $sendSession used for testing
* @return array
* @throws UsageException
*/
private function call($sendSession = true)
{
if ($sendSession) {
session_save_path(Configuration::get('session.save_path'));
session_start();
}
$params = empty($_GET) ? $_POST : $_GET;
if (empty($params)) {
throw new UsageException("NoArguments", "No arguments specified.", UsageException::NO_ARGS);
}
if (!array_key_exists("func", $params)) {
throw new UsageException("MissingMethod", "No method specified.", UsageException::MISSING_METHOD);
}
$this->func = $params["func"];
unset($params['func']);
Logger::info(array(
'func' => $this->func.'('.implode(', ', $params).')',
));
if (!is_callable(array($this, $this->func))) {
throw new UsageException("BadMethod", "Method {$this->func} does not exists.", UsageException::BAD_METHOD);
}
$rm = new \ReflectionMethod($this, $this->func);
$nbParams = count($params);
$nbArgsFix = $rm->getNumberOfRequiredParameters();
$nbArgs = $rm->getNumberOfParameters();
/* Check the number of arguments. */
if ($nbParams < $nbArgsFix) {
throw new UsageException("TooFewArgs", "You must provide at least $nbArgsFix arguments.", UsageException::TOO_FEW_ARGS);
}
if ($nbParams > $nbArgs) {
throw new UsageException("TooManyArgs", "You must provide at most $nbArgs arguments.", UsageException::TOO_MANY_ARGS);
}
return call_user_func_array(array($this, $this->func), $params);
}
}