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

Commit 421e6e8

Browse files
committed
Merge branch 'feature/23-metadata-factories'
Close #23
2 parents 5d4e844 + 2114044 commit 421e6e8

23 files changed

+1117
-313
lines changed

CHANGELOG.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,47 @@ All notable changes to this project will be documented in this file, in reverse
44

55
Versions prior to 0.4.0 were released as the package "weierophinney/hal".
66

7+
## 0.6.0 - 2017-11-07
8+
9+
### Added
10+
11+
- Nothing.
12+
13+
### Changed
14+
15+
- [#23](https://github.com/zendframework/zend-expressive-hal/pull/23) modifies
16+
how the resource generator factory adds strategies and maps metadata to
17+
strategies. It now adds the following factories under the
18+
`Zend\Expressive\Hal\Metadata` namespace:
19+
20+
- `RouteBasedCollectionMetadataFactory`
21+
- `RouteBasedResourceMetadataFactory`
22+
- `UrlBasedCollectionMetadataFactory`
23+
- `UrlBasedResourceMetadataFactory`
24+
25+
Each implements a new `MetadataFactoryInterface` under that same namespace
26+
that accepts the requested metadata type name and associated metadata in order
27+
to create an `AbstractMetadata` instance. Metadata types are mapped to their
28+
factories under the `zend-expressive-hal.metadata-factories` key.
29+
30+
Strategies are now configured as metadata => strategy class pairings under the
31+
`zend-expressive-hal.resource-generator.strategies` key.
32+
33+
In both cases, defaults that mimic previous behavior are provided via the
34+
`ConfigProvider`.
35+
36+
### Deprecated
37+
38+
- Nothing.
39+
40+
### Removed
41+
42+
- Nothing.
43+
44+
### Fixed
45+
46+
- Nothing.
47+
748
## 0.5.1 - 2017-11-07
849

950
### Added
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# Generating custom resources
2+
3+
The `ResourceGenerator` allows composing `Zend\Expressive\Hal\ResourceGenerator\StrategyInterface`
4+
instances. The `StrategyInterface` defines the following:
5+
6+
```php
7+
namespace Zend\Expressive\Hal\ResourceGenerator;
8+
9+
use Psr\Http\Message\ServerRequestInterface;
10+
use Zend\Expressive\Hal\HalResource;
11+
use Zend\Expressive\Hal\Metadata;
12+
use Zend\Expressive\Hal\ResourceGenerator;
13+
14+
interface StrategyInterface
15+
{
16+
/**
17+
* @param object $instance Instance from which to create Resource.
18+
* @throws Exception\UnexpectedMetadataTypeException for metadata types the
19+
* strategy cannot handle.
20+
*/
21+
public function createResource(
22+
$instance,
23+
Metadata\AbstractMetadata $metadata,
24+
ResourceGenerator $resourceGenerator,
25+
ServerRequestInterface $request
26+
) : HalResource;
27+
}
28+
```
29+
30+
When you register a strategy, you will map a metadata type to the strategy; the
31+
`ResourceGenerator` will then call your strategy whenever it encounteres
32+
metadata of that type.
33+
34+
```php
35+
$resourceGenerator->addStrategy(CustomMetadata::class, CustomStrategy::class);
36+
37+
// or:
38+
$resourceGenerator->addStrategy(CustomMetadata::class, $strategyInstance);
39+
```
40+
41+
You can also add your strategies via the configuration:
42+
```php
43+
return [
44+
'zend-expressive-hal' => [
45+
'resource-generator' => [
46+
'strategies' => [
47+
CustomMetadata::class => CustomStrategy::class,
48+
],
49+
],
50+
],
51+
];
52+
```
53+
54+
If a strategy already is mapped for the given metadata type, this method will
55+
override it.
56+
57+
To facilitate common operations, this library provides two traits,
58+
`Zend\Expressive\Hal\ResourceGenerator\ExtractCollectionTrait` and
59+
`Zend\Expressive\Hal\ResourceGenerator\ExtractInstanceTrait`; inspect these if you
60+
decide to write your own strategies.
61+
62+
In order for the `MetadataMap` to be able to use your `CustomMetadata` you need to register
63+
a factory (implementing `Zend\Expressive\Hal\Metadata\MetadataFactoryInterface`) for it.
64+
You can register them via the configuration:
65+
```php
66+
return [
67+
'zend-expressive-hal' => [
68+
'metadata-factories' => [
69+
CustomMetadata::class => CustomMetadataFactory::class,
70+
],
71+
],
72+
];
73+
```

docs/book/resource-generator.md

Lines changed: 0 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -149,51 +149,3 @@ $resource = $resourceGenerator->fromObject($book, $request);
149149
(Where `$request` is a `Psr\Http\Message\ServerRequestInterface` instance; the
150150
instance is passed along to the `LinkGenerator` in order to generate route-based
151151
URIs for `Link` instances.)
152-
153-
### Customizing resource generation
154-
155-
The `ResourceGenerator` allows composing `Zend\Expressive\Hal\ResourceGenerator\StrategyInterface`
156-
instances. The `StrategyInterface` defines the following:
157-
158-
```php
159-
namespace Zend\Expressive\Hal\ResourceGenerator;
160-
161-
use Psr\Http\Message\ServerRequestInterface;
162-
use Zend\Expressive\Hal\HalResource;
163-
use Zend\Expressive\Hal\Metadata;
164-
use Zend\Expressive\Hal\ResourceGenerator;
165-
166-
interface StrategyInterface
167-
{
168-
/**
169-
* @param object $instance Instance from which to create Resource.
170-
* @throws Exception\UnexpectedMetadataTypeException for metadata types the
171-
* strategy cannot handle.
172-
*/
173-
public function createResource(
174-
$instance,
175-
Metadata\AbstractMetadata $metadata,
176-
ResourceGenerator $resourceGenerator,
177-
ServerRequestInterface $request
178-
) : HalResource;
179-
}
180-
```
181-
182-
When you register a strategy, you will map a metadata type to the strategy; the
183-
`ResourceGenerator` will then call your strategy whenever it encounteres
184-
metadata of that type.
185-
186-
```php
187-
$resourceGenerator->addStrategy(CustomMetadata::class, CustomStrategy::class);
188-
189-
// or:
190-
$resourceGenerator->addStrategy(CustomMetadata::class, $strategyInstance);
191-
```
192-
193-
If a strategy already is mapped for the given metadata type, this method will
194-
override it.
195-
196-
To facilitate common operations, this library provides two traits,
197-
`Zend\Expressive\Hal\ResourceGenerator\ExtractCollectionTrait` and
198-
`Zend\Expressive\Hal\ResourceGenerator\ExtractInstanceTrait`; inspect these if you
199-
decide to write your own strategies.

mkdocs.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ pages:
77
- "HAL": hal.md
88
- "Links and Resources": links-and-resources.md
99
- "Generating Resources": resource-generator.md
10+
- "Custom Resources": generating-custom-resources.md
1011
- "Representations": representations.md
1112
- "Factories": factories.md
1213
- Cookbook:

src/ConfigProvider.php

Lines changed: 53 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,27 +7,73 @@
77

88
namespace Zend\Expressive\Hal;
99

10+
use Zend\Expressive\Hal\LinkGenerator\ExpressiveUrlGenerator;
11+
use Zend\Expressive\Hal\LinkGenerator\UrlGeneratorInterface;
12+
use Zend\Expressive\Hal\Metadata\MetadataMap;
13+
use Zend\Expressive\Hal\Metadata\RouteBasedCollectionMetadata;
14+
use Zend\Expressive\Hal\Metadata\RouteBasedCollectionMetadataFactory;
15+
use Zend\Expressive\Hal\Metadata\RouteBasedResourceMetadata;
16+
use Zend\Expressive\Hal\Metadata\RouteBasedResourceMetadataFactory;
17+
use Zend\Expressive\Hal\Metadata\UrlBasedCollectionMetadata;
18+
use Zend\Expressive\Hal\Metadata\UrlBasedCollectionMetadataFactory;
19+
use Zend\Expressive\Hal\Metadata\UrlBasedResourceMetadata;
20+
use Zend\Expressive\Hal\Metadata\UrlBasedResourceMetadataFactory;
21+
use Zend\Expressive\Hal\ResourceGenerator\RouteBasedCollectionStrategy;
22+
use Zend\Expressive\Hal\ResourceGenerator\RouteBasedResourceStrategy;
23+
use Zend\Expressive\Hal\ResourceGenerator\UrlBasedCollectionStrategy;
24+
use Zend\Expressive\Hal\ResourceGenerator\UrlBasedResourceStrategy;
25+
1026
class ConfigProvider
1127
{
1228
public function __invoke() : array
1329
{
1430
return [
15-
'dependencies' => $this->getDependencies(),
31+
'dependencies' => $this->getDependencies(),
32+
'zend-expressive-hal' => $this->getHalConfig(),
1633
];
1734
}
1835

1936
public function getDependencies() : array
2037
{
2138
return [
2239
'aliases' => [
23-
LinkGenerator\UrlGeneratorInterface::class => LinkGenerator\ExpressiveUrlGenerator::class,
40+
UrlGeneratorInterface::class => LinkGenerator\ExpressiveUrlGenerator::class,
2441
],
2542
'factories' => [
26-
HalResponseFactory::class => HalResponseFactoryFactory::class,
27-
LinkGenerator::class => LinkGeneratorFactory::class,
28-
LinkGenerator\ExpressiveUrlGenerator::class => LinkGenerator\ExpressiveUrlGeneratorFactory::class,
29-
Metadata\MetadataMap::class => Metadata\MetadataMapFactory::class,
30-
ResourceGenerator::class => ResourceGeneratorFactory::class,
43+
HalResponseFactory::class => HalResponseFactoryFactory::class,
44+
LinkGenerator::class => LinkGeneratorFactory::class,
45+
ExpressiveUrlGenerator::class => LinkGenerator\ExpressiveUrlGeneratorFactory::class,
46+
MetadataMap::class => Metadata\MetadataMapFactory::class,
47+
ResourceGenerator::class => ResourceGeneratorFactory::class,
48+
],
49+
'invokables' => [
50+
RouteBasedCollectionStrategy::class => RouteBasedCollectionStrategy::class,
51+
RouteBasedResourceStrategy::class => RouteBasedResourceStrategy::class,
52+
53+
UrlBasedCollectionStrategy::class => UrlBasedCollectionStrategy::class,
54+
UrlBasedResourceStrategy::class => UrlBasedResourceStrategy::class
55+
],
56+
];
57+
}
58+
59+
public function getHalConfig() : array
60+
{
61+
return [
62+
'resource-generator' => [
63+
'strategies' => [ // The registered strategies and their metadata types
64+
RouteBasedCollectionMetadata::class => RouteBasedCollectionStrategy::class,
65+
RouteBasedResourceMetadata::class => RouteBasedResourceStrategy::class,
66+
67+
UrlBasedCollectionMetadata::class => UrlBasedCollectionStrategy::class,
68+
UrlBasedResourceMetadata::class => UrlBasedResourceStrategy::class,
69+
],
70+
],
71+
'metadata-factories' => [ // The factories for the metadata types
72+
RouteBasedCollectionMetadata::class => RouteBasedCollectionMetadataFactory::class,
73+
RouteBasedResourceMetadata::class => RouteBasedResourceMetadataFactory::class,
74+
75+
UrlBasedCollectionMetadata::class => UrlBasedCollectionMetadataFactory::class,
76+
UrlBasedResourceMetadata::class => UrlBasedResourceMetadataFactory::class,
3177
],
3278
];
3379
}

src/Metadata/Exception/InvalidConfigException.php

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
use RuntimeException;
1111
use Zend\Expressive\Hal\Metadata\AbstractMetadata;
12+
use Zend\Expressive\Hal\Metadata\MetadataFactoryInterface;
1213
use Zend\Expressive\Hal\Metadata\MetadataMap;
1314
use Zend\Expressive\Hal\Metadata\MetadataMapFactory;
1415

@@ -64,14 +65,22 @@ public static function dueToNonMetadataClass(string $class) : self
6465
));
6566
}
6667

