Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve customizing/extending requests #63

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
8 changes: 7 additions & 1 deletion examples/request_superglobals.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@

// useful for determining how to process the request (list/get/create/update)
var_dump($requestParser->hasIncludePaths());
var_dump($requestParser->hasAnySparseFieldset());
var_dump($requestParser->hasSparseFieldset('user'));
var_dump($requestParser->hasSortFields());
var_dump($requestParser->hasPagination());
Expand All @@ -84,5 +85,10 @@
var_dump($requestParser->getRelationship('ship'));
var_dump($requestParser->getMeta('lock'));

// get the full document for custom processing
// useful for determining how to process the request (list/get/create/update)
var_dump($requestParser->hasQueryParameters());
var_dump($requestParser->hasDocument());

// get the full query parameters or document for custom processing
var_dump($requestParser->getQueryParameters());
var_dump($requestParser->getDocument());
63 changes: 58 additions & 5 deletions src/helpers/RequestParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ class RequestParser {
'useAnnotatedSortFields' => true,
];
/** @var string */
private $selfLink = '';
protected $selfLink = '';
/** @var array */
private $queryParameters = [];
protected $queryParameters = [];
/** @var array */
private $document = [];
protected $document = [];

/**
* @param string $selfLink the uri used to make this request {@see getSelfLink()}
Expand All @@ -47,8 +47,33 @@ public function __construct($selfLink='', array $queryParameters=[], array $docu
*/
public static function fromSuperglobals() {
$selfLink = '';
if (isset($_SERVER['REQUEST_SCHEME']) && isset($_SERVER['HTTP_HOST']) && isset($_SERVER['REQUEST_URI'])) {
$selfLink = $_SERVER['REQUEST_SCHEME'].'://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];

if (isset($_SERVER['HTTP_X_FORWARDED_PROTO'])) {
$selfLink .= $_SERVER['HTTP_X_FORWARDED_PROTO'].'://';
}
elseif (isset($_SERVER['REQUEST_SCHEME'])) {
$selfLink .= $_SERVER['REQUEST_SCHEME'].'://';
}
else {
$selfLink .= 'http://';
}

if (isset($_SERVER['HTTP_HOST'])) {
$selfLink .= $_SERVER['HTTP_HOST'];
}
elseif (isset($_SERVER['SCRIPT_URI'])) {
$startOfDomain = strpos($_SERVER['SCRIPT_URI'], '://') + strlen('://');
$endOfDomain = strpos($_SERVER['SCRIPT_URI'], '/', $startOfDomain);
$lengthOfDomain = ($endOfDomain - $startOfDomain);
$selfLink .= substr($_SERVER['SCRIPT_URI'], $startOfDomain, $lengthOfDomain);
}

if (isset($_SERVER['REQUEST_URI'])) {
$selfLink .= $_SERVER['REQUEST_URI'];
}
elseif (isset($_SERVER['PATH_INFO']) && isset($_SERVER['QUERY_STRING'])) {
$selfLink .= $_SERVER['PATH_INFO'];
$selfLink .= ($_SERVER['QUERY_STRING'] !== '') ? '?'.$_SERVER['QUERY_STRING'] : '';
}

$queryParameters = $_GET;
Expand Down Expand Up @@ -150,6 +175,13 @@ public function getIncludePaths(array $options=[]) {
return $restructured;
}

/**
* @return boolean
*/
public function hasAnySparseFieldset() {
return (isset($this->queryParameters['fields']));
}

/**
* @param string $type
* @return boolean
Expand Down Expand Up @@ -333,6 +365,27 @@ public function getMeta($metaKey) {
return $this->document['meta'][$metaKey];
}

/**
* @return boolean
*/
public function hasQueryParameters() {
return ($this->queryParameters !== []);
}

/**
* @return array
*/
public function getQueryParameters() {
return $this->queryParameters;
}

/**
* @return boolean
*/
public function hasDocument() {
return ($this->document !== []);
}

/**
* @return array
*/
Expand Down
106 changes: 99 additions & 7 deletions tests/helpers/RequestParserTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ public function testFromSuperglobals_HappyPath() {
$this->assertSame('https://example.org/user/42?'.http_build_query($_GET), $requestParser->getSelfLink());

$this->assertTrue($requestParser->hasIncludePaths());
$this->assertTrue($requestParser->hasAnySparseFieldset());
$this->assertTrue($requestParser->hasSparseFieldset('user'));
$this->assertTrue($requestParser->hasSortFields());
$this->assertTrue($requestParser->hasPagination());
Expand All @@ -73,6 +74,10 @@ public function testFromSuperglobals_HappyPath() {
$this->assertSame(['data' => ['type' => 'ship', 'id' => '42']], $requestParser->getRelationship('ship'));
$this->assertSame(true, $requestParser->getMeta('lock'));

$this->assertTrue($requestParser->hasQueryParameters());
$this->assertTrue($requestParser->hasDocument());

$this->assertSame($_GET, $requestParser->getQueryParameters());
$this->assertSame($_POST, $requestParser->getDocument());
}

Expand All @@ -90,10 +95,33 @@ public function testFromSuperglobals_WithPhpInputStream() {
$this->assertSame([], $requestParser->getDocument());
}

public function testFromSuperglobals_WithForwarding() {
unset($_SERVER['REQUEST_SCHEME']);
unset($_SERVER['HTTP_HOST']);
unset($_SERVER['REQUEST_URI']);
unset($_SERVER['CONTENT_TYPE']);

$_SERVER['HTTP_X_FORWARDED_PROTO'] = 'https';
$_SERVER['SCRIPT_URI'] = 'http://example.org/users';
$_SERVER['PATH_INFO'] = '/users';
$_SERVER['QUERY_STRING'] = 'include=foo';

$_GET = [];
$_POST = [];

$requestParser = RequestParser::fromSuperglobals();

$this->assertSame('https://example.org/users?include=foo', $requestParser->getSelfLink());
}

public function testFromSuperglobals_WithoutServerContext() {
unset($_SERVER['HTTP_X_FORWARDED_PROTO']);
unset($_SERVER['REQUEST_SCHEME']);
unset($_SERVER['HTTP_HOST']);
unset($_SERVER['SCRIPT_URI']);
unset($_SERVER['REQUEST_URI']);
unset($_SERVER['PATH_INFO']);
unset($_SERVER['QUERY_STRING']);
unset($_SERVER['CONTENT_TYPE']);

$_GET = [];
Expand Down Expand Up @@ -145,6 +173,7 @@ public function testFromPsrRequest_WithRequestInterface() {
$this->assertSame('https://example.org/user/42?'.http_build_query($queryParameters), $requestParser->getSelfLink());

$this->assertTrue($requestParser->hasIncludePaths());
$this->assertTrue($requestParser->hasAnySparseFieldset());
$this->assertTrue($requestParser->hasSparseFieldset('user'));
$this->assertTrue($requestParser->hasSortFields());
$this->assertTrue($requestParser->hasPagination());
Expand All @@ -164,6 +193,10 @@ public function testFromPsrRequest_WithRequestInterface() {
$this->assertSame(['data' => ['type' => 'ship', 'id' => '42']], $requestParser->getRelationship('ship'));
$this->assertSame(true, $requestParser->getMeta('lock'));

$this->assertTrue($requestParser->hasQueryParameters());
$this->assertTrue($requestParser->hasDocument());

$this->assertSame($queryParameters, $requestParser->getQueryParameters());
$this->assertSame($document, $requestParser->getDocument());
}

Expand Down Expand Up @@ -253,6 +286,21 @@ public function testGetIncludePaths_Raw() {
$this->assertSame(['foo', 'bar', 'baz.baf'], $requestParser->getIncludePaths($options));
}

public function testHasAnySparseFieldset() {
$queryParameters = [];
$requestParser = new RequestParser($selfLink='', $queryParameters);
$this->assertFalse($requestParser->hasAnySparseFieldset());

// not allowed, but possible
$queryParameters = ['fields' => ''];
$requestParser = new RequestParser($selfLink='', $queryParameters);
$this->assertTrue($requestParser->hasAnySparseFieldset());

$queryParameters = ['fields' => ['foo' => 'bar', 'baf' => 'baz']];
$requestParser = new RequestParser($selfLink='', $queryParameters);
$this->assertTrue($requestParser->hasAnySparseFieldset());
}

public function testHasSparseFieldset() {
$requestParser = new RequestParser();
$this->assertFalse($requestParser->hasSparseFieldset('foo'));
Expand Down Expand Up @@ -374,7 +422,7 @@ public function testHasAttribute() {
],
];

$requestParser = new RequestParser($selfLink='', $quaryParameters=[], $document);
$requestParser = new RequestParser($selfLink='', $queryParameters=[], $document);
$this->assertTrue($requestParser->hasAttribute('foo'));
$this->assertFalse($requestParser->hasAttribute('bar'));
}
Expand All @@ -388,7 +436,7 @@ public function testGetAttribute() {
],
];

$requestParser = new RequestParser($selfLink='', $quaryParameters=[], $document);
$requestParser = new RequestParser($selfLink='', $queryParameters=[], $document);
$this->assertSame('bar', $requestParser->getAttribute('foo'));
}

Expand All @@ -410,7 +458,7 @@ public function testHasRelationship() {
],
];

$requestParser = new RequestParser($selfLink='', $quaryParameters=[], $document);
$requestParser = new RequestParser($selfLink='', $queryParameters=[], $document);
$this->assertTrue($requestParser->hasRelationship('foo'));
$this->assertFalse($requestParser->hasRelationship('bar'));
}
Expand All @@ -429,7 +477,7 @@ public function testGetRelationship() {
],
];

