This repository has been archived on 2018-10-11. You can view files and clone it, but cannot push or open issues or pull requests.
sleepy/Sleepy/Core/Output.php
2014-05-07 14:05:13 -04:00

181 lines
3.2 KiB
PHP
Executable File

<?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