diff --git a/Lib/Formatter/Formatter.php b/Lib/Formatter/Formatter.php new file mode 100644 index 0000000..f4496ca --- /dev/null +++ b/Lib/Formatter/Formatter.php @@ -0,0 +1,76 @@ + class) + */ + protected static function registerFormats(array $formats) { + foreach($formats as $f) { + self::$formats[$f] = get_called_class(); + } + } + + /** + * @return Formatter The formatter to use for this request + */ + public static function getFormatter() { + self::loadFormatters(); + $format = self::getFormatFromHeader(); + + return new $format(); + } + + /** + * Load all formatters in the current directory + */ + private static function loadFormatters() { + preg_match('/(.+)\\\([a-zA-Z0-9]+)/', get_called_class(), $parts); + $us = $parts[2]; + $namespace = $parts[1]; + + $base = __DIR__.'/'; + $ext = '.php'; + $files = glob(sprintf('%s%s%s', $base, '*', $ext)); + foreach($files as $f) { + $c = str_replace(array($base, $ext), '', $f); + if($c !== $us) { + $c = $namespace.'\\'.$c; + call_user_func(array($c, 'init')); + } + } + } + + /** + * @return string The class name to instantiate in accord to the Accept header + */ + private static function getFormatFromHeader() { + if(isset($_SERVER['HTTP_ACCEPT'])) { + $formats = array_map(function($f) { + $parts = explode(';', $f); + $parts[1] = (isset($parts[1]) ? (float) preg_replace('/[^0-9\.]/', '', $parts[1]) : 1.0) * 100; + return $parts; + }, explode(',', $_SERVER['HTTP_ACCEPT'])); + + usort($formats, function($a, $b) { return $b[1] - $a[1]; }); + + foreach($formats as $f) { + if(isset(self::$formats[$f[0]])) { + return self::$formats[$f[0]]; + } + } + + } + + return 'BSR\Lib\Formatter\Json'; + } + + /** + * Output the content for the given data + * @param $array data + */ + abstract public function render($data); +} \ No newline at end of file diff --git a/Lib/Formatter/Html.php b/Lib/Formatter/Html.php new file mode 100644 index 0000000..1575a6b --- /dev/null +++ b/Lib/Formatter/Html.php @@ -0,0 +1,80 @@ + array('funcname' => DATA)) + // so take the first element of the 'result' array + $data = reset($data['result']); + + $first = reset($data); + $single = ! is_array($first); + + $content = ''; + if($single) { + $content .= ""; + } else { + $content .= ''; + foreach(array_keys($first) as $k) { + $content .= ""; + } + $content .= ''; + } + $content .= ''; + if($single) { + foreach($data as $k => $v) { + $content .= ""; + } + } else { + foreach($data as $row) { + $content .= ''; + foreach($row as $col) { + $content .= ''; + } + $content .= ''; + } + } + $content .= '
FieldValue
$k
$k".print_r($v, true)."
'.print_r($col, true).'
'; + + return $content; + } + + private function error($data) { + $code = $data['error']['code']; + $name = $data['error']['name']; + $msg = $data['error']['reason']; + + return '

An error occured

'. + "

[$code] $name

". + "

$msg

"; + } + + private function failure($data) { + $code = $data['failure']['code']; + $name = $data['failure']['reason']; + + return '

A failure occured

'. + "

[$code] $name

"; + } + + public function render($data) + { + $type = key($data); + + if (method_exists($this, $type)) { + $content = call_user_func_array(array($this, $type), array($data)); + } else { + $content = '

Unable to render this

'; + } + + echo $content; + } +} diff --git a/Lib/Formatter/Json.php b/Lib/Formatter/Json.php new file mode 100644 index 0000000..647ca96 --- /dev/null +++ b/Lib/Formatter/Json.php @@ -0,0 +1,17 @@ + 'Ok', + 400 => 'Bad request', + 404 => 'Not Found', + 403 => 'Not Authorized', + 500 => 'Server Error', + ); + + public function __construct() { + ob_start(); + } + + public function render($status, $data) { + header(sprintf('HTTP/1.0 %s %s', $status, self::$statusMessages[$status])); + + ob_clean(); + flush(); + + $formatter = Formatter::getFormatter(); + $formatter->render($data); + } +} \ No newline at end of file diff --git a/Lib/WebService.php b/Lib/WebService.php index 0aed98a..97e2cf3 100644 --- a/Lib/WebService.php +++ b/Lib/WebService.php @@ -3,6 +3,7 @@ namespace BSR\Lib; use BSR\Lib\Exception\WebException; +use BSR\Lib\Renderer; abstract class WebService { @@ -30,6 +31,8 @@ abstract class WebService public function Run() { + $renderer = new Renderer(); + $this->log("------------------"); $this->log("Start request", 1, true); $data = array(); @@ -39,19 +42,22 @@ abstract class WebService $data["result"][$this->func] = $result; } catch (WebException $e) { $data["error"]["code"] = $e->getCode(); - $data["error"]["name"] = $e->getName(); $data["error"]["reason"] = $e->getMessage(); + $data["error"]["name"] = $e->getName(); $this->status = 400; $this->log(sprintf("Error : [%s] %s", $e->getCode(), $e->getName())); } catch (\Exception $e) { - $data["failure"]["message"] = $e->getMessage(); + $data["failure"]["code"] = $e->getCode(); + $data["failure"]["reason"] = $e->getMessage(); $this->status = 500; $this->log(sprintf("Failure : %s", $e->getMessage())); } - $this->Send($data); + $this->log("Data: ".print_r($data, true), 2); + + $renderer->render($this->status, $data); $this->log("Request finished", 1, true); $this->log("------------------\n\n"); @@ -63,7 +69,6 @@ abstract class WebService private function Call() { - ob_start(); session_save_path(Configuration::get('session.save_path')); session_start(); @@ -100,23 +105,4 @@ abstract class WebService $this->log("Params: ".print_r($params, true), 2); return call_user_func_array(array($this, $this->func), $params); } - - private function Send(array $data) - { - static $status_messages = array( - 200 => 'Ok', - 400 => 'Bad request', - 404 => 'Not Found', - 403 => 'Not Authorized', - 500 => 'Server Error', - ); - - header(sprintf('HTTP/1.0 %s %s', $this->status, $status_messages[$this->status])); - - ob_clean(); - flush(); - - $this->log("Data: ".print_r($data, true), 2); - echo json_encode($data); - } }