67-
public static function dueToUnrecognizedMetadataClass(string $class, string $classWithoutNamespace) : self
68+
public static function dueToInvalidMetadataFactoryClass(string $class) : self
6869
{
6970
return new self(sprintf(
70-
'%s does not know how to construct a %s instance; please extend the '
71-
. 'factory and create a "create%s" method',
72-
MetadataMapFactory::class,
71+
'%s is not a valid metadata factory class; does not implement %s',
7372
$class,
74-
$classWithoutNamespace
73+
MetadataFactoryInterface::class
74+
));
75+
}
76+
77+
public static function dueToUnrecognizedMetadataClass(string $class) : self
78+
{
79+
return new self(sprintf(
80+
'%s does not know how to construct a %s instance; please provide a '
81+
. 'factory in your configuration',
82+
MetadataMapFactory::class,
83+
$class
7584
));
7685
}
7786

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
/**
3+
* @see https://github.com/zendframework/zend-expressive-hal for the canonical source repository
4+
* @copyright Copyright (c) 2017 Zend Technologies USA Inc. (http://www.zend.com)
5+
* @license https://github.com/zendframework/zend-expressive-hal/blob/master/LICENSE.md New BSD License
6+
*/
7+
8+
namespace Zend\Expressive\Hal\Metadata;
9+
10+
/**
11+
* Interface describing factories that create metadata instances.
12+
*/
13+
interface MetadataFactoryInterface
14+
{
15+
/**
16+
* Creates a Metadata based on the MetadataMap configuration.
17+
*
18+
* @param string $requestedName The requested name of the metadata type
19+
* @param array $metadata The metadata should have the following structure:
20+
* <code>
21+
* [
22+
* '__class__' => 'Fully qualified class name of an AbstractMetadata type',
23+
* // additional key/value pairs as required by the metadata type.
24+
* ]
25+
* </code>
26+
*
27+
* The '__class__' key decides which AbstractMetadata should be used
28+
* (and which corresponding factory will be called to create it).
29+
* @return AbstractMetadata
30+
*/
31+
public function createMetadata(string $requestedName, array $metadata) : AbstractMetadata;
32+
}

0 commit comments

Comments
 (0)