-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathRouteNode.php
256 lines (235 loc) · 7.96 KB
/
RouteNode.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
<?php declare(strict_types=1);
/*
* This file is part of Polymorphine/Routing package.
*
* (c) Shudd3r <q3.shudder@gmail.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace Polymorphine\Routing\Builder\Node;
use Polymorphine\Routing\Builder\Node;
use Polymorphine\Routing\Builder\Context;
use Polymorphine\Routing\Builder\Exception;
use Polymorphine\Routing\Builder\Node\Resource\ResourceSwitchNode;
use Polymorphine\Routing\Builder\Node\Resource\LinkedFormsResourceSwitchNode;
use Polymorphine\Routing\Builder\Node\Resource\FormsContext;
use Polymorphine\Routing\Route;
use Psr\Http\Server\RequestHandlerInterface;
/**
* Builder that adds Route or given routing tree wrapped by gates
* to current NodeContext or creates Builder where new contexts
* Routes are created (branched routes).
*
* Current context might be built as root with build() method.
*/
class RouteNode implements Node
{
use GateBuildMethods;
/**
* @param Context $context
*/
public function __construct(Context $context)
{
$this->context = $context;
}
public function build(): Route
{
return $this->context->build();
}
/**
* Adds CallbackEndpoint created with given callback.
*
* @see Route\Endpoint\CallbackEndpoint
*
* @param callable $callback fn(ServerRequestInterface) => ResponseInterface
*/
public function callback(callable $callback): void
{
$this->context->setCallbackRoute($callback);
}
/**
* Adds HandlerEndpoint created with given handler.
*
* @see Route\Endpoint\HandlerEndpoint
*
* @param RequestHandlerInterface $handler
*/
public function handler(RequestHandlerInterface $handler): void
{
$this->context->setHandlerRoute($handler);
}
/**
* Adds LazyRoute gate that invokes routes with given
* callback on forward request call.
*
* @see Route\Gate\LazyRoute
*
* @param callable $routeCallback fn() => Route
*/
public function lazy(callable $routeCallback): void
{
$this->context->setLazyRoute($routeCallback);
}
/**
* Adds endpoint that returns redirect response to given routing
* path for any request being forwarded.
*
* To call this method BuilderContext the class was instantiated with
* needs to be able to provide Router callback that this endpoint
* depends on - otherwise ConfigException will be thrown.
*
* @see Route\Endpoint\RedirectEndpoint
* @see \Polymorphine\Routing\Builder\MappedRoutes::redirect()
*
* @param string $routingPath
* @param int $code
*
* @throws Exception\ConfigException
*/
public function redirect(string $routingPath, int $code = 301): void
{
$this->context->setRedirectRoute($routingPath, $code);
}
/**
* Adds endpoint Route resolved from passed identifier.
*
* NOTE: In order to use this method endpoint callback in
* MappedRoutes has to be defined or ConfigException will
* be thrown.
*
* @see \Polymorphine\Routing\Builder\MappedRoutes::endpoint()
*
* @param string $id
*
* @throws Exception\ConfigException
*/
public function endpoint(string $id): void
{
$this->context->mapEndpoint($id);
}
/**
* Adds given Route wrapped with called gates.
*
* @param Route $route
*/
public function joinRoute(Route $route): void
{
$this->context->setRoute($route);
}
/**
* Adds a link to another Builder context using reference variable.
* If Route in that context will not be created until this builder
* will attempt to build it BuilderLogicException will be thrown.
*
* @param Route|null &$route reference to current of future Route
*/
public function joinLink(?Route &$route): void
{
$this->context->setBuilder(new LinkedRouteNode($route));
}
/**
* Creates PathSwitch node context builder.
* Optionally already defined array of Routes with keys representing
* Uri (and routing) path segment might be given as parameter.
*
* @see Route\Splitter\PathSwitch
*
* @param Route[] $routes associated with Uri & routing path segment keys
*
* @return PathSwitchNode
*/
public function pathSwitch(array $routes = []): PathSwitchNode
{
return $this->contextBuilder(new PathSwitchNode($this->context, $routes));
}
/**
* Creates RouteScan node context builder.
* Optionally already defined array of Routes with (optional) keys
* representing routing path segment might be given as parameter.
* Anonymous Routes (without key) cannot be explicitly selected
* (to produce Uri), but matched request would reach them.
*
* @see Route\Splitter\ScanSwitch
*
* @param Route[] $routes associated with routing path segment keys
*
* @return ScanSwitchNode
*/
public function responseScan(array $routes = []): ScanSwitchNode
{
return $this->contextBuilder(new ScanSwitchNode($this->context, $routes));
}
/**
* Creates MethodSwitch node context builder.
* Optionally already defined array of Routes with keys representing
* http methods (and routing path segment) might be given as parameter.
*
* @see Route\Splitter\MethodSwitch
*
* @param Route[] $routes associated with http method keys
*
* @return MethodSwitchNode
*/
public function methodSwitch(array $routes = []): MethodSwitchNode
{
return $this->contextBuilder(new MethodSwitchNode($this->context, $routes));
}
/**
* Creates CallbackSwitch node context builder.
* Optional defined associative array of Routes with id keys
* returned by callback.
*
* @see Route\Splitter\CallbackSwitch
*
* @param callable $idCallback fn(ServerRequestInterface) => string
* @param array $routes
*
* @return CallbackSwitchNode
*/
public function callbackSwitch(callable $idCallback, array $routes = []): CallbackSwitchNode
{
return $this->contextBuilder(new CallbackSwitchNode($this->context, $idCallback, $routes));
}
/**
* Creates node context builder producing composite routing logic
* for REST resource.
* Optionally already defined array of Routes with keys representing
* http methods and pseudo methods* (and routing path segment) might be
* given as parameter.
*
* Pseudo methods are:
* INDEX - for GET requests to all resources (unspecified id),
* NEW - for GET requests to form producing new resource (without current id),
* EDIT - for GET requests to form editing resource with given id
*
* Optional ResourceFormsBuilder parameter will be used to define separate
* routing for forms built with add() and edit() methods or passed as array
* Route parameters with NEW|EDIT keys.
*
* WARNING: This method does not specify resource name (path) and should be
* used in case when resource route needs to be wrapped with additional gates.
* Otherwise it is recommended to build resource with method that defines its
* name directly in PathSwitchBuilder or RouteScanBuilder.
*
* @see PathSwitchNode::resource()
* @see ScanSwitchNode::resource()
*
* @param array $routes
* @param FormsContext|null $formsBuilder
*
* @return ResourceSwitchNode
*/
public function resource(array $routes = [], ?FormsContext $formsBuilder = null): ResourceSwitchNode
{
$switchNode = $formsBuilder
? new LinkedFormsResourceSwitchNode($formsBuilder, $this->context, $routes)
: new ResourceSwitchNode($this->context, $routes);
return $this->contextBuilder($switchNode);
}
private function contextBuilder($builder)
{
$this->context->setBuilder($builder);
return $builder;
}
}