appwrite/src/Appwrite/Utopia/Response.php

230 lines
7.6 KiB
PHP
Raw Normal View History

2020-05-16 11:28:26 +00:00
<?php
2020-06-22 12:17:14 +00:00
namespace Appwrite\Utopia;
2020-05-16 11:28:26 +00:00
use Exception;
2020-06-05 09:53:06 +00:00
use Appwrite\Database\Document;
2020-08-15 11:39:44 +00:00
use Utopia\Swoole\Response as SwooleResponse;
2020-08-14 21:56:33 +00:00
use Swoole\Http\Response as SwooleHTTPResponse;
2020-06-23 15:01:20 +00:00
use Appwrite\Utopia\Response\Model;
2020-08-07 06:33:49 +00:00
use Appwrite\Utopia\Response\Model\BaseList;
2020-06-23 15:01:20 +00:00
use Appwrite\Utopia\Response\Model\Error;
use Appwrite\Utopia\Response\Model\ErrorDev;
2020-08-08 11:01:23 +00:00
use Appwrite\Utopia\Response\Model\Execution;
2020-08-06 14:49:29 +00:00
use Appwrite\Utopia\Response\Model\File;
2020-08-07 07:15:50 +00:00
use Appwrite\Utopia\Response\Model\Func;
2020-08-15 21:35:44 +00:00
use Appwrite\Utopia\Response\Model\Key;
2020-06-23 15:01:20 +00:00
use Appwrite\Utopia\Response\Model\User;
2020-06-24 07:35:59 +00:00
use Appwrite\Utopia\Response\Model\Session;
2020-06-24 05:14:42 +00:00
use Appwrite\Utopia\Response\Model\Team;
2020-06-23 15:01:20 +00:00
use Appwrite\Utopia\Response\Model\Locale;
use Appwrite\Utopia\Response\Model\Membership;
2020-08-08 10:41:17 +00:00
use Appwrite\Utopia\Response\Model\Tag;
2020-08-14 21:56:33 +00:00
use Appwrite\Utopia\Response\Model\Webhook;
2020-05-16 11:28:26 +00:00
2020-08-14 21:56:33 +00:00
class Response extends SwooleResponse
2020-05-16 11:28:26 +00:00
{
2020-06-23 18:53:24 +00:00
// General
const MODEL_LOG = 'log'; // - Missing
2020-06-23 15:01:20 +00:00
const MODEL_ERROR = 'error';
const MODEL_ERROR_DEV = 'errorDev';
2020-06-24 05:14:42 +00:00
const MODEL_BASE_LIST = 'baseList';
2020-08-06 14:49:29 +00:00
const MODEL_PERMISSIONS = 'permissions';
2020-06-23 18:53:24 +00:00
// Users
2020-06-23 15:01:20 +00:00
const MODEL_USER = 'user';
2020-08-09 15:34:33 +00:00
const MODEL_USER_LIST = 'userList';
2020-06-23 18:53:24 +00:00
const MODEL_SESSION = 'session';
2020-08-09 21:20:02 +00:00
const MODEL_SESSION_LIST = 'sessionList';
const MODEL_TOKEN = 'token'; // - Missing
2020-06-23 18:53:24 +00:00
// Database
const MODEL_COLLECTION = 'collection'; // - Missing
2020-06-23 18:53:24 +00:00
// Locale
2020-06-23 15:01:20 +00:00
const MODEL_LOCALE = 'locale';
const MODEL_COUNTRY = 'country'; // - Missing
const MODEL_CONTINENT = 'continent'; // - Missing
const MODEL_CURRENCY = 'currency'; // - Missing
const MODEL_LANGUAGE = 'langauge'; // - Missing
const MODEL_PHONE = 'phone'; // - Missing
2020-06-23 18:53:24 +00:00
// Storage
2020-08-06 14:49:29 +00:00
const MODEL_FILE = 'file';
const MODEL_FILE_LIST = 'fileList';
const MODEL_BUCKET = 'bucket'; // - Missing
2020-06-23 18:53:24 +00:00
// Teams
const MODEL_TEAM = 'team';
2020-06-24 05:14:42 +00:00
const MODEL_TEAM_LIST = 'teamList';
2020-06-25 20:26:02 +00:00
const MODEL_MEMBERSHIP = 'membership';
const MODEL_MEMBERSHIP_LIST = 'membershipList';
2020-06-05 09:53:06 +00:00
2020-08-07 04:39:10 +00:00
// Functions
const MODEL_FUNCTION = 'function';
const MODEL_FUNCTION_LIST = 'functionList';
const MODEL_TAG = 'tag';
const MODEL_TAG_LIST = 'tagList';
const MODEL_EXECUTION = 'execution';
const MODEL_EXECUTION_LIST = 'executionList';
2020-08-14 21:56:33 +00:00
// Project
const MODEL_PROJECT = 'project';
const MODEL_PROJECT_LIST = 'projectsList';
const MODEL_WEBHOOK = 'webhook';
const MODEL_WEBHOOK_LIST = 'webhookList';
const MODEL_KEY = 'key';
const MODEL_KEY_LIST = 'keyList';
const MODEL_TASK = 'task';
const MODEL_TASK_LIST = 'taskList';
const MODEL_PLATFORM = 'platform';
const MODEL_PLATFORM_LIST = 'platformList';
const MODEL_DOMAIN = 'domain';
const MODEL_DOMAIN_LIST = 'domainList';
2020-08-07 04:39:10 +00:00
2020-06-26 12:27:58 +00:00
/**
* Response constructor.
*/
2020-08-14 21:56:33 +00:00
public function __construct(SwooleHTTPResponse $response)
2020-06-05 09:53:06 +00:00
{
$this
2020-08-07 06:33:49 +00:00
// General
2020-06-23 15:01:20 +00:00
->setModel(new Error())
->setModel(new ErrorDev())
2020-08-07 06:33:49 +00:00
// Lists
2020-08-09 15:34:33 +00:00
->setModel(new BaseList('Users List', self::MODEL_USER_LIST, 'users', self::MODEL_USER))
2020-08-09 21:20:02 +00:00
->setModel(new BaseList('Sessions List', self::MODEL_SESSION_LIST, 'sessions', self::MODEL_SESSION))
2020-08-07 06:33:49 +00:00
->setModel(new BaseList('Files List', self::MODEL_FILE_LIST, 'files', self::MODEL_FILE))
->setModel(new BaseList('Teams List', self::MODEL_TEAM_LIST, 'teams', self::MODEL_TEAM))
->setModel(new BaseList('Memberships List', self::MODEL_MEMBERSHIP_LIST, 'memberships', self::MODEL_MEMBERSHIP))
->setModel(new BaseList('Functions List', self::MODEL_FUNCTION_LIST, 'functions', self::MODEL_FUNCTION))
->setModel(new BaseList('Tags List', self::MODEL_TAG_LIST, 'tags', self::MODEL_TAG))
->setModel(new BaseList('Executions List', self::MODEL_EXECUTION_LIST, 'executions', self::MODEL_EXECUTION))
2020-08-17 21:57:03 +00:00
->setModel(new BaseList('Projects List', self::MODEL_PROJECT_LIST, 'projects', self::MODEL_PROJECT))
->setModel(new BaseList('Webhooks List', self::MODEL_WEBHOOK_LIST, 'webhooks', self::MODEL_WEBHOOK))
2020-08-15 21:35:44 +00:00
->setModel(new BaseList('API Keys List', self::MODEL_KEY_LIST, 'keys', self::MODEL_KEY))
2020-08-17 21:57:03 +00:00
->setModel(new BaseList('Tasks List', self::MODEL_TASK_LIST, 'tasks', self::MODEL_TASK))
->setModel(new BaseList('Platforms List', self::MODEL_PLATFORM_LIST, 'platforms', self::MODEL_PLATFORM))
->setModel(new BaseList('Domains List', self::MODEL_DOMAIN_LIST, 'domains', self::MODEL_DOMAIN))
2020-08-07 06:33:49 +00:00
// Entities
2020-06-23 15:01:20 +00:00
->setModel(new User())
2020-06-24 07:35:59 +00:00
->setModel(new Session())
2020-06-23 15:01:20 +00:00
->setModel(new Locale())
2020-08-06 14:49:29 +00:00
->setModel(new File())
2020-06-24 05:14:42 +00:00
->setModel(new Team())
->setModel(new Membership())
2020-08-07 06:33:49 +00:00
->setModel(new Func())
2020-08-08 10:41:17 +00:00
->setModel(new Tag())
2020-08-08 11:01:23 +00:00
->setModel(new Execution())
2020-08-14 21:56:33 +00:00
->setModel(new Webhook())
2020-08-15 21:35:44 +00:00
->setModel(new Key())
2020-06-05 09:53:06 +00:00
;
2020-07-04 18:21:42 +00:00
2020-08-14 21:56:33 +00:00
parent::__construct($response);
2020-06-05 09:53:06 +00:00
}
2020-05-16 11:28:26 +00:00
/**
* HTTP content types
*/
const CONTENT_TYPE_YAML = 'application/x-yaml';
2020-06-05 09:53:06 +00:00
/**
* List of defined output objects
*/
2020-06-23 15:01:20 +00:00
protected $models = [];
2020-06-05 09:53:06 +00:00
/**
2020-06-23 15:01:20 +00:00
* Set Model Object
2020-06-05 09:53:06 +00:00
*
* @return self
*/
2020-06-23 15:01:20 +00:00
public function setModel(Model $instance): self
2020-05-16 11:28:26 +00:00
{
2020-06-23 15:01:20 +00:00
$this->models[$instance->getType()] = $instance;
2020-06-05 09:53:06 +00:00
return $this;
}
/**
2020-06-23 15:01:20 +00:00
* Get Model Object
2020-06-05 09:53:06 +00:00
*
2020-06-23 15:01:20 +00:00
* @return Model
2020-06-05 09:53:06 +00:00
*/
2020-06-23 15:01:20 +00:00
public function getModel(string $key): Model
2020-06-05 09:53:06 +00:00
{
2020-06-23 15:01:20 +00:00
if(!isset($this->models[$key])) {
throw new Exception('Undefined model: '.$key);
2020-06-05 09:53:06 +00:00
}
2020-06-23 15:01:20 +00:00
return $this->models[$key];
2020-06-05 09:53:06 +00:00
}
/**
* Validate response objects and outputs
* the response according to given format type
*/
2020-06-23 15:01:20 +00:00
public function dynamic(Document $document, string $model)
2020-06-05 09:53:06 +00:00
{
2020-06-24 06:05:43 +00:00
return $this->json($this->output($document, $model));
}
/**
* Generate valid response object from document data
*/
protected function output(Document $document, string $model): array
{
$data = $document;
2020-06-23 15:01:20 +00:00
$model = $this->getModel($model);
2020-06-05 09:53:06 +00:00
$output = [];
2020-06-23 15:01:20 +00:00
foreach($model->getRules() as $key => $rule) {
2020-06-24 06:05:43 +00:00
if(!$document->isSet($key)) {
2020-06-22 14:33:37 +00:00
if(!is_null($rule['default'])) {
2020-06-24 06:05:43 +00:00
$document->setAttribute($key, $rule['default']);
2020-06-22 14:33:37 +00:00
}
else {
2020-08-09 21:20:02 +00:00
throw new Exception('Model '.$model->getName().' is missing response key: '.$key);
2020-06-22 14:33:37 +00:00
}
2020-06-05 09:53:06 +00:00
}
2020-06-24 06:05:43 +00:00
if($rule['array']) {
if(!is_array($data[$key])) {
2020-08-08 10:41:17 +00:00
throw new Exception($key.' must be an array of type '.$rule['type']);
2020-06-24 06:05:43 +00:00
}
foreach ($data[$key] as &$item) {
if(array_key_exists($rule['type'], $this->models) && $item instanceof Document) {
$item = $this->output($item, $rule['type']);
}
}
2020-06-23 15:01:20 +00:00
}
2020-06-05 09:53:06 +00:00
$output[$key] = $data[$key];
}
2020-06-24 06:05:43 +00:00
return $output;
2020-05-16 11:28:26 +00:00
}
/**
* YAML
*
* This helper is for sending YAML HTTP response.
* It sets relevant content type header ('application/x-yaml') and convert a PHP array ($data) to valid YAML using native yaml_parse
*
* @see https://en.wikipedia.org/wiki/YAML
*
* @param array $data
*/
public function yaml(array $data)
{
if(!extension_loaded('yaml')) {
throw new Exception('Missing yaml extension. Learn more at: https://www.php.net/manual/en/book.yaml.php');
}
$this
->setContentType(Response::CONTENT_TYPE_YAML)
->send(yaml_emit($data, YAML_UTF8_ENCODING))
;
}
}