Skip to content

Commit be04699

Browse files
author
Nil Portugues Caldero
committed
Updated with the final name for the standard: RF7807
1 parent 06c4d8c commit be04699

File tree

6 files changed

+180
-18
lines changed

6 files changed

+180
-18
lines changed

README.md

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,29 @@ PSR7 Response implementation for the [Problem Details for HTTP APIs (RFC7807)](h
1313

1414
To report a single error, all you need to do is pass in the mandatory parameters and you'll be fine.
1515

16-
**Using the constructor**
16+
**Straightforward usage (recommended)**
17+
18+
This is probably the fastest way and it's really convenient as it hides the presenter and creating the instances from you.
1719

1820
```php
19-
<?php
21+
use NilPortugues\Api\Problem\ApiProblemResponse;
22+
23+
$additionalDetails = []; //you may pass additional details too.
24+
25+
ApiProblemResponse::json(404,'User with id 5 not found.', 'Not Found', 'user.not_found', $additionalDetails);
26+
ApiProblemResponse::xml(404,'User with id 5 not found.', 'Not Found', 'user.not_found', $additionalDetails);
27+
28+
ApiProblemResponse::fromExceptionToJson($exception);
29+
ApiProblemResponse::fromExceptionToXml($exception);
30+
```
31+
32+
**Using the constructor and handling the response yourself.**
33+
34+
```php
35+
use NilPortugues\Api\Problem\ApiProblem;
36+
use NilPortugues\Api\Problem\ApiProblemResponse;
37+
use NilPortugues\Api\Problem\Presenter\JsonPresenter;
38+
2039
$apiProblem = new ApiProblem(
2140
404,
2241
'User with id 5 not found.',
@@ -28,10 +47,13 @@ $presenter = new JsonPresenter($apiProblem); //or XmlPresenter
2847
return new ApiProblemResponse($presenter);
2948
```
3049

31-
**Using an Exception**
50+
**Using an Exception and handling the response yourself.**
3251

3352
```php
34-
<?php
53+
use NilPortugues\Api\Problem\ApiProblem;
54+
use NilPortugues\Api\Problem\ApiProblemResponse;
55+
use NilPortugues\Api\Problem\Presenter\JsonPresenter;
56+
3557
try {
3658
//...your code throwing an exception
3759
throw new \Exception('User with id 5 not found.', 404);
@@ -49,7 +71,10 @@ try {
4971
In order to report more than problem, you must use the additional details parameter.
5072

5173
```php
52-
<?php
74+
use NilPortugues\Api\Problem\ApiProblem;
75+
use NilPortugues\Api\Problem\ApiProblemResponse;
76+
use NilPortugues\Api\Problem\Presenter\JsonPresenter;
77+
5378
try {
5479
// some code of yours throws an exception... for instance:
5580
throw new \Exception('User data is not valid.', 500);
@@ -116,7 +141,7 @@ Content-Type: application/problem+xml
116141

117142
```xml
118143
<?xml version="1.0" encoding="UTF-8"?>
119-
<problem xmlns="urn:ietf:rfc:XXXX">
144+
<problem xmlns="urn:ietf:rfc:7807">
120145
<title>Input values do not match the requirements</title>
121146
<status>500</status>
122147
<detail>User data is not valid.</detail>

src/ApiProblem/ApiProblem.php

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
namespace NilPortugues\Api\Problem;
1212

13+
use Exception;
1314
use NilPortugues\Assert\Assert;
1415

1516
/**
@@ -117,14 +118,14 @@ public function __construct($status, $detail, $title = '', $type = '', array $ad
117118
}
118119

119120
/**
120-
* @param \Exception $exception
121-
* @param string $title
122-
* @param string $type
123-
* @param array $additionalDetails
121+
* @param Exception $exception
122+
* @param string $title
123+
* @param string $type
124+
* @param array $additionalDetails
124125
*
125126
* @return ApiProblem
126127
*/
127-
public static function fromException(\Exception $exception, $title = '', $type = '', array $additionalDetails = [])
128+
public static function fromException(Exception $exception, $title = '', $type = '', array $additionalDetails = [])
128129
{
129130
$eCode = $exception->getCode();
130131
$code = (isset($eCode) && is_int($eCode)) ? $eCode : 500;

src/ApiProblem/ApiProblemResponse.php

Lines changed: 65 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@
1010

1111
namespace NilPortugues\Api\Problem;
1212

13+
use Exception;
1314
use GuzzleHttp\Psr7\Response;
15+
use NilPortugues\Api\Problem\Presenter\JsonPresenter;
1416
use NilPortugues\Api\Problem\Presenter\Presenter;
17+
use NilPortugues\Api\Problem\Presenter\XmlPresenter;
1518

16-
/**
17-
* Class ApiProblemResponse.
18-
*/
1919
class ApiProblemResponse extends Response
2020
{
2121
/**
@@ -41,4 +41,66 @@ protected function responseHeader(Presenter $presenter)
4141
{
4242
return ($presenter->format() === 'xml') ? 'application/problem+xml' : 'application/problem+json';
4343
}
44+
45+
/**
46+
* @param $status
47+
* @param $detail
48+
* @param string $title
49+
* @param string $type
50+
* @param array $additionalDetails
51+
*
52+
* @return ApiProblemResponse
53+
*/
54+
public static function json($status, $detail, $title = '', $type = '', array $additionalDetails = [])
55+
{
56+
return new self(new JsonPresenter(new ApiProblem($status, $detail, $title, $type, $additionalDetails)));
57+
}
58+
59+
/**
60+
* @param Exception $exception
61+
* @param string $title
62+
* @param string $type
63+
* @param array $additionalDetails
64+
*
65+
* @return ApiProblemResponse
66+
*/
67+
public static function fromExceptionToJson(
68+
Exception $exception,
69+
$title = '',
70+
$type = '',
71+
array $additionalDetails = []
72+
) {
73+
return new self(new JsonPresenter(ApiProblem::fromException($exception, $title, $type, $additionalDetails)));
74+
}
75+
76+
/**
77+
* @param $status
78+
* @param $detail
79+
* @param string $title
80+
* @param string $type
81+
* @param array $additionalDetails
82+
*
83+
* @return ApiProblemResponse
84+
*/
85+
public static function xml($status, $detail, $title = '', $type = '', array $additionalDetails = [])
86+
{
87+
return new self(new XmlPresenter(new ApiProblem($status, $detail, $title, $type, $additionalDetails)));
88+
}
89+
90+
/**
91+
* @param Exception $exception
92+
* @param string $title
93+
* @param string $type
94+
* @param array $additionalDetails
95+
*
96+
* @return ApiProblemResponse
97+
*/
98+
public static function fromExceptionToXml(
99+
Exception $exception,
100+
$title = '',
101+
$type = '',
102+
array $additionalDetails = []
103+
) {
104+
return new self(new XmlPresenter(ApiProblem::fromException($exception, $title, $type, $additionalDetails)));
105+
}
44106
}

src/ApiProblem/Presenter/XmlPresenter.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public function contents()
3636

3737
return <<<XML
3838
<?xml version="1.0" encoding="UTF-8"?>
39-
<problem xmlns="urn:ietf:rfc:XXXX">
39+
<problem xmlns="urn:ietf:rfc:7807">
4040
$flattenedLines
4141
</problem>
4242
XML;

tests/ApiProblem/ApiProblemResponseTest.php

Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,81 @@ public function testItWillCreateXmlResponse()
3737

3838
$body = <<<XML
3939
<?xml version="1.0" encoding="UTF-8"?>
40-
<problem xmlns="urn:ietf:rfc:XXXX">
40+
<problem xmlns="urn:ietf:rfc:7807">
41+
<title>Not Found</title>
42+
<status>404</status>
43+
<detail>User with id 5 not found.</detail>
44+
<type>http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html</type>
45+
</problem>
46+
XML;
47+
48+
$this->assertEquals($response->getBody()->getContents(), $body);
49+
$this->assertEquals($response->getStatusCode(), 404);
50+
$this->assertEquals($response->getHeaderLine('Content-type'), 'application/problem+xml');
51+
}
52+
53+
public function testToJson()
54+
{
55+
$response = ApiProblemResponse::json(404, 'User with id 5 not found.', 'Not Found');
56+
57+
$body = <<<JSON
58+
{
59+
"title": "Not Found",
60+
"status": 404,
61+
"detail": "User with id 5 not found."
62+
}
63+
JSON;
64+
65+
$this->assertEquals($response->getBody()->getContents(), $body);
66+
$this->assertEquals($response->getStatusCode(), 404);
67+
$this->assertEquals($response->getHeaderLine('Content-type'), 'application/problem+json');
68+
}
69+
70+
public function testToJsonFromException()
71+
{
72+
$exception = new \Exception('User with id 5 not found.', 404);
73+
$response = ApiProblemResponse::fromExceptionToJson($exception);
74+
75+
$body = <<<JSON
76+
{
77+
"title": "Not Found",
78+
"status": 404,
79+
"detail": "User with id 5 not found.",
80+
"type": "http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html"
81+
}
82+
JSON;
83+
84+
$this->assertEquals($response->getBody()->getContents(), $body);
85+
$this->assertEquals($response->getStatusCode(), 404);
86+
$this->assertEquals($response->getHeaderLine('Content-type'), 'application/problem+json');
87+
}
88+
89+
public function testToXml()
90+
{
91+
$response = ApiProblemResponse::xml(404, 'User with id 5 not found.', 'Not Found');
92+
93+
$body = <<<XML
94+
<?xml version="1.0" encoding="UTF-8"?>
95+
<problem xmlns="urn:ietf:rfc:7807">
96+
<title>Not Found</title>
97+
<status>404</status>
98+
<detail>User with id 5 not found.</detail>
99+
</problem>
100+
XML;
101+
102+
$this->assertEquals($response->getBody()->getContents(), $body);
103+
$this->assertEquals($response->getStatusCode(), 404);
104+
$this->assertEquals($response->getHeaderLine('Content-type'), 'application/problem+xml');
105+
}
106+
107+
public function testToXmlFromException()
108+
{
109+
$exception = new \Exception('User with id 5 not found.', 404);
110+
$response = ApiProblemResponse::fromExceptionToXml($exception);
111+
112+
$body = <<<XML
113+
<?xml version="1.0" encoding="UTF-8"?>
114+
<problem xmlns="urn:ietf:rfc:7807">
41115
<title>Not Found</title>
42116
<status>404</status>
43117
<detail>User with id 5 not found.</detail>

tests/ApiProblem/Presenter/XmlPresenterTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public function testItCanWriteXmlFromNestedArray()
3535
{
3636
$expected = <<<JSON
3737
<?xml version="1.0" encoding="UTF-8"?>
38-
<problem xmlns="urn:ietf:rfc:XXXX">
38+
<problem xmlns="urn:ietf:rfc:7807">
3939
<title>Input values do not match the requirements</title>
4040
<status>500</status>
4141
<detail>User data is not valid.</detail>
@@ -56,7 +56,7 @@ public function testItCanCastObjectToString()
5656
{
5757
$expected = <<<JSON
5858
<?xml version="1.0" encoding="UTF-8"?>
59-
<problem xmlns="urn:ietf:rfc:XXXX">
59+
<problem xmlns="urn:ietf:rfc:7807">
6060
<title>Input values do not match the requirements</title>
6161
<status>500</status>
6262
<detail>User data is not valid.</detail>

0 commit comments

Comments
 (0)