$requestParser = new RequestParser($selfLink='', $quaryParameters=[], $document);
$requestParser = new RequestParser($selfLink='', $queryParameters=[], $document);
$this->assertSame(['data' => ['type' => 'bar', 'id' => '42']], $requestParser->getRelationship('foo'));
}

Expand All @@ -444,7 +492,7 @@ public function testHasMeta() {
],
];

$requestParser = new RequestParser($selfLink='', $quaryParameters=[], $document);
$requestParser = new RequestParser($selfLink='', $queryParameters=[], $document);
$this->assertTrue($requestParser->hasMeta('foo'));
$this->assertFalse($requestParser->hasMeta('bar'));
}
Expand All @@ -456,10 +504,54 @@ public function testGetMeta() {
],
];

$requestParser = new RequestParser($selfLink='', $quaryParameters=[], $document);
$requestParser = new RequestParser($selfLink='', $queryParameters=[], $document);
$this->assertSame('bar', $requestParser->getMeta('foo'));
}

public function testHasQueryParameters() {
$queryParameters = [];
$requestParser = new RequestParser($selfLink='', $queryParameters, $document=[]);
$this->assertFalse($requestParser->hasQueryParameters());

$queryParameters = [
'filter' => '42',
];
$requestParser = new RequestParser($selfLink='', $queryParameters, $document=[]);
$this->assertTrue($requestParser->hasQueryParameters());
}

public function testGetQueryParameters() {
$queryParameters = [
'include' => 'ship,ship.wing',
'fields' => [
'user' => 'name,location',
],
'sort' => 'name,-location',
'page' => [
'number' => '2',
'size' => '10',
],
'filter' => '42',
];

$requestParser = new RequestParser($selfLink='', $queryParameters, $document=[]);
$this->assertSame($queryParameters, $requestParser->getQueryParameters());
}

public function testHasDocument() {
$document = [];
$requestParser = new RequestParser($selfLink='', $queryParameters=[], $document);
$this->assertFalse($requestParser->hasDocument());

$document = [
'meta' => [
'foo' => 'bar',
],
];
$requestParser = new RequestParser($selfLink='', $queryParameters=[], $document);
$this->assertTrue($requestParser->hasDocument());
}

public function testGetDocument() {
$document = [
'data' => [
Expand All @@ -481,7 +573,7 @@ public function testGetDocument() {
'foo' => 'bar',
];

$requestParser = new RequestParser($selfLink='', $quaryParameters=[], $document);
$requestParser = new RequestParser($selfLink='', $queryParameters=[], $document);
$this->assertSame($document, $requestParser->getDocument());
}
}