Skip to content

Commit

Permalink
Merge pull request #12 from mpscholten/psr7
Browse files Browse the repository at this point in the history
Added Psr7 integration
  • Loading branch information
mpscholten authored Jul 17, 2016
2 parents 6a43376 + f3ce868 commit 493146e
Show file tree
Hide file tree
Showing 12 changed files with 421 additions and 95 deletions.
53 changes: 51 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,16 @@ Install via composer
composer require mpscholten/request-parser
```

If you're using the `symfony/http-foundation` `Request`, you just need to import a trait into your controller. If you're using some other `Request` abstraction (or maybe just plain old `$_GET` and friends), [check out this example](https://github.com/mpscholten/request-parser/blob/master/examples/not-symfony.php).

The following example asumes you're using the symfony `Request`:
**Integrations:**

- If you're using `symfony/http-foundation`, [click here](#symfony-httpfoundation).
- If you're using a Psr7 `ServerRequestInterface` implementation, [click here](#psr7).
- If you're using some other `Request` abstraction (or maybe just plain old `$_GET` and friends), [check out this example](https://github.com/mpscholten/request-parser/blob/master/examples/not-symfony.php).

#### Symfony HttpFoundation

The following example assumes you're using the symfony `Request`:

```php
class MyController
Expand Down Expand Up @@ -112,6 +119,48 @@ be handled by your application to show an error message.

