181 lines
3.2 KiB
PHP
181 lines
3.2 KiB
PHP
|
<?php
|
||
|
/**
|
||
|
* Sleepy - a REST framework
|
||
|
*
|
||
|
*
|
||
|
* A PHP Rest Framework valuing convention over configuration,
|
||
|
* but aiming to be as flexible as possible
|
||
|
*
|
||
|
* @author Timothy J. Warren
|
||
|
* @package Sleepy/core
|
||
|
*/
|
||
|
|
||
|
namespace Sleepy\core;
|
||
|
|
||
|
/**
|
||
|
* Default output class
|
||
|
*/
|
||
|
class Output {
|
||
|
|
||
|
/**
|
||
|
* The data to serialize and output
|
||
|
*
|
||
|
* @var mixed
|
||
|
*/
|
||
|
protected $data;
|
||
|
|
||
|
/**
|
||
|
* A list of HTTP headers to send with a response
|
||
|
*
|
||
|
* @var array
|
||
|
*/
|
||
|
protected $headers = [];
|
||
|
|
||
|
/**
|
||
|
* The serialization object for the current data type
|
||
|
*
|
||
|
* @var Sleepy\core\aType
|
||
|
*/
|
||
|
protected $type_wrapper;
|
||
|
|
||
|
/**
|
||
|
* The input object
|
||
|
*
|
||
|
* @var Sleepy\core\Input
|
||
|
*/
|
||
|
protected $input;
|
||
|
|
||
|
// --------------------------------------------------------------------------
|
||
|
// ! Methods
|
||
|
// --------------------------------------------------------------------------
|
||
|
|
||
|
/**
|
||
|
* Create the output object
|
||
|
*
|
||
|
* @param array $config
|
||
|
*/
|
||
|
public function __construct(Input $input)
|
||
|
{
|
||
|
$this->input = $input;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Output the data to the client
|
||
|
*/
|
||
|
public function __destruct()
|
||
|
{
|
||
|
// Output the headers
|
||
|
$this->_output_headers();
|
||
|
|
||
|
// Echo the response
|
||
|
echo $this->type_wrapper;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Add a header to be output
|
||
|
*
|
||
|
* @param mixed $header
|
||
|
* @return void
|
||
|
*/
|
||
|
public function set_header($header)
|
||
|
{
|
||
|
if (is_array($header))
|
||
|
{
|
||
|
array_merge($this->headers, $header);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
$this->headers[] = $header;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Set the data to be output to the endpoint
|
||
|
*
|
||
|
* @param string $type - The datatype to send
|
||
|
* @param mixed $data
|
||
|
* @return void
|
||
|
*/
|
||
|
public function set_data($type = 'json', $data)
|
||
|
{
|
||
|
// Get the appropriate output format for the client
|
||
|
// And set the data
|
||
|
$this->get_accepted_type($type, $data);
|
||
|
}
|
||
|
|
||
|
// --------------------------------------------------------------------------
|
||
|
// ! Private helper methods
|
||
|
// --------------------------------------------------------------------------
|
||
|
|
||
|
/**
|
||
|
* Get the type more accepted for output
|
||
|
*
|
||
|
* @param mixed $types
|
||
|
* @param mixed $data
|
||
|
* @return void
|
||
|
*/
|
||
|
protected function get_accepted_type($types, $data)
|
||
|
{
|
||
|
$types = (array) $types;
|
||
|
$types = array_map('strtoupper', $types);
|
||
|
|
||
|
$headers = $this->input->header_array();
|
||
|
$accept = array_flip($headers['accept']);
|
||
|
|
||
|
$type_map = [];
|
||
|
$accepted = [];
|
||
|
$classes = [];
|
||
|
|
||
|
foreach($types as $t)
|
||
|
{
|
||
|
$type_class = "Sleepy\\Type\\{$t}";
|
||
|
$classes[$type_class] = new $type_class($data);
|
||
|
$mime = $classes[$type_class]->get_mime();
|
||
|
|
||
|
$type_map[$mime] = $type_class;
|
||
|
}
|
||
|
|
||
|
foreach($accept as $type => $q)
|
||
|
{
|
||
|
if (array_key_exists($type, $type_map))
|
||
|
{
|
||
|
$accepted[$q] = $type;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
krsort($accepted);
|
||
|
|
||
|
$class = $type_map[current($accepted)];
|
||
|
$this->type_wrapper = $classes[$class];
|
||
|
|
||
|
// Make sure to set the content-type header
|
||
|
if (empty($this->headers))
|
||
|
{
|
||
|
$mime = $this->type_wrapper->get_mime();
|
||
|
$this->set_header("Content-type: {$mime}");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Set the applicable response headers
|
||
|
*
|
||
|
* @return void
|
||
|
*/
|
||
|
protected function _output_headers()
|
||
|
{
|
||
|
foreach($this->headers as $name => $val)
|
||
|
{
|
||
|
if (is_numeric($name))
|
||
|
{
|
||
|
$output_header = $val;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
$output_header = implode(": ", [$name, $val]);
|
||
|
}
|
||
|
|
||
|
@header($output_header);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
// End of core/Output.php
|