Skip to content
Permalink
Browse files

Replace IDecorator interface, make tags optional

  • Loading branch information...
mabar authored and f3l1x committed Feb 25, 2019
1 parent 0a1848d commit ddef7bf0bc80e327fed2354e6eca308b8806a572
Showing with 47 additions and 45 deletions.
  1. +2 −2 phpstan.neon
  2. +18 −31 src/DI/NegotiationPlugin.php
  3. +27 −12 src/Decorator/ResponseEntityDecorator.php
@@ -12,5 +12,5 @@ parameters:
# Better not to solve that
- '#^Only booleans are allowed in a negated boolean, int given\.$#'

# Phpstan bug
- '#^Parameter \#1 \$request of method Apitte\\Negotiation\\ContentNegotiation\:\:negotiate\(\) expects Apitte\\Core\\Http\\ApiRequest, Psr\\Http\\Message\\ServerRequestInterface given\.$#'
# Maybe later - complicated to fix
- '#^.*should be contravariant with parameter.*$#'
@@ -2,7 +2,6 @@
namespace Apitte\Negotiation\DI;
use Apitte\Core\Decorator\IDecorator;
use Apitte\Core\DI\ApiExtension;
use Apitte\Core\DI\Helpers;
use Apitte\Core\DI\Plugin\AbstractPlugin;
@@ -13,8 +12,10 @@
use Apitte\Negotiation\Decorator\ResponseEntityDecorator;
use Apitte\Negotiation\DefaultNegotiator;
use Apitte\Negotiation\FallbackNegotiator;
use Apitte\Negotiation\INegotiator;
use Apitte\Negotiation\SuffixNegotiator;
use Apitte\Negotiation\Transformer\CsvTransformer;
use Apitte\Negotiation\Transformer\ITransformer;
use Apitte\Negotiation\Transformer\JsonTransformer;
use Apitte\Negotiation\Transformer\JsonUnifyTransformer;
use Apitte\Negotiation\Transformer\RendererTransformer;
@@ -89,7 +90,7 @@ public function loadPluginConfiguration(): void
$builder->addDefinition($this->prefix('decorator.response'))
->setFactory(ResponseEntityDecorator::class)
->addTag(ApiExtension::CORE_DECORATOR_TAG, ['priority' => 500, 'type' => [IDecorator::ON_HANDLER_AFTER, IDecorator::ON_DISPATCHER_EXCEPTION]]);
->addTag(ApiExtension::CORE_DECORATOR_TAG, ['priority' => 500]);
if ($config['unification'] === true) {
$builder->removeDefinition($this->prefix('transformer.fallback'));
@@ -113,62 +114,48 @@ public function loadPluginConfiguration(): void
*/
public function beforePluginCompile(): void
{
$this->compileTaggedNegotiators();
$this->compileTaggedTransformers();
$this->compileNegotiators();
$this->compileTransformers();
}
protected function compileTaggedNegotiators(): void
protected function compileNegotiators(): void
{
$builder = $this->getContainerBuilder();
// Find all definitions by tag
$definitions = $builder->findByTag(ApiExtension::NEGOTIATION_NEGOTIATOR_TAG);
// Ensure we have at least 1 service
if ($definitions === []) {
throw new InvalidStateException(sprintf('No services with tag "%s"', ApiExtension::NEGOTIATION_NEGOTIATOR_TAG));
}
$definitions = $builder->findByType(INegotiator::class);
// Sort by priority
$definitions = Helpers::sort($definitions);
// Find all services by names
$negotiators = Helpers::getDefinitions($definitions, $builder);
// Obtain negotiation
$negotiation = $builder->getDefinition($this->prefix('negotiation'));
$definitions = Helpers::sortByPriorityInTag(ApiExtension::NEGOTIATION_NEGOTIATOR_TAG, $definitions);
// Set services as argument
$negotiation->setArguments([$negotiators]);
// Setup negotiators
$builder->getDefinition($this->prefix('negotiation'))
->setArguments([$definitions]);
}
protected function compileTaggedTransformers(): void
protected function compileTransformers(): void
{
$builder = $this->getContainerBuilder();
// Find all definitions by tag
$definitions = $builder->findByTag(ApiExtension::NEGOTIATION_TRANSFORMER_TAG);
// Ensure we have at least 1 service
if ($definitions === []) {
throw new InvalidStateException(sprintf('No services with tag "%s"', ApiExtension::NEGOTIATION_TRANSFORMER_TAG));
}
$definitions = $builder->findByType(ITransformer::class);
// Init temporary array for services
$transformers = [
'suffix' => [],
'fallback' => null,
];
// Find all services by names
foreach ($definitions as $name => $tag) {
foreach ($definitions as $definition) {
$tag = $definition->getTag(ApiExtension::NEGOTIATION_TRANSFORMER_TAG);
if (isset($tag['suffix'])) {
// Find suffix transformer service
$transformers['suffix'][$tag['suffix']] = $builder->getDefinition($name);
$transformers['suffix'][$tag['suffix']] = $definition;
}
if (isset($tag['fallback'])) {
$transformers['fallback'] = $builder->getDefinition($name);
$transformers['fallback'] = $definition;
}
}
@@ -2,14 +2,16 @@
namespace Apitte\Negotiation\Decorator;
use Apitte\Core\Decorator\IDecorator;
use Apitte\Core\Decorator\IErrorDecorator;
use Apitte\Core\Decorator\IResponseDecorator;
use Apitte\Core\Http\ApiRequest;
use Apitte\Core\Http\ApiResponse;
use Apitte\Negotiation\ContentNegotiation;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Throwable;
class ResponseEntityDecorator implements IDecorator
class ResponseEntityDecorator implements IResponseDecorator, IErrorDecorator
{
/** @var ContentNegotiation */
@@ -21,21 +23,34 @@ public function __construct(ContentNegotiation $negotiation)
}
/**
* @param ApiRequest|ServerRequestInterface $request
* @param ApiResponse|ResponseInterface $response
* @param mixed[] $context
* @param ApiRequest $request
*/
public function decorate(ServerRequestInterface $request, ResponseInterface $response, array $context = []): ResponseInterface
public function decorateError(ServerRequestInterface $request, ResponseInterface $response, Throwable $error): ResponseInterface
{
// Skip if response is not our ApiResponse
if (!($response instanceof ApiResponse)) return $response;
if (!($response instanceof ApiResponse)) {
return $response;
}
// Skip if there's no entity and no $context, it does not make sence
// to negotiate response without entity.
// Except if there's exception in $context.
if ($response->getEntity() === null && $context === []) return $response;
return $this->negotiation->negotiate($request, $response, ['exception' => $error]);
}
/**
* @param ApiRequest $request
*/
public function decorateResponse(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface
{
// Skip if response is not our ApiResponse
if (!($response instanceof ApiResponse)) {
return $response;
}
// Cannot negotiate response without entity
if ($response->getEntity() === null) {
return $response;
}
return $this->negotiation->negotiate($request, $response, $context);
return $this->negotiation->negotiate($request, $response);
}
}

0 comments on commit ddef7bf

Please sign in to comment.
You can’t perform that action at this time.