Development

- Fixed updatae causing middlewares to sometimes load on wrong routes.
- Converted project to PSR/2.
- Updated InputCollection class and added get method for easy access to values.
- Complete refactor of RouterBase.
- Added findRoute method to RouterBase.
- It's now possible to change parameter modifiers and symbol by overwriting properties on RouterBase.
- Added RouterUrlTest unit-test for testing route-urls.
- Added IRestController that can be easily implemented in custom ResourceController-classes.
- It's now possible to use "-" instead of "_" when using getHeader method in Request class.
- Added PHPDocs.
- Fixed "/" route sometimes returning "//" as url.
- Optimisations and bugfixes.
This commit is contained in:
Simon Sessingø
2016-11-19 02:48:19 +01:00
parent a4447313f6
commit ed1ac74e7a
41 changed files with 2813 additions and 2318 deletions
+160 -162
View File
@@ -3,211 +3,209 @@ namespace Pecee\Http\Input;
use Pecee\Http\Request;
class Input {
class Input
{
/**
* @var \Pecee\Http\Input\InputCollection
*/
public $get;
/**
* @var \Pecee\Http\Input\InputCollection
*/
public $get;
/**
* @var \Pecee\Http\Input\InputCollection
*/
public $post;
/**
* @var \Pecee\Http\Input\InputCollection
*/
public $post;
/**
* @var \Pecee\Http\Input\InputCollection
*/
public $file;
/**
* @var \Pecee\Http\Input\InputCollection
*/
public $file;
/**
* @var Request
*/
protected $request;
/**
* @var Request
*/
protected $request;
public function __construct(Request $request)
{
$this->request = $request;
$this->setGet();
$this->setPost();
$this->setFile();
}
public function __construct(Request $request) {
$this->request = $request;
$this->setGet();
$this->setPost();
$this->setFile();
}
/**
* Get all get/post items
* @param array|null $filter Only take items in filter
* @return array
*/
public function all(array $filter = null)
{
$output = $_POST;
/**
* Get all get/post items
* @param array|null $filter Only take items in filter
* @return array
*/
public function all(array $filter = null) {
if ($this->request->getMethod() === 'post') {
$output = $_POST;
$contents = file_get_contents('php://input');
if($this->request->getMethod() === 'post') {
if (stripos(trim($contents), '{') === 0) {
$output = json_decode($contents, true);
if ($output === false) {
$output = array();
}
}
}
$contents = file_get_contents('php://input');
$output = array_merge($_GET, $output);
if (stripos(trim($contents), '{') === 0) {
$output = json_decode($contents, true);
if($output === false) {
$output = array();
}
}
}
if ($filter !== null) {
$output = array_filter($output, function ($key) use ($filter) {
if (in_array($key, $filter)) {
return true;
}
$output = array_merge($_GET, $output);
return false;
}, ARRAY_FILTER_USE_KEY);
}
if($filter !== null) {
$output = array_filter($output, function ($key) use ($filter) {
if (in_array($key, $filter)) {
return true;
}
return $output;
}
return false;
}, ARRAY_FILTER_USE_KEY);
}
public function getObject($index, $default = null)
{
$key = (strpos($index, '[') > -1) ? substr($index, strpos($index, '[') + 1, strpos($index, ']') - strlen($index)) : null;
$index = (strpos($index, '[') > -1) ? substr($index, 0, strpos($index, '[')) : $index;
return $output;
}
$element = $this->get->findFirst($index);
public function getObject($index, $default = null) {
$key = (strpos($index, '[') > -1) ? substr($index, strpos($index, '[')+1, strpos($index, ']') - strlen($index)) : null;
$index = (strpos($index, '[') > -1) ? substr($index, 0, strpos($index, '[')) : $index;
if ($element !== null) {
return ($key !== null) ? $element[$key] : $element;
}
$element = $this->get->findFirst($index);
if ($this->request->getMethod() !== 'get') {
if($element !== null) {
return ($key !== null) ? $element[$key] : $element;
}
$element = $this->post->findFirst($index);
if ($element !== null) {
return ($key !== null) ? $element[$key] : $element;
}
if($this->request->getMethod() !== 'get') {
$element = $this->file->findFirst($index);
if ($element !== null) {
return ($key !== null) ? $element[$key] : $element;
}
}
$element = $this->post->findFirst($index);
return $default;
}
if ($element !== null) {
return ($key !== null) ? $element[$key] : $element;
}
/**
* Get input element value matching index
* @param string $index
* @param string|null $default
* @return string|null
*/
public function get($index, $default = null)
{
$item = $this->getObject($index);
$element = $this->file->findFirst($index);
if ($element !== null) {
return ($key !== null) ? $element[$key] : $element;
}
}
if ($item !== null) {
return $default;
}
if ($item instanceof InputCollection || $item instanceof InputFile) {
return $item;
}
/**
* Get input element value matching index
* @param string $index
* @param string|null $default
* @return string|null
*/
public function get($index, $default = null) {
return (trim($item->getValue()) === '') ? $default : $item->getValue();
}
$item = $this->getObject($index);
return $default;
}
if($item !== null) {
public function exists($index)
{
return ($this->getObject($index) !== null);
}
if($item instanceof InputCollection || $item instanceof InputFile) {
return $item;
}
public function setGet()
{
$this->get = new InputCollection();
return (trim($item->getValue()) === '') ? $default : $item->getValue();
}
if (count($_GET) > 0) {
foreach ($_GET as $key => $get) {
if (is_array($get) === false) {
$this->get->{$key} = new InputItem($key, $get);
continue;
}
return $default;
}
$output = new InputCollection();
public function exists($index) {
return ($this->getObject($index) !== null);
}
foreach ($get as $k => $g) {
$output->{$k} = new InputItem($k, $g);
}
public function setGet() {
$this->get = new InputCollection();
$this->get->{$key} = $output;
}
}
}
if(count($_GET)) {
foreach($_GET as $key => $get) {
if(!is_array($get)) {
$this->get->{$key} = new InputItem($key, $get);
continue;
}
public function setPost()
{
$this->post = new InputCollection();
$output = new InputCollection();
$postVars = $_POST;
foreach($get as $k => $g) {
$output->{$k} = new InputItem($k, $g);
}
if (in_array($this->request->getMethod(), ['put', 'patch', 'delete']) === true) {
parse_str(file_get_contents('php://input'), $postVars);
}
$this->get->{$key} = $output;
}
}
}
if (count($postVars) > 0) {
public function setPost() {
$this->post = new InputCollection();
foreach ($postVars as $key => $post) {
if (is_array($post) === false) {
$this->post->{strtolower($key)} = new InputItem($key, $post);
continue;
}
$postVars = $_POST;
$output = new InputCollection();
if(in_array($this->request->getMethod(), ['put', 'patch', 'delete'])) {
parse_str(file_get_contents('php://input'), $postVars);
}
foreach ($post as $k => $p) {
$output->{$k} = new InputItem($k, $p);
}
if(count($postVars)) {
$this->post->{strtolower($key)} = $output;
}
}
}
foreach($postVars as $key => $post) {
if(!is_array($post)) {
$this->post->{strtolower($key)} = new InputItem($key, $post);
continue;
}
public function setFile()
{
$this->file = new InputCollection();
$output = new InputCollection();
if (count($_FILES) > 0) {
foreach ($_FILES as $key => $values) {
foreach($post as $k => $p) {
$output->{$k} = new InputItem($k, $p);
}
// Handle array input
if (is_array($values['name']) === false && trim($values['error']) !== '4') {
$values['index'] = $key;
$this->file->{strtolower($key)} = InputFile::createFromArray($values);
continue;
}
$this->post->{strtolower($key)} = $output;
}
}
}
$output = new InputCollection();
public function setFile() {
$this->file = new InputCollection();
foreach ($values['name'] as $k => $val) {
if (trim($val['error'][$k]) !== '4') {
$output->{$k} = InputFile::createFromArray([
'index' => $k,
'error' => $val['error'][$k],
'tmp_name' => $val['tmp_name'][$k],
'type' => $val['type'][$k],
'size' => $val['size'][$k],
'name' => $val['name'][$k]
]);
}
}
if(count($_FILES)) {
foreach($_FILES as $key => $value) {
// Multiple files
if(!is_array($value['name'])) {
// Strip empty values
if($value['error'] != '4') {
$file = new InputFile($key);
$file->setName($value['name']);
$file->setSize($value['size']);
$file->setType($value['type']);
$file->setTmpName($value['tmp_name']);
$file->setError($value['error']);
$this->file->{strtolower($key)} = $file;
}
continue;
}
$output = new InputCollection();
foreach($value['name'] as $k=>$val) {
// Strip empty values
if($value['error'][$k] != '4') {
$file = new InputFile($k);
$file->setName($value['name'][$k]);
$file->setSize($value['size'][$k]);
$file->setType($value['type'][$k]);
$file->setTmpName($value['tmp_name'][$k]);
$file->setError($value['error'][$k]);
$output->{$k} = $file;
}
}
$this->file->{strtolower($key)} = $output;
}
}
}
$this->file->{strtolower($key)} = $output;
}
}
}
}
+76 -67
View File
@@ -1,85 +1,94 @@
<?php
namespace Pecee\Http\Input;
class InputCollection implements \IteratorAggregate {
class InputCollection implements \IteratorAggregate
{
protected $data = array();
protected $data = array();
/**
* Search for input element matching index.
*
* @param string $index
* @param string|null $default
* @return InputItem
*/
public function findFirst($index, $default = null)
{
if (count($this->data) > 0) {
/**
* Search for input element matching index.
* Useful for searching for finding items where $index doesn't contain form name.
*
* @param string $index
* @param string|null $defaultValue
* @return mixed
*/
public function findFirst($index, $defaultValue = null) {
if(count($this->data)) {
if (isset($this->data[$index])) {
return $this->data[$index];
}
if(isset($this->data[$index])) {
return $this->data[$index];
}
foreach ($this->data as $key => $input) {
if (strtolower($index) === strtolower($key)) {
return $input;
}
}
}
foreach($this->data as $key => $value) {
if(strtolower($index) === strtolower($key)) {
return $value;
}
}
}
return $default;
}
return $defaultValue;
}
/**
* Get input element value matching index
*
* @param string $index
* @param string|null $default
* @return string|null
*/
public function get($index, $default = null)
{
$input = $this->findFirst($index);
public function getValue($index, $defaultValue = null) {
if(count($this->data)) {
if($input !== null) {
if(trim($input->getValue()) === '') {
return $default;
}
if(isset($this->data[$index])) {
return $this->data[$index]->getValue();
}
return $input;
}
foreach($this->data as $key => $value) {
if(strtolower($index) === strtolower($key)) {
return $value->getValue();
}
}
}
return $default;
}
return $defaultValue;
}
/**
* @param string $index
* @throws \InvalidArgumentException
* @return InputItem
*/
public function __get($index)
{
$item = $this->findFirst($index);
// Ensure that item are always available
if ($item === null) {
$this->data[$index] = new InputItem($index, null);
return $this->data[$index];
}
/**
* @param $index
* @throws \InvalidArgumentException
* @return InputItem
*/
public function __get($index) {
$item = $this->findFirst($index);
// Ensure that item are always available
if($item === null) {
$this->data[$index] = new InputItem($index, null);
return $this->data[$index];
}
return $item;
}
return $item;
}
public function __set($index, $value)
{
$this->data[$index] = $value;
}
public function __set($index, $value) {
$this->data[$index] = $value;
}
public function getData()
{
return $this->data;
}
public function getData() {
return $this->data;
}
/**
* Retrieve an external iterator
* @link http://php.net/manual/en/iteratoraggregate.getiterator.php
* @return \Traversable An instance of an object implementing <b>Iterator</b> or
* <b>Traversable</b>
* @since 5.0.0
*/
public function getIterator() {
return new \ArrayIterator($this->data);
}
/**
* Retrieve an external iterator
* @link http://php.net/manual/en/iteratoraggregate.getiterator.php
* @return \Traversable An instance of an object implementing <b>Iterator</b> or
* <b>Traversable</b>
* @since 5.0.0
*/
public function getIterator()
{
return new \ArrayIterator($this->data);
}
}
+68 -27
View File
@@ -1,68 +1,109 @@
<?php
namespace Pecee\Http\Input;
class InputFile extends InputItem {
protected $name;
protected $size;
protected $type;
protected $error;
protected $tmpName;
class InputFile extends InputItem
{
public $size;
public $type;
public $error;
public $tmpName;
/**
* @return string
*/
public function getSize() {
public function getSize()
{
return $this->size;
}
/**
* @return string
*/
public function getType() {
public function getType()
{
return $this->type;
}
/**
* @return string
*/
public function getError() {
public function getError()
{
return $this->error;
}
public function getMime()
{
return $this->getType();
}
/**
* @return string
*/
public function getTmpName() {
public function getTmpName()
{
return $this->tmpName;
}
public function getExtension() {
public function getExtension()
{
return pathinfo($this->getName(), PATHINFO_EXTENSION);
}
}
public function move($destination) {
public function move($destination)
{
return move_uploaded_file($this->tmpName, $destination);
}
public function getContents() {
public function getContents()
{
return file_get_contents($this->tmpName);
}
public function setTmpName($name) {
$this->tmpName = $name;
}
public function setTmpName($name)
{
$this->tmpName = $name;
}
public function setSize($size) {
$this->size = $size;
}
public function setSize($size)
{
$this->size = $size;
}
public function setType($type) {
$this->type = $type;
}
public function setType($type)
{
$this->type = $type;
}
public function setError($error) {
$this->error = $error;
}
public function setError($error)
{
$this->error = $error;
}
/**
* Create from array
* @param array $values
* @return static
*/
public static function createFromArray(array $values)
{
if(!isset($values['index'])) {
throw new \InvalidArgumentException('Index key is required');
}
$input = new static($values['index']);
$input->setTmpName((isset($values['error']) ? $values['error'] : null));
$input->setName((isset($values['name']) ? $values['name'] : null));
$input->setSize((isset($values['size']) ? $values['size'] : null));
$input->setType((isset($values['type']) ? $values['type'] : null));
$input->setError((isset($values['tmp_name']) ? $values['tmp_name'] : null));
return $input;
}
public function __toString()
{
return (string)$this->tmpName;
}
}
+57 -50
View File
@@ -1,63 +1,70 @@
<?php
namespace Pecee\Http\Input;
class InputItem {
class InputItem
{
public $index;
public $name;
public $value;
protected $index;
protected $name;
protected $value;
public function __construct($index, $value = null)
{
$this->index = $index;
$this->value = $value;
public function __construct($index, $value = null) {
$this->index = $index;
$this->value = $value;
// Make the name human friendly, by replace _ with space
$this->name = ucfirst(str_replace('_', ' ', $this->index));
}
// Make the name human friendly, by replace _ with space
$this->name = ucfirst(str_replace('_', ' ', $this->index));
}
/**
* @return array
*/
public function getName()
{
return $this->name;
}
/**
* @return array
*/
public function getName() {
return $this->name;
}
/**
* @return array
*/
public function getValue()
{
return $this->value;
}
/**
* @return array
*/
public function getValue() {
return $this->value;
}
/**
* @return string
*/
public function getIndex()
{
return $this->index;
}
/**
* @return string
*/
public function getIndex() {
return $this->index;
}
/**
* Set input name
* @param string $name
* @return static $this
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Set input name
* @param string $name
* @return static $this
*/
public function setName($name) {
$this->name = $name;
return $this;
}
/**
* Set input value
* @param string $value
* @return static $this
*/
public function setValue($value)
{
$this->value = $value;
return $this;
}
/**
* Set input value
* @param string $value
* @return static $this
*/
public function setValue($value) {
$this->value = $value;
return $this;
}
public function __toString() {
return (string)$this->getValue();
}
public function __toString()
{
return (string)$this->value;
}
}