2014-05-07 14:05:13 -04:00
|
|
|
<?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
|
|
|
|
*/
|
|
|
|
|
2014-05-14 10:32:31 -04:00
|
|
|
namespace Sleepy\Core;
|
2014-05-07 14:05:13 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* 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
|
|
|
|
*
|
2014-05-14 10:32:31 -04:00
|
|
|
* @var Sleepy\Core\aType
|
2014-05-07 14:05:13 -04:00
|
|
|
*/
|
|
|
|
protected $type_wrapper;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The input object
|
|
|
|
*
|
2014-05-14 10:32:31 -04:00
|
|
|
* @var Sleepy\Core\Input
|
2014-05-07 14:05:13 -04:00
|
|
|
*/
|
|
|
|
protected $input;
|
2014-05-14 10:32:31 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Config object
|
|
|
|
*
|
|
|
|
* @var Sleepy\Core\Config;
|
|
|
|
*/
|
|
|
|
protected $config;
|
2014-05-07 14:05:13 -04:00
|
|
|
|
|
|
|
// --------------------------------------------------------------------------
|
|
|
|
// ! Methods
|
|
|
|
// --------------------------------------------------------------------------
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Create the output object
|
|
|
|
*
|
2014-05-14 10:32:31 -04:00
|
|
|
* @param Config $config
|
|
|
|
* @param Input $input
|
2014-05-07 14:05:13 -04:00
|
|
|
*/
|
2014-05-14 10:32:31 -04:00
|
|
|
public function __construct(Config $config, Input $input)
|
2014-05-07 14:05:13 -04:00
|
|
|
{
|
2014-05-14 10:32:31 -04:00
|
|
|
$this->config = $config;
|
2014-05-07 14:05:13 -04:00
|
|
|
$this->input = $input;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Output the data to the client
|
2014-05-14 16:58:34 -04:00
|
|
|
* @codeCoverageIgnore
|
2014-05-07 14:05:13 -04:00
|
|
|
*/
|
|
|
|
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))
|
|
|
|
{
|
2014-05-14 16:58:34 -04:00
|
|
|
foreach($header as $type => $val)
|
|
|
|
{
|
|
|
|
$this->headers[] = (is_numeric($type))
|
|
|
|
? $val
|
|
|
|
: "{$type}: {$val}";
|
|
|
|
}
|
2014-05-07 14:05:13 -04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
$this->headers[] = $header;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set the data to be output to the endpoint
|
|
|
|
*
|
2014-05-14 16:58:34 -04:00
|
|
|
* @param mixed $type - The data format to send
|
2014-05-14 10:32:31 -04:00
|
|
|
* @param mixed $data - The data to send
|
2014-05-07 14:05:13 -04:00
|
|
|
* @return void
|
|
|
|
*/
|
2014-05-14 10:32:31 -04:00
|
|
|
public function set_data($type = 'html', $data = NULL)
|
2014-05-07 14:05:13 -04:00
|
|
|
{
|
2014-05-14 10:32:31 -04:00
|
|
|
if (is_null($data) && ! empty($this->data))
|
|
|
|
{
|
|
|
|
$data = $this->data;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set instance data
|
|
|
|
$this->data = $data;
|
|
|
|
|
2014-05-07 14:05:13 -04:00
|
|
|
// Get the appropriate output format for the client
|
|
|
|
// And set the data
|
2014-05-14 16:58:34 -04:00
|
|
|
return $this->get_accepted_type($type, $this->data);
|
2014-05-07 14:05:13 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------------
|
|
|
|
// ! Private helper methods
|
|
|
|
// --------------------------------------------------------------------------
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the type more accepted for output
|
|
|
|
*
|
|
|
|
* @param mixed $types
|
|
|
|
* @param mixed $data
|
2014-05-14 16:58:34 -04:00
|
|
|
* @return array
|
2014-05-07 14:05:13 -04:00
|
|
|
*/
|
|
|
|
protected function get_accepted_type($types, $data)
|
|
|
|
{
|
2014-05-14 16:58:34 -04:00
|
|
|
// Get the mime - type class mapping to use
|
|
|
|
// for determining which classes need to be loaded
|
2014-05-07 14:05:13 -04:00
|
|
|
$types = (array) $types;
|
|
|
|
$types = array_map('strtoupper', $types);
|
2014-05-14 16:58:34 -04:00
|
|
|
$type_map = $this->config->get('type_class_map');
|
|
|
|
$filtered_type_map = $this->filter_mime_types($type_map, $types);
|
2014-05-07 14:05:13 -04:00
|
|
|
|
2014-05-14 16:58:34 -04:00
|
|
|
// Get the accept headers to filter valid mime types
|
|
|
|
// for the current client
|
2014-05-07 14:05:13 -04:00
|
|
|
$headers = $this->input->header_array();
|
|
|
|
$accept = array_flip($headers['accept']);
|
2014-05-14 16:58:34 -04:00
|
|
|
$valid_mimes = array_keys(array_intersect_key($accept, $filtered_type_map));
|
|
|
|
|
|
|
|
// When you don't have a matching mime, send the default
|
|
|
|
// data type specified for the output in the type_class_map
|
|
|
|
// config file
|
|
|
|
if (empty($valid_mimes))
|
2014-05-07 14:05:13 -04:00
|
|
|
{
|
2014-05-14 16:58:34 -04:00
|
|
|
$valid_mimes[] = $type_map['*/*'];
|
2014-05-07 14:05:13 -04:00
|
|
|
}
|
|
|
|
|
2014-05-14 16:58:34 -04:00
|
|
|
// Map type objects to the appropriate
|
|
|
|
// associated mime types
|
|
|
|
$classes = [];
|
|
|
|
foreach($valid_mimes as $mime)
|
2014-05-14 10:32:31 -04:00
|
|
|
{
|
2014-05-14 16:58:34 -04:00
|
|
|
$t = $type_map[$mime];
|
|
|
|
$type_class = "Sleepy\\Type\\{$t}";
|
|
|
|
$classes[$mime] = $type_class;
|
2014-05-14 10:32:31 -04:00
|
|
|
}
|
2014-05-07 14:05:13 -04:00
|
|
|
|
2014-05-14 10:32:31 -04:00
|
|
|
// Use the first output type to output the data
|
2014-05-14 16:58:34 -04:00
|
|
|
$selected_mime = array_shift($valid_mimes);
|
|
|
|
$class = $classes[$selected_mime];
|
|
|
|
$this->type_wrapper = new $class($data);
|
2014-05-07 14:05:13 -04:00
|
|
|
|
|
|
|
// Make sure to set the content-type header
|
|
|
|
if (empty($this->headers))
|
|
|
|
{
|
|
|
|
$mime = $this->type_wrapper->get_mime();
|
2014-05-14 16:58:34 -04:00
|
|
|
$this->set_header("Content-type: {$mime};charset=utf8");
|
|
|
|
}
|
|
|
|
|
|
|
|
return [$selected_mime => $class];
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Filter the list of mime types by their values
|
|
|
|
*
|
|
|
|
* @param array $mime_list
|
|
|
|
* @param array $type_list
|
|
|
|
* @return array
|
|
|
|
*/
|
|
|
|
protected function filter_mime_types($mime_list, $type_list)
|
|
|
|
{
|
|
|
|
$filtered_list = [];
|
|
|
|
|
|
|
|
foreach($type_list as $class)
|
|
|
|
{
|
|
|
|
foreach($mime_list as $mime => $c)
|
|
|
|
{
|
|
|
|
if (strtoupper($c) === strtoupper($class))
|
|
|
|
{
|
|
|
|
$filtered_list[$mime] = $c;
|
|
|
|
}
|
|
|
|
}
|
2014-05-07 14:05:13 -04:00
|
|
|
}
|
2014-05-14 16:58:34 -04:00
|
|
|
|
|
|
|
return $filtered_list;
|
2014-05-07 14:05:13 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set the applicable response headers
|
|
|
|
*
|
2014-05-14 16:58:34 -04:00
|
|
|
* @codeCoverageIgnore
|
2014-05-07 14:05:13 -04:00
|
|
|
* @return void
|
|
|
|
*/
|
|
|
|
protected function _output_headers()
|
|
|
|
{
|
2014-05-14 16:58:34 -04:00
|
|
|
foreach($this->headers as $header)
|
2014-05-07 14:05:13 -04:00
|
|
|
{
|
2014-05-14 16:58:34 -04:00
|
|
|
@header($header);
|
2014-05-07 14:05:13 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2014-05-14 10:32:31 -04:00
|
|
|
// End of Core/Output.php
|