/lib/App/REST.php
PHP | 196 lines | 123 code | 30 blank | 43 comment | 17 complexity | 9dce4e19e63a4230a53207dcec89c949 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception
- <?php
- /**
- * REST Server implementation for Agile Toolkit.
- *
- * This class takes advantage of the tight integration for Agile Toolkit
- * to enhance and make it super simple to create an awesome API for
- * your existing application.
- */
- // @codingStandardsIgnoreStart because REST is acronym
- class App_REST extends App_CLI
- {
- // @codingStandardsIgnoreEnd
- public $doc_page = 'app/rest';
- public $page;
- public $endpoint;
- public $version;
- /**
- * Initialization.
- */
- public function init()
- {
- parent::init();
- try {
- // Extra 24-hour protection
- parent::init();
- $this->getLogger();
- $this->pm = $this->add($this->pagemanager_class, $this->pagemanager_options);
- /** @type Controller_PageManager $this->pm */
- $this->pm->parseRequestedURL();
- // It's recommended that you use versioning inside your API,
- // for example http://api.example.com/v1/user
- //
- // This way version is accessible anywhere from $this->app->version
- list($this->version,) = explode('_', $this->page, 2);
- // Add-ons may define additional endpoints for your API, but
- // you must activate them explicitly.
- $this->pathfinder->base_location->defineContents(array('endpoint' => 'endpoint'));
- } catch (Exception $e) {
- $this->caughtException($e);
- }
- }
- /**
- * Output will be properly fromatted.
- *
- * @param mixed $data
- */
- public function encodeOutput($data)
- {
- // TODO - use HTTP_ACCEPT here ?
- //var_dump($_SERVER['HTTP_ACCEPT']);
- if ($_GET['format'] == 'xml') {
- throw $this->exception('only JSON format is supported', null, 406);
- }
- if ($_GET['format'] == 'json_pretty') {
- header('Content-type: application/json');
- echo json_encode($data, JSON_PRETTY_PRINT);
- return;
- }
- if ($_GET['format'] == 'html') {
- echo '<pre>';
- echo json_encode($data, JSON_PRETTY_PRINT);
- return;
- }
- header('Content-type: application/json');
- if ($data === null) {
- $data = array();
- }
- echo json_encode($data);
- }
- /**
- * Main.
- */
- public function main()
- {
- $this->execute();
- $this->hook('saveDelayedModels');
- }
- /**
- * Execute.
- */
- public function execute()
- {
- try {
- try {
- $file = $this->app->locatePath('endpoint', str_replace('_', '/', $this->page).'.php');
- include_once $file;
- $this->pm->base_path = '/';
- } catch (Exception $e) {
- http_response_code(500);
- if ($e instanceof Exception_Pathfinder) {
- $error = array(
- 'error' => 'No such endpoint',
- 'type' => 'API_Error',
- );
- } else {
- $error = array(
- 'error' => 'Problem with endpoint',
- 'type' => 'API_Error',
- );
- }
- $this->caughtException($e);
- $this->encodeOutput($error);
- return;
- }
- try {
- $class = 'endpoint_'.$this->page;
- $this->endpoint = $this->add($class);
- $this->endpoint->app = $this;
- $this->endpoint->api = $this->endpoint->app; // compatibility with ATK 4.2 and lower
- $method = strtolower($_SERVER['REQUEST_METHOD']);
- $raw_post = file_get_contents('php://input');
- if ($raw_post && $raw_post[0] == '{') {
- $args = json_decode($raw_post, true);
- } elseif ($method == 'put') {
- parse_str($raw_post, $args);
- } else {
- $args = $_POST;
- }
- if ($_GET['method']) {
- $method .= '_'.$_GET['method'];
- }
- if (!$this->endpoint->hasMethod($method)) {
- throw $this->exception('Method does not exist for this endpoint', null, 404)
- ->addMoreInfo('method', $method)
- ->addMoreInfo('endpoint', $this->endpoint)
- ;
- }
- $this->logRequest($method, $args);
- // Perform the desired action
- $this->encodeOutput($this->endpoint->$method($args));
- $this->logSuccess();
- } catch (Exception $e) {
- $this->caughtException($e);
- http_response_code($e->getCode() ?: 500);
- $error = array(
- 'error' => $e->getMessage(),
- 'type' => get_class($e),
- 'more_info' => $e instanceof BaseException ? $e->more_info : null,
- );
- array_walk_recursive($error, function (&$item) {
- if (is_object($item)) {
- $item = (string) $item;
- }
- });
- $this->encodeOutput($error);
- }
- } catch (Exception $e) {
- $this->caughtException($e);
- }
- }
- /**
- * Override to extend the logging.
- *
- * @param string $method
- * @param array $args
- */
- public function logRequest($method, $args)
- {
- }
- /**
- * Overwrite to extend the logging.
- */
- public function logSuccess()
- {
- }
- }