Skip to content

Commit 010c4d0

Browse files
authored
Merge pull request #5 from pdsinterop/feature/templating
Add templating
2 parents 622294f + 9ec02b1 commit 010c4d0

File tree

13 files changed

+611
-64
lines changed

13 files changed

+611
-64
lines changed

composer.json

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,16 @@
2121
"ext-json": "*",
2222
"ext-mbstring": "*",
2323
"ext-openssl": "*",
24-
"defuse/php-encryption":"^2.2",
25-
"laminas/laminas-diactoros":" ^2.3",
26-
"laminas/laminas-httphandlerrunner":"^1.2",
27-
"league/container":"^3.3",
28-
"league/flysystem":"^1.0.",
29-
"league/oauth2-server":"^8.0",
30-
"league/route":"^4.5",
31-
"pdsinterop/flysystem-rdf":"^0.1",
32-
"php-http/httplug":"^2.1"
24+
"defuse/php-encryption": "^2.2",
25+
"laminas/laminas-diactoros": " ^2.3",
26+
"laminas/laminas-httphandlerrunner": "^1.2",
27+
"league/container": "^3.3",
28+
"league/flysystem": "^1.0.",
29+
"league/oauth2-server": "^8.0",
30+
"league/route": "^4.5",
31+
"pdsinterop/flysystem-rdf": "^0.1",
32+
"php-http/httplug": "^2.1",
33+
"phptal/phptal": "^1.4"
3334
},
3435
"require-dev": {
3536
"phpunit/phpunit": "*"

src/Controller/AbstractController.php

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,43 +2,45 @@
22

33
namespace Pdsinterop\Solid\Controller;
44

5+
use Pdsinterop\Solid\Traits\HasResponseTrait;
6+
use Pdsinterop\Solid\Traits\HasTemplateTrait;
57
use Psr\Http\Message\ResponseInterface;
68
use Psr\Http\Message\ServerRequestInterface;
79

810
abstract class AbstractController
911
{
1012
////////////////////////////// CLASS PROPERTIES \\\\\\\\\\\\\\\\\\\\\\\\\\\\
1113

12-
/** @var ResponseInterface */
13-
private $response;
14-
15-
//////////////////////////// GETTERS AND SETTERS \\\\\\\\\\\\\\\\\\\\\\\\\\\
16-
17-
final public function getResponse() : ResponseInterface
18-
{
19-
return $this->response;
20-
}
14+
use HasResponseTrait;
15+
use HasTemplateTrait;
2116

2217
//////////////////////////////// PUBLIC API \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
2318

24-
public function __construct(ResponseInterface $response)
25-
{
26-
$this->response = $response;
27-
}
28-
2919
abstract public function __invoke(ServerRequestInterface $request, array $args) : ResponseInterface;
3020

3121
final public function createRedirectResponse(string $url, int $status = 302) : ResponseInterface
3222
{
33-
return $this->response->withHeader('location', $url)->withStatus($status);
23+
return $this->getResponse()
24+
->withHeader('location', $url)
25+
->withStatus($status)
26+
;
27+
}
28+
29+
final public function createTemplateResponse(string $template, array $context = []) : ResponseInterface
30+
{
31+
$response = $this->buildTemplate($template, $context);
32+
33+
return $this->createTextResponse($response);
3434
}
3535

3636
final public function createTextResponse(string $message, int $status = 200) : ResponseInterface
3737
{
38-
$body = $this->response->getBody();
38+
$response = $this->getResponse();
39+
40+
$body = $response->getBody();
3941

4042
$body->write($message);
4143

42-
return $this->response->withBody($body)->withStatus($status);
44+
return $response->withBody($body)->withStatus($status);
4345
}
4446
}

src/Controller/Profile/CardController.php

Lines changed: 9 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,39 +2,21 @@
22

33
namespace Pdsinterop\Solid\Controller\Profile;
44

5-
use League\Flysystem\FilesystemInterface;
65
use League\Route\Http\Exception\NotFoundException;
76
use Pdsinterop\Rdf\Enum\Format;
87
use Pdsinterop\Solid\Controller\AbstractController;
8+
use Pdsinterop\Solid\Traits\HasFilesystemTrait;
99
use Psr\Http\Message\ServerRequestInterface;
1010
use Psr\Http\Message\ResponseInterface;
1111

1212
class CardController extends AbstractController
1313
{
1414
////////////////////////////// CLASS PROPERTIES \\\\\\\\\\\\\\\\\\\\\\\\\\\\
1515

16-
/** @var FilesystemInterface $filesystem */
17-
private $filesystem;
18-
19-
//////////////////////////// GETTERS AND SETTERS \\\\\\\\\\\\\\\\\\\\\\\\\\\
16+
use HasFilesystemTrait;
2017

2118
//////////////////////////////// PUBLIC API \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
2219

23-
/**
24-
* CardController constructor.
25-
*
26-
* @param ResponseInterface $response
27-
* @param FilesystemInterface $filesystem
28-
*/
29-
final public function __construct(
30-
ResponseInterface $response,
31-
FilesystemInterface $filesystem
32-
) {
33-
$this->filesystem = $filesystem;
34-
35-
parent::__construct($response);
36-
}
37-
3820
/**
3921
* @param ServerRequestInterface $request
4022
* @param array $args
@@ -45,8 +27,14 @@ final public function __construct(
4527
*/
4628
final public function __invoke(ServerRequestInterface $request, array $args): ResponseInterface
4729
{
30+
// @FIXME: Target file is hard-coded for not, replace with path from $request->getRequestTarget()
31+
$filePath = '/foaf.rdf';
32+
$filesystem = $this->getFilesystem();
4833
$extension = '.ttl';
4934

35+
// @TODO: Content negotiation from Accept headers
36+
//$format = $request->getHeader('Accept');
37+
5038
if (array_key_exists('extension', $args)) {
5139
$extension = $args['extension'];
5240
}
@@ -59,11 +47,8 @@ final public function __invoke(ServerRequestInterface $request, array $args): Re
5947

6048
$contentType = $this->getContentTypeForFormat($format);
6149

62-
// @FIXME: Target file is hard-coded for not, replace with path from $request->getRequestTarget()
63-
$filePath = '/foaf.rdf';
64-
6550
/** @noinspection PhpUndefinedMethodInspection */ // Method `readRdf` is defined by plugin
66-
$content = $this->filesystem->readRdf($filePath, $format);
51+
$content = $filesystem->readRdf($filePath, $format);
6752

6853
return $this->createTextResponse($content)->withHeader('Content-Type', $contentType);
6954
}

src/Controller/Profile/ProfileController.php

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,51 @@
22

33
namespace Pdsinterop\Solid\Controller\Profile;
44

5-
use Pdsinterop\Solid\Controller\AbstractRedirectController;
5+
use League\Flysystem\FilesystemInterface;
6+
use Pdsinterop\Rdf\Enum\Format;
7+
use Pdsinterop\Solid\Controller\AbstractController;
8+
use Pdsinterop\Solid\Traits\HasFilesystemTrait;
9+
use Psr\Http\Message\ResponseInterface;
10+
use Psr\Http\Message\ServerRequestInterface;
611

7-
class ProfileController extends AbstractRedirectController
12+
class ProfileController extends AbstractController
813
{
9-
/** @return string */
10-
public function getTargetUrl() : string
14+
////////////////////////////// CLASS PROPERTIES \\\\\\\\\\\\\\\\\\\\\\\\\\\\
15+
16+
use HasFilesystemTrait;
17+
18+
//////////////////////////////// PUBLIC API \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
19+
20+
public function __invoke(ServerRequestInterface $request, array $args) : ResponseInterface
1121
{
12-
return $this->getPath() . 'card' . $this->getQuery();
22+
$filesystem = $this->getFilesystem();
23+
24+
$formats = Format::keys();
25+
$contents = $this->fetchFileContents($filesystem, $formats);
26+
27+
return $this->createTemplateResponse('card.html', [
28+
'files' => $contents,
29+
'formats' => $formats,
30+
]);
31+
}
32+
33+
////////////////////////////// UTILITY METHODS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\
34+
35+
/**
36+
* @param FilesystemInterface $filesystem
37+
* @param array string[]
38+
*
39+
* @return string[]
40+
*/
41+
private function fetchFileContents(FilesystemInterface $filesystem, array $formats) : array
42+
{
43+
$contents = [];
44+
45+
array_walk($formats, static function ($format, $index) use (&$contents, $filesystem) {
46+
/** @noinspection PhpUndefinedMethodInspection */ // Method `readRdf` is defined by plugin
47+
$contents[$index] = $filesystem->readRdf('/foaf.rdf', $format);
48+
});
49+
50+
return $contents;
1351
}
1452
}

src/ExceptionResponse.php

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace Pdsinterop\Solid;
4+
5+
use Exception;
6+
use Laminas\Diactoros\Response\HtmlResponse;
7+
use League\Route\Http\Exception as HttpException;
8+
use League\Route\Http\Exception\NotFoundException;
9+
10+
class ExceptionResponse
11+
{
12+
////////////////////////////// CLASS PROPERTIES \\\\\\\\\\\\\\\\\\\\\\\\\\\\
13+
14+
private const MESSAGE_GENERIC_ERROR = 'Yeah, that\'s an error.';
15+
private const MESSAGE_NO_SUCH_PAGE = 'No such page.';
16+
17+
/** @var Exception */
18+
private $exception;
19+
20+
//////////////////////////////// PUBLIC API \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
21+
22+
final public function __construct(Exception $exception)
23+
{
24+
$this->exception = $exception;
25+
}
26+
27+
final public function createResponse() : HtmlResponse
28+
{
29+
$exception = $this->exception;
30+
31+
if ($exception instanceof HttpException) {
32+
$response = $this->respondToHttpException($exception);
33+
} else {
34+
$response = $this->responseToException($exception);
35+
}
36+
37+
return $response;
38+
}
39+
40+
////////////////////////////// UTILITY METHODS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\
41+
42+
private function isDevelop() : bool
43+
{
44+
static $isDevelop;
45+
46+
if ($isDevelop === null) {
47+
$isDevelop = getenv('ENVIRONMENT') === 'development';
48+
}
49+
50+
return $isDevelop;
51+
}
52+
53+
private function responseToException(Exception $exception) : HtmlResponse
54+
{
55+
$html = "<h1>Oh-no! The developers messed up!</h1><p>{$exception->getMessage()}</p>";
56+
57+
if ($this->isDevelop()) {
58+
$html .=
59+
"<p>{$exception->getFile()}:{$exception->getLine()}</p>" .
60+
"<pre>{$exception->getTraceAsString()}</pre>";
61+
}
62+
63+
return new HtmlResponse($html, 500, []);
64+
}
65+
66+
private function respondToHttpException(HttpException $exception) : HtmlResponse
67+
{
68+
$status = $exception->getStatusCode();
69+
70+
$message = self::MESSAGE_GENERIC_ERROR;
71+
72+
if ($exception instanceof NotFoundException) {
73+
$message = self::MESSAGE_NO_SUCH_PAGE;
74+
}
75+
76+
$html = vsprintf('<h1>%s</h1><p>%s (%s)</p>', [
77+
$message,
78+
$exception->getMessage(),
79+
$status,
80+
]);
81+
82+
if ($this->isDevelop()) {
83+
$html .= "<pre>{$exception->getTraceAsString()}</pre>";
84+
}
85+
86+
return new HtmlResponse($html, $status, $exception->getHeaders());
87+
}
88+
}

0 commit comments

Comments
 (0)