Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions examples/errors_all_options.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,15 @@
$error->add_meta($key='foo', $meta_data='bar');
$error->fill_meta($meta_data=['bar' => 'baz']);

// or as object
$meta_object = new stdClass();
$meta_object->property = 'value';
$error->add_meta($key='object', $meta_object);

// the http status code
// @note it is better to set this on the jsonapi\errors object ..
// .. as only a single one can be consumed by the browser
$error->set_http_status($http_status=\alsvanzelf\jsonapi\base::STATUS_NOT_FOUND);
$error->set_http_status($http_status=\alsvanzelf\jsonapi\response::STATUS_NOT_FOUND);

// if not set during construction, set them here
$error->set_error_message($error_message='too much options');
Expand All @@ -40,7 +45,7 @@
*/

$another_error = new \alsvanzelf\jsonapi\error('kiss', 'Error objects can be small and simple as well.');
$some_exception = new Exception('please don\'t throw things', \alsvanzelf\jsonapi\base::STATUS_INTERNAL_SERVER_ERROR);
$some_exception = new Exception('please don\'t throw things', \alsvanzelf\jsonapi\response::STATUS_INTERNAL_SERVER_ERROR);

/**
* building up the json response
Expand All @@ -56,7 +61,7 @@
$jsonapi->add_error($another_error);
$jsonapi->add_exception($some_exception);

$jsonapi->set_http_status(\alsvanzelf\jsonapi\base::STATUS_BAD_REQUEST);
$jsonapi->set_http_status(\alsvanzelf\jsonapi\response::STATUS_BAD_REQUEST);

/**
* sending the response
Expand Down
2 changes: 1 addition & 1 deletion examples/errors_exception.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
*/

