Skip to content
This repository has been archived by the owner on Jan 29, 2020. It is now read-only.

Commit

Permalink
Merge 85ae05b into 12117d8
Browse files Browse the repository at this point in the history
  • Loading branch information
moufmouf committed Jun 24, 2015
2 parents 12117d8 + 85ae05b commit 4e35d57
Show file tree
Hide file tree
Showing 7 changed files with 258 additions and 206 deletions.
55 changes: 38 additions & 17 deletions doc/book/custom-responses.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,41 +23,62 @@ Some standard use cases, however, make this un-wieldy:
Starting with version 1.1, Diactoros offers several custom response types and factories for
simplifying these common tasks.

## String responses
## HTML responses

`Zend\Diactoros\Response\StringResponse` provides factory methods for two standard string response
types: HTML and JSON.
`Zend\Diactoros\Response\HtmlResponse` is a `Zend\Diactoros\Response` extension for producing
HTML responses. The only required argument is the HTML body, which may be provided as either a string or
`Psr\Http\Message\StreamInterface` instance. By default, the status 200 is used, and 'text/html' content-type
is used; you may alter these via the additional optional arguments:

### HTML
```php
class HtmlResponse extends Response
{
public function __construct($body, $status = 200, array $headers = []);
}
```

The `html()` factory will create a response with the provided HTML as a payload, setting the
`Content-Type` header to `text/html` by default:
Typical usage is:

```php
$response = StringResponse::html($htmlContent);
$response = new HtmlResponse('<html><body>Hello world!</body></html>');
```

The factory allows passing two additional arguments: a status code, and an array of headers. These
The constructor allows passing two additional arguments: a status code, and an array of headers. These
allow you to further seed the initial state of the response.

