Completed
Push — master ( 06321c...b705c4 )
by Alexpts
02:11
created

EndPoint::getParams()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 6
ccs 0
cts 3
cp 0
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 4
nc 1
nop 1
crap 2
1
<?php
2
declare(strict_types=1);
3
4
namespace PTS\EndPoint;
5
6
use Psr\Http\Message\ResponseInterface;
7
use Psr\Http\Message\ServerRequestInterface;
8
use Psr\Http\Server\RequestHandlerInterface;
9
use PTS\PSR15Routing\Route;
10
11
abstract class EndPoint implements RequestHandlerInterface
12
{
13
	/** @var string|null */
14
	protected $controller;
15
	/** @var string|null */
16
	protected $action;
17
	/** @var string */
18
    protected $prefix = '';
19
20
    public function __construct(array $params = [])
21
    {
22
        foreach ($params as $name => $param) {
23
            if (property_exists($this, $name)) {
24
                $this->{$name} = $param;
25
            }
26
        }
27
    }
28
29
    /**
30
     * @param ServerRequestInterface $request
31
     *
32
     * @return ResponseInterface
33
     * @throws \BadMethodCallException
34
     */
35
    public function handle(ServerRequestInterface $request): ResponseInterface
36
	{
37
    	$route = $this->getRoute($request);
38
        $endPoint = $this->getPoint($request);
39
40
        $params = $this->getParams($route);
41
        return $endPoint(...$params);
42
    }
43
44
	/**
45
	 * Get params from router and remove all protected params (_controller/_action/_other)
46
	 *
47
	 * @param Route $route
48
	 * @return array
49
	 */
50
    protected function getParams(Route $route): array
51
	{
52
        return array_filter($route->getMatchesParams(), function ($name) {
53
            return $name[0] !== '_';
54
        }, ARRAY_FILTER_USE_KEY);
55
	}
56
57
    /**
58
     * @param ServerRequestInterface $request
59
     *
60
     * @return callable
61
     * @throws \BadMethodCallException
62
     */
63
	protected function getPoint(ServerRequestInterface $request) : callable
64
    {
65
        $controller = $this->getControllerClass($request);
66
        $this->checkController($controller);
67
68
        $controller = new $controller($request);
69
70
        $action = $this->getAction($request) ?? 'index';
71
        $this->checkAction($controller, $action);
72
73
        return [$controller, $action];
74
    }
75
76
    abstract protected function getControllerClass(ServerRequestInterface $request);
77
78
	/**
79
	 * @param string $controller
80
	 * @throws \BadMethodCallException
81
	 */
82
	protected function checkController(string $controller) : void
83
    {
84
        if (!class_exists($controller)) {
85
            throw new \BadMethodCallException('Controller not found');
86
        }
87
    }
88
89
	/**
90
	 * @param \object $controller
0 ignored issues
show
Documentation introduced by
Should the type for parameter $controller not be object?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
91
	 * @param string $action
92
	 * @throws \BadMethodCallException
93
	 */
94
	protected function checkAction(object $controller, string $action) : void
95
    {
96
        if (!method_exists($controller, $action)) {
97
            throw new \BadMethodCallException('Action not found');
98
        }
99
    }
100
101
	protected function getAction(ServerRequestInterface $request): ?string
102
	{
103
        $route = $this->getRoute($request);
104
        $matches = $route->getMatchesParams();
105
		return $matches['_action'] ?? $this->action ?? null;
106
	}
107
108
	protected function getRoute(ServerRequestInterface $request): Route
109
    {
110
        return $request->getAttribute('route');
111
    }
112
}
113