try {
throw new Exception('unknown user', \alsvanzelf\jsonapi\base::STATUS_NOT_FOUND);
throw new Exception('unknown user', \alsvanzelf\jsonapi\response::STATUS_NOT_FOUND);
}
catch (Exception $e) {
$jsonapi = new \alsvanzelf\jsonapi\errors($e);
Expand Down
228 changes: 22 additions & 206 deletions src/base.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,39 +5,40 @@
class base {

/**
* advised http status codes
* @deprecated
* @see response::STATUS_*
*/
const STATUS_BAD_REQUEST = 400;
const STATUS_UNAUTHORIZED = 401;
const STATUS_FORBIDDEN = 403;
const STATUS_NOT_FOUND = 404;
const STATUS_METHOD_NOT_ALLOWED = 405;
const STATUS_UNPROCESSABLE_ENTITY = 422;
const STATUS_INTERNAL_SERVER_ERROR = 500;
const STATUS_SERVICE_UNAVAILABLE = 503;
const STATUS_BAD_REQUEST = response::STATUS_BAD_REQUEST;
const STATUS_UNAUTHORIZED = response::STATUS_UNAUTHORIZED;
const STATUS_FORBIDDEN = response::STATUS_FORBIDDEN;
const STATUS_NOT_FOUND = response::STATUS_NOT_FOUND;
const STATUS_METHOD_NOT_ALLOWED = response::STATUS_METHOD_NOT_ALLOWED;
const STATUS_UNPROCESSABLE_ENTITY = response::STATUS_UNPROCESSABLE_ENTITY;
const STATUS_INTERNAL_SERVER_ERROR = response::STATUS_INTERNAL_SERVER_ERROR;
const STATUS_SERVICE_UNAVAILABLE = response::STATUS_SERVICE_UNAVAILABLE;

/**
* content type headers
* @deprecated
* @see response::CONTENT_TYPE_*
*/
const CONTENT_TYPE_OFFICIAL = 'application/vnd.api+json';
const CONTENT_TYPE_DEBUG = 'application/json';
const CONTENT_TYPE_OFFICIAL = response::CONTENT_TYPE_OFFICIAL;
const CONTENT_TYPE_DEBUG = response::CONTENT_TYPE_DEBUG;

/**
* json encode options
* default is JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE
* in debug mode (@see ::$debug) JSON_PRETTY_PRINT is added
* @deprecated
* @see response::ENCODE_*
*/
const ENCODE_DEFAULT = 320;
const ENCODE_DEBUG = 448;
const ENCODE_DEFAULT = response::ENCODE_DEFAULT;
const ENCODE_DEBUG = response::ENCODE_DEBUG;

/**
* debug modus for non-production environments
*
* this is automatically set based on the display_errors directive
* it can be overridden by setting it to a boolean value
*
* - encodes json with in pretty print (@see ::ENCODE_DEBUG) (*)
* - makes browser display json instead of offering a file (@see ::CONTENT_TYPE_DEBUG) (*)
* - encodes json with in pretty print (@see response::ENCODE_DEBUG) (*)
* - makes browser display json instead of offering a file (@see response::CONTENT_TYPE_DEBUG) (*)
* - outputs the error message for errors (@see error->get_array())
* - outputs exception details for errors (@see errors->add_exception())
*
Expand All @@ -47,201 +48,16 @@ class base {
public static $debug = null;

/**
* internal data containers
*/
protected $links = array();
protected $meta_data = array();
protected $included_resources = array();

/**
* base constructor for all response objects (resource, collection, errors)
* base constructor for all objects
*
* a few things are arranged here:
* few things are arranged here:
* - determines ::$debug based on the display_errors directive
* - sets the self link using $_SERVER variables
*
* @see ->set_self_link() to override this default behavior
*/
public function __construct() {
// set debug mode based on display_errors
if (is_null(self::$debug)) {
self::$debug = (bool)ini_get('display_errors');
}

// auto-fill the self link based on the current request
$self_link = $_SERVER['REQUEST_URI'];
if (isset($_SERVER['PATH_INFO'])) {
$self_link = $_SERVER['PATH_INFO'];
}

$this->set_self_link($self_link);
}

/**
* alias for ->get_json()
*
* @see ->get_json()
*
* @return string
*/
public function __toString() {
return $this->get_json();
}

/**
* returns the whole response body as json
* it generates the response via ->get_array()
*
* @see ->get_array() for the structure
* @see json_encode() options
*
* @param int $encode_options optional, $options for json_encode()
* defaults to ::ENCODE_DEFAULT or ::ENCODE_DEBUG, @see ::$debug
* @return json
*/
public function get_json($encode_options=null) {
if (is_int($encode_options) == false) {
$encode_options = self::ENCODE_DEFAULT;
}
if (self::$debug || strpos($_SERVER['HTTP_ACCEPT'], '/json') == false) {
$encode_options = self::ENCODE_DEBUG;
}

$response = $this->get_array();

$json = json_encode($response, $encode_options);

return $json;
}

/**
* sends out the json response to the browser
* this will fetch the response from ->get_json() if not given via $response
*
* @param string $content_type optional, defaults to ::CONTENT_TYPE_OFFICIAL (the official IANA registered one) ..
* .. or to ::CONTENT_TYPE_DEBUG, @see ::$debug
* @param int $encode_options optional, $options for json_encode()
* defaults to ::ENCODE_DEFAULT or ::ENCODE_DEBUG, @see ::$debug
* @param json $response optional, defaults to ::get_json()
* @return void however, a string will be echo'd to the browser
*/
public function send_response($content_type=null, $encode_options=null, $response=null) {
if (is_null($response)) {
$response = $this->get_json($encode_options);
}

if (empty($content_type)) {
$content_type = self::CONTENT_TYPE_OFFICIAL;
}
if (self::$debug || strpos($_SERVER['HTTP_ACCEPT'], '/json') == false) {
$content_type = self::CONTENT_TYPE_DEBUG;
}

header('Content-Type: '.$content_type.'; charset=utf-8');
echo $response;
}

/**
* returns the included resource objects
* this is used by a collection to work with the actual objects
*
* @return array
*/
public function get_included_resources() {
return $this->included_resources;
}

/**
* sets the link to the request used to give this response
* this will end up in response.links.self ..
* and in response.data.links.self for single resource objects
*
* by default this is already set using $_SERVER variables
* use this method to override this default behavior
* @see ::__construct()
*
* @param string $link
* @return void
*/
public function set_self_link($link) {
$this->links['self'] = $link;
}

/**
* adds an included resource
* this will end up in response.included[]
*
* prefer using ->add_relation() instead
*
* a $resource should have its 'id' set
*
* @note this can only be used by resource and collection, not by errors
*
* @param \alsvanzelf\jsonapi\resource $resource
*/
public function add_included_resource(\alsvanzelf\jsonapi\resource $resource) {
if (property_exists($this, 'included_resources') == false) {
throw new \Exception(get_class($this).' can not contain included resources');
}

$resource_array = $resource->get_array();
if (empty($resource_array['data']['id'])) {
return;
}

$resource_array = $resource_array['data'];
unset($resource_array['relationships'], $resource_array['meta']);

$key = $resource_array['type'].'/'.$resource_array['id'];

$this->included_data[$key] = $resource_array;

// make a backup of the actual resource, to pass on to a collection
$this->included_resources[$key] = $resource;
}

/**
* fills the included resources
* this will end up in response.included[]
*
* prefer using ->fill_relations() instead
*
* @param array $resources of \alsvanzelf\jsonapi\resource objects
* @return void
*/
public function fill_included_resources($resources) {
foreach ($resources as $resource) {
$this->add_included_resource($resource);
}
}

/**
* adds some meta data
* this will end up in response.meta.{$key}
*
* @param string $key
* @param mixed $meta_data objects are converted in arrays, @see ::convert_object_to_array()
* @return void
*/
public function add_meta($key, $meta_data) {
if (is_object($meta_data)) {
$meta_data = self::convert_object_to_array($meta_data);
}

$this->meta_data[$key] = $meta_data;
}

/**
* fills the meta data
* this will end up in response.meta
*
* @param array $meta_data
* @return void
*/
public function fill_meta($meta_data) {
foreach ($meta_data as $key => $single_meta_data) {
$this->add_meta($key, $single_meta_data);
}
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
* - included although possible, you should set those via the resource
*/

class collection extends base {
class collection extends response {

/**
* internal data containers
Expand Down
6 changes: 4 additions & 2 deletions src/error.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
* it is used, and can be used, to fill an errors collection
*/

class error {
class error extends base {

/**
* internal data containers
Expand All @@ -34,6 +34,8 @@ class error {
* @param string $about_link optional, @see ->set_about_link()
*/
public function __construct($error_message, $friendly_message=null, $about_link=null) {
parent::__construct();

$this->set_error_message($error_message);

if ($friendly_message) {
Expand Down Expand Up @@ -224,7 +226,7 @@ public function set_identifier($identifier) {
*/
public function add_meta($key, $meta_data) {
if (is_object($meta_data)) {
$meta_data = base::convert_object_to_array($meta_data);
$meta_data = parent::convert_object_to_array($meta_data);
}

$this->meta_data[$key] = $meta_data;
Expand Down
2 changes: 1 addition & 1 deletion src/errors.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
* ```
*/

class errors extends base {
class errors extends response {

/**
* http status messages used for string output
Expand Down
8 changes: 4 additions & 4 deletions src/resource.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
* - included @see ->add_included_resource() or ->fill_included_resources()
*/

class resource extends base {
class resource extends response {

/**
* internal data containers
Expand Down Expand Up @@ -259,13 +259,13 @@ public function fill_links($links) {
/**
* sets the link to the request used to give this response
* this will end up in response.links.self and response.data.links.self
* this overrides the jsonapi\base->set_self_link() which only adds it to response.links.self
* this overrides the jsonapi\response->set_self_link() which only adds it to response.links.self
*
* @see jsonapi\base->set_self_link()
* @see jsonapi\response->set_self_link()
*
* by default this is already set using $_SERVER variables
* use this method to override this default behavior
* @see jsonapi\base::__construct()
* @see jsonapi\response::__construct()
*
* @param string $link
* @return void
Expand Down
Loading