Headers must be in the same format as you would provide to the
[Response constructor][api.md#response-message].

### JSON
The `json()` factory accepts a data structure to convert to JSON, and returns a response with the
JSON content and the `Content-Type` header set to `application/json`:
## JSON responses

`Zend\Diactoros\Response\JsonResponse` is a `Zend\Diactoros\Response` extension for producing
JSON responses. The only required argument is the data that will be serialized as a JSON string.
By default, the status 200 is used, and 'application/json' content-type
is used; you may alter these via the additional optional arguments:

```php
$response = StringResponse::json($data);
class HtmlResponse extends Response
{
public function __construct($data, $status = 200, array $headers = [], $encodingOptions = 15);
}
```

If a null value is provide, an empty JSON object is used for the content. Scalar data is cast to an
array before serialization. If providing an object, we recommend implementing
If providing an object, we recommend implementing
[JsonSerializable](http://php.net/JsonSerializable) to ensure your object is correctly serialized.

Just like the `html()` factory, the `json()` factory allows passing two additional arguments — a
status code, and an array of headers — to allow you to further seed the initial state of the
response.
Typical usage is:

```php
$response = new JsonResponse(array("hello" => "world");
```

The constructor allows passing three additional arguments:

- A status code
- An array of headers. Headers must be in the same format as you would provide to the
[Response constructor][api.md#response-message].
- The JSON encoding options. These options default to JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP
| JSON_HEX_QUOT (RFC4627-compliant JSON, which may also be embedded into HTML)

## Empty Responses

Expand Down
52 changes: 52 additions & 0 deletions src/Response/HtmlResponse.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @see http://github.com/zendframework/zend-diactoros for the canonical source repository
* @copyright Copyright (c) 2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license https://github.com/zendframework/zend-diactoros/blob/master/LICENSE.md New BSD License
*/
namespace Zend\Diactoros\Response;

use InvalidArgumentException;
use Psr\Http\Message\StreamInterface;
use Psr\Http\Message\UriInterface;
use Zend\Diactoros\Response;

/**
* Produce a HTML response.
*/
class HtmlResponse extends Response
{
/**
* Create a HTML response.
*
* Produces a simple response with the string passed in parameter.
* MIME Content-type is text/html
*
* @param string|StreamInterface $body The body of the response.
* @param int $status Integer status code for the response; 200 by default.
* @param array $headers Array of headers to use at initialization.
*/
public function __construct($body, $status = 200, array $headers = [])
{
if (! is_string($body) && ! $body instanceof StreamInterface) {
throw new InvalidArgumentException(sprintf(
'Body provided to %s MUST be a string or Psr\Http\Message\StreamInterface instance; received "%s"',
__CLASS__,
(is_object($body) ? get_class($body) : gettype($body))
));
}

if (!isset($headers['content-type'])) {
$headers['content-type'] = 'text/html';
}

if ($body instanceof StreamInterface) {
parent::__construct($body, $status, $headers);
} else {
parent::__construct('php://temp', $status, $headers);
$this->getBody()->write($body);
}
}
}
53 changes: 53 additions & 0 deletions src/Response/JsonResponse.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @see http://github.com/zendframework/zend-diactoros for the canonical source repository
* @copyright Copyright (c) 2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license https://github.com/zendframework/zend-diactoros/blob/master/LICENSE.md New BSD License
*/
namespace Zend\Diactoros\Response;

use InvalidArgumentException;
use Psr\Http\Message\StreamInterface;
use Psr\Http\Message\UriInterface;
use Zend\Diactoros\Response;

/**
* Produce a Json response.
*/
class JsonResponse extends Response
{
/**
* Create a Json response.
*
* Produces a JSON response, serialized from $data passed in parameter.
* MIME Content-type is application/json
*
* Default JSON encoding is performed with JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT options
* (RFC4627-compliant JSON, which may also be embedded into HTML)
*
* @param mixed $data The response data, to be serialized in JSON.
* @param int $status Integer status code for the response; 200 by default.
* @param array $headers Array of headers to use at initialization.
* @param int $encodingOptions JSON Encoding parameters.
* @throws \Exception
*/
public function __construct($data, $status = 200, array $headers = [], $encodingOptions = 15)
{
// Clear json_last_error()
json_encode(null);
$json = json_encode($data, $encodingOptions);

if (JSON_ERROR_NONE !== json_last_error()) {
throw new \InvalidArgumentException(json_last_error_msg());
}

if (!isset($headers['content-type'])) {
$headers['content-type'] = 'application/json';
}

parent::__construct('php://temp', $status, $headers);
$this->getBody()->write($json);
}
}
94 changes: 0 additions & 94 deletions src/Response/StringResponse.php

This file was deleted.

60 changes: 60 additions & 0 deletions test/Response/HtmlResponseTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @see http://github.com/zendframework/zend-diactoros for the canonical source repository
* @copyright Copyright (c) 2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license https://github.com/zendframework/zend-diactoros/blob/master/LICENSE.md New BSD License
*/

namespace ZendTest\Diactoros\Response;

use PHPUnit_Framework_TestCase as TestCase;
use Zend\Diactoros\Response\HtmlResponse;
use Zend\Diactoros\Response\StringResponse;
use Zend\Diactoros\Stream;

class HtmlResponseTest extends TestCase
{
public function testHtmlConstructor()
{
$body = '<html>Uh oh not found</html>';
$status = 404;
$headers = [
'x-custom' => [ 'foo-bar' ],
];

$response = new HtmlResponse($body, $status, $headers);
$this->assertSame($body, (string) $response->getBody());
$this->assertEquals(404, $response->getStatusCode());
$this->assertEquals(['foo-bar'], $response->getHeader('x-custom'));
$this->assertEquals('text/html', $response->getHeaderLine('content-type'));
}

public function testHtmlConstructorWithStream()
{
$body = '<html>Hello world</html>';
$stream = new Stream("php://memory", "wb+");
$stream->write($body);

$response = new HtmlResponse($stream);
$this->assertSame($body, (string) $response->getBody());
}

public function testContentTypeCanBeOverwritten()
{
$body = '<html>Uh oh not found</html>';

$response = new HtmlResponse($body, 200, ['content-type' => 'foo/html']);
$this->assertSame($body, (string) $response->getBody());
$this->assertEquals('foo/html', $response->getHeaderLine('content-type'));
}

/**
* @expectedException InvalidArgumentException
*/
public function testInvalidContent()
{
new HtmlResponse(new \stdClass());
}
}
55 changes: 55 additions & 0 deletions test/Response/JsonResponseTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @see http://github.com/zendframework/zend-diactoros for the canonical source repository
* @copyright Copyright (c) 2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license https://github.com/zendframework/zend-diactoros/blob/master/LICENSE.md New BSD License
*/

namespace ZendTest\Diactoros\Response;

use PHPUnit_Framework_TestCase as TestCase;
use Zend\Diactoros\Response\JsonResponse;
use Zend\Diactoros\Response\StringResponse;
use ZendTest\Diactoros\TestAsset\JsonSerializableObject;

class JsonResponseTest extends TestCase
{
public function testJsonConstructor()
{
$data = [
'nested' => [
'json' => [
'tree',
],
],
];
$json = '{"nested":{"json":["tree"]}}';

$response = new JsonResponse($data);
$this->assertEquals(200, $response->getStatusCode());
$this->assertEquals('application/json', $response->getHeaderLine('content-type'));
$this->assertSame($json, (string) $response->getBody());
}

public function testContentTypeCanBeOverwritten()
{
$data = [];
$json = '[]';

$response = new JsonResponse($data, 200, ['content-type' => 'foo/json']);
$this->assertSame($json, (string) $response->getBody());
$this->assertEquals('foo/json', $response->getHeaderLine('content-type'));
}

/**
* @expectedException \InvalidArgumentException
*/
public function testJsonErrorHandling()
{
// Serializing something that is not serializable.
$resource = fopen("php://memory", "r");
new JsonResponse($resource);
}
}
Loading

0 comments on commit 4e35d57

Please sign in to comment.