Take a look at [the examples](https://github.com/mpscholten/request-parser/tree/master/examples).

#### Psr7

The following example assumes you're using the Psr7 `ServerRequestInterface`:

```php
class MyController
{
use \MPScholten\RequestParser\Psr7\ControllerHelperTrait;

public function __construct(ServerRequestInterface $request)
{
$this->initRequestParser($request);
}
}
```

Then you can use the library like this:
```php
class MyController
{
use \MPScholten\RequestParser\Psr7\ControllerHelperTrait;

public function __construct(ServerRequestInterface $request)
{
$this->initRequestParser($request);
}

public function myAction()
{
$someParameter = $this->queryParameter('someParameter')->string()->required();
}
}
```

When doing `GET /MyController/myAction?someParameter=example`, the `$someParameter` variable will contain the string `"example"`.

You might wonder what happens when we leave out the `?someParameter` part, like `GET /MyController/myAction`. In this case the
`$this->queryParameter('someParameter')->string()->required()` will throw a `NotFoundException`. This exception can
be handled by your application to show an error message.

Take a look at [the examples](https://github.com/mpscholten/request-parser/tree/master/examples).

#### Optional Parameters

To make the `someParameter` optional, we can just replace `required()` with `defaultsTo($someDefaultValue)`:
Expand Down
4 changes: 3 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@
"require": {},
"require-dev": {
"phpunit/phpunit": "3.7.*",
"symfony/http-foundation": "3.1.*"
"symfony/http-foundation": "3.1.*",
"symfony/psr-http-message-bridge": "^0.2.0",
"zendframework/zend-diactoros": "^1.3"
},
"autoload": {
"psr-4": {"MPScholten\\RequestParser\\": "src/"}
Expand Down
61 changes: 41 additions & 20 deletions examples/not-symfony.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,45 +12,60 @@

require __DIR__ . '/../vendor/autoload.php';

trait CustomControllerHelperTrait
class CustomRequestParserFactory implements \MPScholten\RequestParser\RequestParserFactory
{
private $queryParser;
private $bodyParser;
/**
* @var array
*/
private $request;
private $exceptionFactory;

public function __construct(array $request, $exceptionFactory)
{
$this->request = $request;
$this->exceptionFactory = $exceptionFactory;
}

protected final function initRequestParser()
public function createQueryParser()
{
$this->queryParser = new MPScholten\RequestParser\RequestParser(
return new MPScholten\RequestParser\RequestParser(
function ($parameterName) {
if (isset($_GET[$parameterName])) {
return $_GET[$parameterName];
if (isset($this->request[$parameterName])) {
return $this->request[$parameterName];
}

return null;
},
null
$this->exceptionFactory
);
$this->bodyParser = new MPScholten\RequestParser\RequestParser(
}

public function createBodyParser()
{
return new MPScholten\RequestParser\RequestParser(
function ($parameterName) {
if (isset($_POST[$parameterName])) {
return $_POST[$parameterName];
if (isset($this->request[$parameterName])) {
return $this->request[$parameterName];
}

return null;
},
null
$this->exceptionFactory
);
}
}

protected function queryParameter($name)
{
return $this->queryParser->get($name);
}
trait CustomControllerHelperTrait
{
use \MPScholten\RequestParser\BaseControllerHelperTrait;

protected function bodyParameter($name)
/**
* Will be called during the `initRequestParser()` call in `MyController`
*/
protected final function createRequestParserFactory($request, $exceptionFactory)
{
return $this->bodyParser->get($name);
return new CustomRequestParserFactory($request, $exceptionFactory);
}

}

class MyController
Expand All @@ -59,7 +74,13 @@ class MyController

public function __construct()
{
$this->initRequestParser();
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
$request = $_GET;
} else {
$request = $_POST;
}

$this->initRequestParser($request);
}

public function hello()
Expand Down
62 changes: 62 additions & 0 deletions examples/psr7.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?php

// This example shows how to use this library with the Psr7 `ServerRequestInterface`
// To try out this example do the following:
// - Install dependencies: `composer install`
// - Start webserver: `cd examples && php -S localhost:8080`
// - Open in browser:
// | http://localhost:8080/psr7.php?action=hello
// | http://localhost:8080/psr7.php?action=hello&name=yourname
// | http://localhost:8080/psr7.php?action=helloWithDefault
// | http://localhost:8080/psr7.php?action=json&payload={%22a%22:1}

require __DIR__ . '/../vendor/autoload.php';

use MPScholten\RequestParser\Psr7\ControllerHelperTrait;
use Psr\Http\Message\ServerRequestInterface;
use Symfony\Bridge\PsrHttpMessage\Factory\DiactorosFactory;
use Symfony\Component\HttpFoundation\Request;

$symfonyRequest = Request::createFromGlobals();
$psr7Factory = new DiactorosFactory();
$request = $psr7Factory->createRequest($symfonyRequest);

class MyController
{
use ControllerHelperTrait;

public function __construct(ServerRequestInterface $request)
{
$this->initRequestParser($request);
}

public function hello()
{
$name = $this->queryParameter('name')->string()->required();

return "Hello $name";
}

public function helloWithDefault()
{
$name = $this->queryParameter('name')->string()->defaultsTo('unknown');

return "Hello $name";
}

public function json()
{
$payload = $this->queryParameter('payload')->json()->required();

return print_r($payload, true);
}
}

$controller = new MyController($request);
$action = $request->getQueryParams()['action'];

try {
echo $controller->$action();
} catch (\MPScholten\RequestParser\NotFoundException $e) {
echo $e->getMessage();
}
50 changes: 50 additions & 0 deletions src/BaseControllerHelperTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php

namespace MPScholten\RequestParser;

trait BaseControllerHelperTrait
{
/**
* @var RequestParser
*/
private $queryParser;

/**
* @var RequestParser
*/
private $bodyParser;

protected final function initRequestParser($request, callable $exceptionFactory = null)
{
/** @var $requestParserFactory RequestParserFactory */
$requestParserFactory = $this->createRequestParserFactory($request, $exceptionFactory);
$this->queryParser = $requestParserFactory->createQueryParser();
$this->bodyParser = $requestParserFactory->createBodyParser();
}

/**
* Use this method to access the query parameters of the request.
*
* $page = $this->queryParameter('page')->int()->defaultsTo(0)
*
* @param string $name
* @return TypeParser
*/
protected function queryParameter($name)
{
return $this->queryParser->get($name);
}

/**
* Use this method to access the body parameters of the request (e.g. $_POST).
*
* $password = $this->bodyParameter('password')->string()->required()
*
* @param string $name
* @return TypeParser
*/
protected function bodyParameter($name)
{
return $this->bodyParser->get($name);
}
}
15 changes: 15 additions & 0 deletions src/Psr7/ControllerHelperTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

namespace MPScholten\RequestParser\Psr7;

use MPScholten\RequestParser\BaseControllerHelperTrait;

trait ControllerHelperTrait
{
use BaseControllerHelperTrait;

protected final function createRequestParserFactory($request, $exceptionFactory)
{
return new Psr7RequestParserFactory($request, $exceptionFactory);
}
}
49 changes: 49 additions & 0 deletions src/Psr7/Psr7RequestParserFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php

namespace MPScholten\RequestParser\Psr7;

use MPScholten\RequestParser\RequestParser;
use MPScholten\RequestParser\RequestParserFactory;
use Psr\Http\Message\ServerRequestInterface;

class Psr7RequestParserFactory implements RequestParserFactory
{
private $request;
private $exceptionFactory;

public function __construct(ServerRequestInterface $request, $exceptionFactory = null)
{
$this->request = $request;
$this->exceptionFactory = $exceptionFactory;
}

public function createQueryParser()
{
$query = $this->request->getQueryParams();

$readParameter = function ($name) use ($query) {
if (!isset($query[$name])) {
return null;
}

return $query[$name];
};

return new RequestParser($readParameter, $this->exceptionFactory);
}

public function createBodyParser()
{
$body = $this->request->getParsedBody();

$readParameter = function ($name) use ($body) {
if (!isset($body[$name])) {
return null;
}

return $body[$name];
};

return new RequestParser($readParameter, $this->exceptionFactory);
}
}
16 changes: 16 additions & 0 deletions src/RequestParserFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

namespace MPScholten\RequestParser;

interface RequestParserFactory
{
/**
* @return RequestParser
*/
public function createQueryParser();

/**
* @return RequestParser
*/
public function createBodyParser();
}
Loading

0 comments on commit 493146e

Please sign in to comment.