Skip to content
This repository was archived by the owner on Jan 29, 2020. It is now read-only.

Commit a476345

Browse files
committed
Added documentation on zend-expressive-helpers
This patch adds a new section on zendframework/zend-expressive-helpers, detailing installation, usage, and configuration of each of the `UrlHelper` and `ServerUrlHelper`. It also updates the Observers documentation as follows: - It removes the section on delegator factories; and - Adds a section detailing how factories for observers can also attach the observer to the application instance, which becomes a portable way of accomplishing the task between container implementations.
1 parent e161d2e commit a476345

File tree

7 files changed

+340
-59
lines changed

7 files changed

+340
-59
lines changed

doc/book/helpers/bookdown.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"title": "Helpers",
3+
"content": [
4+
{"Introduction": "intro.md"},
5+
{"UrlHelper": "url-helper.md"},
6+
{"ServerUrlHelper": "server-url-helper.md"}
7+
]
8+
}

doc/book/helpers/intro.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Helpers
2+
3+
Some tasks and features will be common to many if not all applications. For
4+
those, Expressive provides *helpers*. These are typically utility classes that
5+
may integrate features or simply provide standalone benefits.
6+
7+
Currently, these include:
8+
9+
- [UrlHelper](url-helper.md)
10+
- [ServerUrlHelper](server-url-helper.md)
11+
12+
## Installation
13+
14+
If you started your project using the Expressive skeleton package, the helpers
15+
are already installed.
16+
17+
If not, you can install them as follows:
18+
19+
```bash
20+
$ composer require zendframework/zend-expressive-helpers
21+
```
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
# ServerUrlHelper
2+
3+
`Zend\Expressive\Helper\ServerUrlHelper` provides the ability to generate a full
4+
URI by passing only the path to the helper; it will then use that path with the
5+
current `Psr\Http\Message\UriInterface` instance provided to it in order to
6+
generate a fully qualified URI.
7+
8+
## Usage
9+
10+
When you have an instance, use either its `generate()` method, or call the
11+
instance as an invokable:
12+
13+
```php
14+
// Using the generate() method:
15+
$url = $helper->generate('/foo');
16+
17+
// is equivalent to invocation:
18+
$url = $helper('/foo');
19+
```
20+
21+
The helper is particularly useful when used in conjunction with the
22+
[UrlHelper](url-helper.md), as you can then create fully qualified URIs for use
23+
with headers, API hypermedia links, etc.:
24+
25+
```php
26+
$url = $serverUrl($url('resource', ['id' => 'sha1']));
27+
```
28+
29+
The signature for the ServerUrlHelper `generate()` and `__invoke()` methods is:
30+
31+
```php
32+
function ($path = null) : string
33+
```
34+
35+
Where:
36+
37+
- `$path`, when provided, can be a string path to use to generate a URI.
38+
39+
## Creating an instance
40+
41+
In order to use the helper, you will need to inject it with the current
42+
`UriInterface` from the request instance. To automate this, we provide
43+
`Zend\Expressive\Helper\ServerUrlMiddleware`, which composes a `ServerUrl`
44+
instance, and, when invoked, injects it with the URI instance.
45+
46+
As such, you will need to:
47+
48+
- Register the `ServerUrlHelper` as a service in your container.
49+
- Register the `ServerUrlMiddleware` as a service in your container.
50+
- Register the `ServerUrlMiddleware` as pre_routing pipeline middleware.
51+
52+
The following examples demonstrate registering the services.
53+
54+
```php
55+
use Zend\Expressive\Helper\ServerUrlHelper;
56+
use Zend\Expressive\Helper\ServerUrlMiddleware;
57+
use Zend\Expressive\Helper\ServerUrlMiddlewareFactory;
58+
59+
// zend-servicemanager:
60+
$services->setInvokableClass(ServerUrlHelper::class, ServerUrlHelper::class);
61+
$services->setFactory(ServerUrlMiddleware::class, ServerUrlMiddlewareFactory::class);
62+
63+
// Pimple:
64+
$pimple[ServerUrlHelper::class] = $pimple->share(function ($container) {
65+
return new ServerUrlHelper();
66+
});
67+
$pimple[ServerUrlMiddleware::class] = $pimple->share(function ($container) {
68+
$factory = new ServerUrlMiddlewareFactory();
69+
return $factory($container);
70+
});
71+
72+
// Aura.Di:
73+
$container->set(ServerUrlHelper::class, $container->lazyNew(ServerUrlHelper::class));
74+
$container->set(ServerUrlMiddlewareFactory::class, $container->lazyNew(ServerUrlMiddlewareFactory::class));
75+
$container->set(
76+
ServerUrlMiddleware::class,
77+
$container->lazyGetCall(ServerUrlMiddlewareFactory::class, '__invoke', $container)
78+
);
79+
```
80+
81+
To register the `ServerUrlMiddleware` as pre-routing pipeline middleware:
82+
83+
```php
84+
use Zend\Expressive\Helper\ServerUrlMiddleware;
85+
86+
// Do this early, before piping other middleware or routes:
87+
$app->pipe(ServerUrlMiddleware::class);
88+
89+
// Or use configuration:
90+
// [
91+
// 'middleware_pipeline' => [
92+
// 'pre_routing' => [
93+
// ['middleware' => ServerUrlMiddleware::class],
94+
// ],
95+
// ],
96+
// ]
97+
```
98+
99+
The following dependency configuration will work for all three when using the
100+
Expressive skeleton:
101+
102+
```php
103+
return [
104+
'dependencies' => [
105+
'invokables' => [
106+
ServerUrlHelper::class => ServerUrlHelper::class,
107+
],
108+
'factories' => [
109+
ServerUrlMiddleware::class => ServerUrlMiddlewareFactory::class,
110+
],
111+
],
112+
'middleware_pipeline' => [
113+
'pre_routing' => [
114+
['middleware' => ServerUrlMiddleware::class],
115+
],
116+
],
117+
]
118+
```
119+
120+
> ## Skeleton configures helpers
121+
>
122+
> If you started your project using the Expressive skeleton package, the
123+
> `ServerUrlHelper` and `ServerUrlMiddleware` factories are already registered
124+
> for you, as is the `ServerUrlMiddleware` pre_routing pipeline middleware.
125+
126+
## Using the helper in middleware
127+
128+
Compose the helper in your middleware (or elsewhere), and then use it to
129+
generate URI paths:
130+
131+
```php
132+
use Zend\Expressive\Helper\ServerUrlHelper;
133+
134+
class FooMiddleware
135+
{
136+
private $helper;
137+
138+
public function __construct(ServerUrlHelper $helper)
139+
{
140+
$this->helper = $helper;
141+
}
142+
143+
public function __invoke($request, $response, callable $next)
144+
{
145+
$response = $response->withHeader(
146+
'Link',
147+
$this->helper->generate() . '; rel="self"'
148+
);
149+
return $next($request, $response);
150+
}
151+
}
152+
```

