Subversion-Projekte lars-tiefland.laravel_shop

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
199 lars 1
<?php namespace Clockwork\Support\Slim;
2
 
3
use Clockwork\Clockwork;
4
use Clockwork\Authentication\NullAuthenticator;
5
use Clockwork\DataSource\PsrMessageDataSource;
6
use Clockwork\Storage\FileStorage;
7
use Clockwork\Helpers\ServerTiming;
8
 
9
use Psr\Http\Message\ServerRequestInterface as Request;
10
use Psr\Http\Server\RequestHandlerInterface as RequestHandler;
11
 
12
// Slim 4 middleware
13
class ClockworkMiddleware
14
{
15
	protected $app;
16
	protected $clockwork;
17
	protected $startTime;
18
 
19
	public function __construct($app, $storagePathOrClockwork, $startTime = null)
20
	{
21
		$this->app = $app;
22
		$this->clockwork = $storagePathOrClockwork instanceof Clockwork
23
			? $storagePathOrClockwork : $this->createDefaultClockwork($storagePathOrClockwork);
24
		$this->startTime = $startTime ?: microtime(true);
25
	}
26
 
27
	public function __invoke(Request $request, RequestHandler $handler)
28
	{
29
		return $this->process($request, $handler);
30
	}
31
 
32
	public function process(Request $request, RequestHandler $handler)
33
	{
34
		$authUri = '#/__clockwork/auth#';
35
		if (preg_match($authUri, $request->getUri()->getPath(), $matches)) {
36
			return $this->authenticate($request);
37
		}
38
 
39
		$clockworkDataUri = '#/__clockwork(?:/(?<id>[0-9-]+))?(?:/(?<direction>(?:previous|next)))?(?:/(?<count>\d+))?#';
40
		if (preg_match($clockworkDataUri, $request->getUri()->getPath(), $matches)) {
41
			$matches = array_merge([ 'id' => null, 'direction' => null, 'count' => null ], $matches);
42
			return $this->retrieveRequest($request, $matches['id'], $matches['direction'], $matches['count']);
43
		}
44
 
45
		$response = $handler->handle($request);
46
 
47
		return $this->logRequest($request, $response);
48
	}
49
 
50
	protected function authenticate(Request $request)
51
	{
52
		$token = $this->clockwork->authenticator()->attempt($request->getParsedBody());
53
 
54
		return $this->jsonResponse([ 'token' => $token ], $token ? 200 : 403);
55
	}
56
 
57
	protected function retrieveRequest(Request $request, $id, $direction, $count)
58
	{
59
		$authenticator = $this->clockwork->authenticator();
60
		$storage = $this->clockwork->storage();
61
 
62
		$authenticated = $authenticator->check(current($request->getHeader('X-Clockwork-Auth')));
63
 
64
		if ($authenticated !== true) {
65
			return $this->jsonResponse([ 'message' => $authenticated, 'requires' => $authenticator->requires() ], 403);
66
		}
67
 
68
		if ($direction == 'previous') {
69
			$data = $storage->previous($id, $count);
70
		} elseif ($direction == 'next') {
71
			$data = $storage->next($id, $count);
72
		} elseif ($id == 'latest') {
73
			$data = $storage->latest();
74
		} else {
75
			$data = $storage->find($id);
76
		}
77
 
78
		return $this->jsonResponse($data);
79
	}
80
 
81
	protected function logRequest(Request $request, $response)
82
	{
83
		$this->clockwork->timeline()->finalize($this->startTime);
84
		$this->clockwork->addDataSource(new PsrMessageDataSource($request, $response));
85
 
86
		$this->clockwork->resolveRequest();
87
		$this->clockwork->storeRequest();
88
 
89
		$clockworkRequest = $this->clockwork->request();
90
 
91
		$response = $response
92
			->withHeader('X-Clockwork-Id', $clockworkRequest->id)
93
			->withHeader('X-Clockwork-Version', Clockwork::VERSION);
94
 
95
		if ($basePath = $this->app->getBasePath()) {
96
			$response = $response->withHeader('X-Clockwork-Path', $basePath);
97
		}
98
 
99
		return $response->withHeader('Server-Timing', ServerTiming::fromRequest($clockworkRequest)->value());
100
	}
101
 
102
	protected function createDefaultClockwork($storagePath)
103
	{
104
		$clockwork = new Clockwork();
105
 
106
		$clockwork->storage(new FileStorage($storagePath));
107
		$clockwork->authenticator(new NullAuthenticator);
108
 
109
		return $clockwork;
110
	}
111
 
112
	protected function jsonResponse($data, $status = 200)
113
	{
114
		$response = $this->app->getResponseFactory()
115
			->createResponse($status)
116
			->withHeader('Content-Type', 'application/json');
117
 
118
		$response->getBody()->write(json_encode($data));
119
 
120
		return $response;
121
	}
122
}