This repository has been archived by the owner on Jan 29, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 195
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'feature/helpers' into develop
Forward port #210
- Loading branch information
Showing
8 changed files
with
343 additions
and
59 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
{ | ||
"title": "Helpers", | ||
"content": [ | ||
{"Introduction": "intro.md"}, | ||
{"UrlHelper": "url-helper.md"}, | ||
{"ServerUrlHelper": "server-url-helper.md"} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# Helpers | ||
|
||
Some tasks and features will be common to many if not all applications. For | ||
those, Expressive provides *helpers*. These are typically utility classes that | ||
may integrate features or simply provide standalone benefits. | ||
|
||
Currently, these include: | ||
|
||
- [UrlHelper](url-helper.md) | ||
- [ServerUrlHelper](server-url-helper.md) | ||
|
||
## Installation | ||
|
||
If you started your project using the Expressive skeleton package, the helpers | ||
are already installed. | ||
|
||
If not, you can install them as follows: | ||
|
||
```bash | ||
$ composer require zendframework/zend-expressive-helpers | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
# ServerUrlHelper | ||
|
||
`Zend\Expressive\Helper\ServerUrlHelper` provides the ability to generate a full | ||
URI by passing only the path to the helper; it will then use that path with the | ||
current `Psr\Http\Message\UriInterface` instance provided to it in order to | ||
generate a fully qualified URI. | ||
|
||
## Usage | ||
|
||
When you have an instance, use either its `generate()` method, or call the | ||
instance as an invokable: | ||
|
||
```php | ||
// Using the generate() method: | ||
$url = $helper->generate('/foo'); | ||
|
||
// is equivalent to invocation: | ||
$url = $helper('/foo'); | ||
``` | ||
|
||
The helper is particularly useful when used in conjunction with the | ||
[UrlHelper](url-helper.md), as you can then create fully qualified URIs for use | ||
with headers, API hypermedia links, etc.: | ||
|
||
```php | ||
$url = $serverUrl($url('resource', ['id' => 'sha1'])); | ||
``` | ||
|
||
The signature for the ServerUrlHelper `generate()` and `__invoke()` methods is: | ||
|
||
```php | ||
function ($path = null) : string | ||
``` | ||
|
||
Where: | ||
|
||
- `$path`, when provided, can be a string path to use to generate a URI. | ||
|
||
## Creating an instance | ||
|
||
In order to use the helper, you will need to inject it with the current | ||
`UriInterface` from the request instance. To automate this, we provide | ||
`Zend\Expressive\Helper\ServerUrlMiddleware`, which composes a `ServerUrl` | ||
instance, and, when invoked, injects it with the URI instance. | ||
|
||
As such, you will need to: | ||
|
||
- Register the `ServerUrlHelper` as a service in your container. | ||
- Register the `ServerUrlMiddleware` as a service in your container. | ||
- Register the `ServerUrlMiddleware` as pre_routing pipeline middleware. | ||
|
||
The following examples demonstrate registering the services. | ||
|
||
```php | ||
use Zend\Expressive\Helper\ServerUrlHelper; | ||
use Zend\Expressive\Helper\ServerUrlMiddleware; | ||
use Zend\Expressive\Helper\ServerUrlMiddlewareFactory; | ||
|
||
// zend-servicemanager: | ||
$services->setInvokableClass(ServerUrlHelper::class, ServerUrlHelper::class); | ||
$services->setFactory(ServerUrlMiddleware::class, ServerUrlMiddlewareFactory::class); | ||
|
||
// Pimple: | ||
$pimple[ServerUrlHelper::class] = $pimple->share(function ($container) { | ||
return new ServerUrlHelper(); | ||
}); | ||
$pimple[ServerUrlMiddleware::class] = $pimple->share(function ($container) { | ||
$factory = new ServerUrlMiddlewareFactory(); | ||
return $factory($container); | ||
}); | ||
|
||
// Aura.Di: | ||
$container->set(ServerUrlHelper::class, $container->lazyNew(ServerUrlHelper::class)); | ||
$container->set(ServerUrlMiddlewareFactory::class, $container->lazyNew(ServerUrlMiddlewareFactory::class)); | ||
$container->set( | ||
ServerUrlMiddleware::class, | ||
$container->lazyGetCall(ServerUrlMiddlewareFactory::class, '__invoke', $container) | ||
); | ||
``` | ||
|
||
To register the `ServerUrlMiddleware` as pre-routing pipeline middleware: | ||
|
||
```php | ||
use Zend\Expressive\Helper\ServerUrlMiddleware; | ||
|
||
// Do this early, before piping other middleware or routes: | ||
$app->pipe(ServerUrlMiddleware::class); | ||
|
||
// Or use configuration: | ||
// [ | ||
// 'middleware_pipeline' => [ | ||
// 'pre_routing' => [ | ||
// ['middleware' => ServerUrlMiddleware::class], | ||
// ], | ||
// ], | ||
// ] | ||
``` | ||
|
||
The following dependency configuration will work for all three when using the | ||
Expressive skeleton: | ||
|
||
```php | ||
return [ | ||
'dependencies' => [ | ||
'invokables' => [ | ||
ServerUrlHelper::class => ServerUrlHelper::class, | ||
], | ||
'factories' => [ | ||
ServerUrlMiddleware::class => ServerUrlMiddlewareFactory::class, | ||
], | ||
], | ||
'middleware_pipeline' => [ | ||
'pre_routing' => [ | ||
['middleware' => ServerUrlMiddleware::class], | ||
], | ||
], | ||
] | ||
``` | ||
|
||
> ## Skeleton configures helpers | ||
> | ||
> If you started your project using the Expressive skeleton package, the | ||
> `ServerUrlHelper` and `ServerUrlMiddleware` factories are already registered | ||
> for you, as is the `ServerUrlMiddleware` pre_routing pipeline middleware. | ||
## Using the helper in middleware | ||
|
||
Compose the helper in your middleware (or elsewhere), and then use it to | ||
generate URI paths: | ||
|
||
```php | ||
use Zend\Expressive\Helper\ServerUrlHelper; | ||
|
||
class FooMiddleware | ||
{ | ||
private $helper; | ||
|
||
public function __construct(ServerUrlHelper $helper) | ||
{ | ||
$this->helper = $helper; | ||
} | ||
|
||
public function __invoke($request, $response, callable $next) | ||
{ | ||
$response = $response->withHeader( | ||
'Link', | ||
$this->helper->generate() . '; rel="self"' | ||
); | ||
return $next($request, $response); | ||
} | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
# UrlHelper | ||
|
||
`Zend\Expressive\Helper\UrlHelper` provides the ability to generate a URI path | ||
based on a given route defined in the `Zend\Expressive\Router\RouterInterface`. | ||
If registered as a route result observer, and the route being used was also | ||
the one matched during routing, you can provide a subset of routing | ||
parameters, and any not provided will be pulled from those matched. | ||
|
||
## Usage | ||
|
||
When you have an instance, use either its `generate()` method, or call the | ||
instance as an invokable: | ||
|
||
```php | ||
// Using the generate() method: | ||
$url = $helper->generate('resource', ['id' => 'sha1']); | ||
|
||
// is equivalent to invocation: | ||
$url = $helper('resource', ['id' => 'sha1']); | ||
``` | ||
|
||
The signature for both is: | ||
|
||
```php | ||
function ($routeName, array $params = []) : string | ||
``` | ||
|
||
Where: | ||
|
||
- `$routeName` is the name of a route defined in the composed router. You may | ||
omit this argument if you want to generate the path for the currently matched | ||
request. | ||
- `$params` is an array of substitutions to use for the provided route, with the | ||
following behavior: | ||
- If a `RouteResult` is composed in the helper, and the `$routeName` matches | ||
it, the provided `$params` will be merged with any matched parameters, with | ||
those provided taking precedence. | ||
- If a `RouteResult` is not composed, or if the composed result does not match | ||
the provided `$routeName`, then only the `$params` provided will be used | ||
for substitutions. | ||
- If no `$params` are provided, and the `$routeName` matches the currently | ||
matched route, then any matched parameters found will be used. | ||
parameters found will be used. | ||
- If no `$params` are provided, and the `$routeName` does not match the | ||
currently matched route, or if no route result is present, then no | ||
substitutions will be made. | ||
|
||
Each method will raise an exception if: | ||
|
||
- No `$routeName` is provided, and no `RouteResult` is composed. | ||
- No `$routeName` is provided, a `RouteResult` is composed, but that result | ||
represents a matching failure. | ||
- The given `$routeName` is not defined in the router. | ||
|
||
## Creating an instance | ||
|
||
In order to use the helper, you will need to instantiate it with the current | ||
`RouterInterface`. The factory `Zend\Expressive\Helper\UrlHelperFactory` has | ||
been provided for this purpose, and can be used trivially with most | ||
dependency injection containers implementing container-interop: | ||
|
||
```php | ||
use Zend\Expressive\Helper\UrlHelper; | ||
use Zend\Expressive\Helper\UrlHelperFactory; | ||
|
||
// zend-servicemanager: | ||
$services->setFactory(UrlHelper::class, UrlHelperFactory::class); | ||
|
||
// Pimple: | ||
$pimple[UrlHelper::class] = $pimple->share(function ($container) { | ||
$factory = new UrlHelperFactory(); | ||
return $factory($container); | ||
}); | ||
|
||
// Aura.Di: | ||
$container->set(UrlHelperFactory::class, $container->lazyNew(UrlHelperFactory::class)); | ||
$container->set( | ||
UrlHelper::class, | ||
$container->lazyGetCall(UrlHelperFactory::class, '__invoke', $container) | ||
); | ||
``` | ||
|
||
The following dependency configuration will work for all three when using the | ||
Expressive skeleton: | ||
|
||
```php | ||
return ['dependencies' => [ | ||
'factories' => [ | ||
UrlHelper::class => UrlHelperFactory::class, | ||
], | ||
]] | ||
``` | ||
|
||
> ## Factory requires RouterInterface | ||
> | ||
> The factory requires that a service named `Zend\Expressive\Router\RouterInterface` is present, | ||
> and will raise an exception if the service is not found. | ||
> ## Skeleton configures helpers | ||
> | ||
> If you started your project using the Expressive skeleton package, the | ||
> `UrlHelper` factory is already registered for you. | ||
## Using the helper in middleware | ||
|
||
Compose the helper in your middleware (or elsewhere), and then use it to | ||
generate URI paths: | ||
|
||
```php | ||
use Zend\Expressive\Helper\UrlHelper; | ||
|
||
class FooMiddleware | ||
{ | ||
private $helper; | ||
|
||
public function __construct(UrlHelper $helper) | ||
{ | ||
$this->helper = $helper; | ||
} | ||
|
||
public function __invoke($request, $response, callable $next) | ||
{ | ||
$response = $response->withHeader( | ||
'Link', | ||
$this->helper->generate('resource', ['id' => 'sha1']) | ||
); | ||
return $next($request, $response); | ||
} | ||
} | ||
``` |
Oops, something went wrong.