Skip to content

Commit 13bba5f

Browse files
authored
Add PlainTextDataResponseFormatter and FormatDataResponseAsPlainText (#88)
1 parent 94b86d1 commit 13bba5f

6 files changed

+202
-1
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
- Enh #85: Raise minimum PHP version to 8.1 and refactor code (@vjik)
66
- Enh #80: Add support for `psr/http-message` version `^2.0` (@vjik)
77
- Bug #85: Explicitly add transitive dependencies `psr/http-factory` and `psr/http-server-handler` (@vjik)
8+
- New #88: Add `PlainTextDataResponseFormatter` formatter and `FormatDataResponseAsPlainText` middleware (@vjik)
89

910
## 2.0.0 February 15, 2023
1011

README.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ response.
2727
The package could be installed via composer:
2828

2929
```shell
30-
composer require yiisoft/data-response --prefer-dist
30+
composer require yiisoft/data-response
3131
```
3232

3333
## General usage
@@ -85,6 +85,7 @@ The following formatters are available:
8585
- `HtmlDataResponseFormatter`
8686
- `JsonDataResponseFormatter`
8787
- `XmlDataResponseFormatter`
88+
- `PlainTextDataResponseFormatter`
8889

8990
### Middleware
9091

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Yiisoft\DataResponse\Formatter;
6+
7+
use LogicException;
8+
use Psr\Http\Message\ResponseInterface;
9+
use Stringable;
10+
use Yiisoft\DataResponse\DataResponse;
11+
use Yiisoft\DataResponse\DataResponseFormatterInterface;
12+
use Yiisoft\DataResponse\ResponseContentTrait;
13+
14+
/**
15+
* `PlainTextDataResponseFormatter` formats the response data as plain text.
16+
*/
17+
final class PlainTextDataResponseFormatter implements DataResponseFormatterInterface
18+
{
19+
use ResponseContentTrait;
20+
21+
/**
22+
* @var string The Content-Type header for the response.
23+
*/
24+
private string $contentType = 'text/plain';
25+
26+
/**
27+
* @var string The encoding for the Content-Type header.
28+
*/
29+
private string $encoding = 'UTF-8';
30+
31+
/**
32+
* @inheritDoc
33+
*/
34+
public function format(DataResponse $dataResponse): ResponseInterface
35+
{
36+
$data = $dataResponse->getData();
37+
38+
if (!is_scalar($data) && $data !== null && !$data instanceof Stringable) {
39+
throw new LogicException(sprintf(
40+
'Data must be either a scalar value, null, or a stringable object. %s given.',
41+
get_debug_type($data),
42+
));
43+
}
44+
45+
return $this->addToResponse($dataResponse->getResponse(), empty($data) ? null : (string) $data);
46+
}
47+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Yiisoft\DataResponse\Middleware;
6+
7+
use Yiisoft\DataResponse\Formatter\PlainTextDataResponseFormatter;
8+
9+
/**
10+
* `FormatDataResponseAsPlainText` adds a plain text formatter {@see PlainTextDataResponseFormatter} instance to the
11+
* instance of the data response {@see DataResponse}, if the formatter was not added earlier.
12+
*/
13+
final class FormatDataResponseAsPlainText extends FormatDataResponse
14+
{
15+
public function __construct(PlainTextDataResponseFormatter $responseFormatter)
16+
{
17+
parent::__construct($responseFormatter);
18+
}
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Yiisoft\DataResponse\Tests\Formatter;
6+
7+
use LogicException;
8+
use Yiisoft\DataResponse\Formatter\PlainTextDataResponseFormatter;
9+
use Yiisoft\DataResponse\Tests\TestCase;
10+
11+
final class PlainTextDataResponseFormatterTest extends TestCase
12+
{
13+
public function testCorrectFormat(): void
14+
{
15+
$dataResponse = $this->createDataResponse('test');
16+
$result = (new PlainTextDataResponseFormatter())->format($dataResponse);
17+
$result->getBody()->rewind();
18+
19+
$this->assertSame(
20+
'test',
21+
$result->getBody()->getContents(),
22+
);
23+
$this->assertSame(['text/plain; charset=UTF-8'], $result->getHeader('Content-Type'));
24+
}
25+
26+
public function testWithEncoding(): void
27+
{
28+
$dataResponse = $this->createDataResponse('test');
29+
$result = (new PlainTextDataResponseFormatter())
30+
->withEncoding('ISO-8859-1')
31+
->format($dataResponse);
32+
$result->getBody()->rewind();
33+
34+
$this->assertSame(
35+
'test',
36+
$result->getBody()->getContents(),
37+
);
38+
$this->assertSame(['text/plain; charset=ISO-8859-1'], $result->getHeader('Content-Type'));
39+
}
40+
41+
public function testWithContentType(): void
42+
{
43+
$dataResponse = $this->createDataResponse('test');
44+
$result = (new PlainTextDataResponseFormatter())
45+
->withContentType('text/html')
46+
->format($dataResponse);
47+
$result->getBody()->rewind();
48+
49+
$this->assertSame(
50+
'test',
51+
$result->getBody()->getContents(),
52+
);
53+
$this->assertSame('text/html; charset=UTF-8', $result->getHeaderLine('Content-Type'));
54+
}
55+
56+
public function testWithIncorrectType(): void
57+
{
58+
$dataResponse = $this->createDataResponse(['test']);
59+
$formatter = new PlainTextDataResponseFormatter();
60+
61+
$this->expectException(LogicException::class);
62+
$this->expectExceptionMessage('Data must be either a scalar value, null, or a stringable object. array given.');
63+
$formatter->format($dataResponse);
64+
}
65+
66+
public function testDataWithNull(): void
67+
{
68+
$dataResponse = $this->createDataResponse(null);
69+
$result = (new PlainTextDataResponseFormatter())->format($dataResponse);
70+
$result->getBody()->rewind();
71+
72+
$this->assertSame(
73+
'',
74+
$result->getBody()->getContents(),
75+
);
76+
$this->assertSame(['text/plain; charset=UTF-8'], $result->getHeader('Content-Type'));
77+
}
78+
79+
public function testDataWithStringableObject(): void
80+
{
81+
$data = new class () {
82+
public function __toString(): string
83+
{
84+
return 'test';
85+
}
86+
};
87+
88+
$dataResponse = $this->createDataResponse($data);
89+
$result = (new PlainTextDataResponseFormatter())->format($dataResponse);
90+
$result->getBody()->rewind();
91+
92+
$this->assertSame(
93+
'test',
94+
$result->getBody()->getContents(),
95+
);
96+
$this->assertSame(['text/plain; charset=UTF-8'], $result->getHeader('Content-Type'));
97+
}
98+
99+
public function testImmutability(): void
100+
{
101+
$formatter = new PlainTextDataResponseFormatter();
102+
$this->assertNotSame($formatter, $formatter->withContentType('text/html'));
103+
$this->assertNotSame($formatter, $formatter->withEncoding('utf-8'));
104+
}
105+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Yiisoft\DataResponse\Tests\Middleware;
6+
7+
use Yiisoft\DataResponse\Formatter\PlainTextDataResponseFormatter;
8+
use Yiisoft\DataResponse\Middleware\FormatDataResponseAsPlainText;
9+
use Yiisoft\DataResponse\Tests\TestCase;
10+
11+
final class FormatDataResponseAsPlainTextTest extends TestCase
12+
{
13+
public function testBase(): void
14+
{
15+
$middleware = new FormatDataResponseAsPlainText(new PlainTextDataResponseFormatter());
16+
$dataResponse = $this->createDataResponse('test');
17+
18+
$response = $middleware->process(
19+
$this->createRequest(),
20+
$this->createRequestHandler($dataResponse)
21+
);
22+
23+
$response->getBody()->rewind();
24+
25+
$this->assertSame('test', $response->getBody()->getContents());
26+
$this->assertSame(['text/plain; charset=UTF-8'], $response->getHeader('Content-Type'));
27+
}
28+
}

0 commit comments

Comments
 (0)