doc/book/helpers/url-helper.md

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
# UrlHelper
2+
3+
`Zend\Expressive\Helper\UrlHelper` provides the ability to generate a URI path
4+
based on a given route defined in the `Zend\Expressive\Router\RouterInterface`.
5+
If registered as a route result observer, and the route being used was also
6+
the one matched during routing, you can provide a subset of routing
7+
parameters, and any not provided will be pulled from those matched.
8+
9+
## Usage
10+
11+
When you have an instance, use either its `generate()` method, or call the
12+
instance as an invokable:
13+
14+
```php
15+
// Using the generate() method:
16+
$url = $helper->generate('resource', ['id' => 'sha1']);
17+
18+
// is equivalent to invocation:
19+
$url = $helper('resource', ['id' => 'sha1']);
20+
```
21+
22+
The signature for both is:
23+
24+
```php
25+
function ($routeName, array $params = []) : string
26+
```
27+
28+
Where:
29+
30+
- `$routeName` is the name of a route defined in the composed router. You may
31+
omit this argument if you want to generate the path for the currently matched
32+
request.
33+
- `$params` is an array of substitutions to use for the provided route, with the
34+
following behavior:
35+
- If a `RouteResult` is composed in the helper, and the `$routeName` matches
36+
it, the provided `$params` will be merged with any matched parameters, with
37+
those provided taking precedence.
38+
- If a `RouteResult` is not composed, or if the composed result does not match
39+
the provided `$routeName`, then only the `$params` provided will be used
40+
for substitutions.
41+
- If no `$params` are provided, and the `$routeName` matches the currently
42+
matched route, then any matched parameters found will be used.
43+
parameters found will be used.
44+
- If no `$params` are provided, and the `$routeName` does not match the
45+
currently matched route, or if no route result is present, then no
46+
substitutions will be made.
47+
48+
Each method will raise an exception if:
49+
50+
- No `$routeName` is provided, and no `RouteResult` is composed.
51+
- No `$routeName` is provided, a `RouteResult` is composed, but that result
52+
represents a matching failure.
53+
- The given `$routeName` is not defined in the router.
54+
55+
## Creating an instance
56+
57+
In order to use the helper, you will need to instantiate it with the current
58+
`RouterInterface`. The factory `Zend\Expressive\Helper\UrlHelperFactory` has
59+
been provided for this purpose, and can be used trivially with most
60+
dependency injection containers implementing container-interop:
61+
62+
```php
63+
use Zend\Expressive\Helper\UrlHelper;
64+
use Zend\Expressive\Helper\UrlHelperFactory;
65+
66+
// zend-servicemanager:
67+
$services->setFactory(UrlHelper::class, UrlHelperFactory::class);
68+
69+
// Pimple:
70+
$pimple[UrlHelper::class] = $pimple->share(function ($container) {
71+
$factory = new UrlHelperFactory();
72+
return $factory($container);
73+
});
74+
75+
// Aura.Di:
76+
$container->set(UrlHelperFactory::class, $container->lazyNew(UrlHelperFactory::class));
77+
$container->set(
78+
UrlHelper::class,
79+
$container->lazyGetCall(UrlHelperFactory::class, '__invoke', $container)
80+
);
81+
```
82+
83+
The following dependency configuration will work for all three when using the
84+
Expressive skeleton:
85+
86+
```php
87+
return ['dependencies' => [
88+
'factories' => [
89+
UrlHelper::class => UrlHelperFactory::class,
90+
],
91+
]]
92+
```
93+
94+
> ## Factory requires RouterInterface
95+
>
96+
> The factory requires that a service named `Zend\Expressive\Router\RouterInterface` is present,
97+
> and will raise an exception if the service is not found.
98+
99+
> ## Skeleton configures helpers
100+
>
101+
> If you started your project using the Expressive skeleton package, the
102+
> `UrlHelper` factory is already registered for you.
103+
104+
## Using the helper in middleware
105+
106+
Compose the helper in your middleware (or elsewhere), and then use it to
107+
generate URI paths:
108+
109+
```php
110+
use Zend\Expressive\Helper\UrlHelper;
111+
112+
class FooMiddleware
113+
{
114+
private $helper;
115+
116+
public function __construct(UrlHelper $helper)
117+
{
118+
$this->helper = $helper;
119+
}
120+
121+
public function __invoke($request, $response, callable $next)
122+
{
123+
$response = $response->withHeader(
124+
'Link',
125+
$this->helper->generate('resource', ['id' => 'sha1'])
126+
);
127+
return $next($request, $response);
128+
}
129+
}
130+
```

0 commit comments

Comments
 (0)