diff --git a/lib/Alchemy/Phrasea/Application/Api.php b/lib/Alchemy/Phrasea/Application/Api.php index cdd0f3c747..86ecc21fa3 100644 --- a/lib/Alchemy/Phrasea/Application/Api.php +++ b/lib/Alchemy/Phrasea/Application/Api.php @@ -52,6 +52,12 @@ return call_user_func(function ($environment = PhraseaApplication::ENV_PROD) { return $monolog; })); + $app['phraseanet.content-negotiation.priorities'] = array_merge( + ['application/json', 'application/yaml', 'text/yaml', 'text/javascript', 'application/javascript'], + V1::$extendedContentTypes['json'], + V1::$extendedContentTypes['yaml'] + ); + // handle API content negotiation $app->before(function(Request $request) use ($app) { // register custom API format @@ -60,24 +66,9 @@ return call_user_func(function ($environment = PhraseaApplication::ENV_PROD) { $request->setFormat(Result::FORMAT_JSONP_EXTENDED, V1::$extendedContentTypes['jsonp']); $request->setFormat(Result::FORMAT_JSONP, array('text/javascript', 'application/javascript')); - $format = $app['negotiator']->getBest( - $request->headers->get('accept', 'application/json'), - array_merge( - ['application/json', 'application/yaml', 'text/yaml', 'text/javascript', 'application/javascript'], - V1::$extendedContentTypes['json'], - V1::$extendedContentTypes['yaml'] - ) - ); - - // throw unacceptable http error if API can not handle asked format - if (null === $format) { - $app->abort(406); - } // set request format according to negotiated content or override format with JSONP if callback parameter is defined if (trim($request->get('callback')) !== '') { $request->setRequestFormat(Result::FORMAT_JSONP); - } else { - $request->setRequestFormat($request->getFormat($format->getValue())); } // tells whether asked format is extended or not diff --git a/lib/Alchemy/Phrasea/Core/Event/Subscriber/ContentNegotiationSubscriber.php b/lib/Alchemy/Phrasea/Core/Event/Subscriber/ContentNegotiationSubscriber.php index d79d02d2d7..8350e37c03 100644 --- a/lib/Alchemy/Phrasea/Core/Event/Subscriber/ContentNegotiationSubscriber.php +++ b/lib/Alchemy/Phrasea/Core/Event/Subscriber/ContentNegotiationSubscriber.php @@ -11,18 +11,25 @@ namespace Alchemy\Phrasea\Core\Event\Subscriber; -use Alchemy\Phrasea\Application; +use Negotiation\Accept; +use Negotiation\Negotiator; +use Silex\Application; +use Symfony\Component\HttpKernel\Exception\HttpException; use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpKernel\Event\GetResponseEvent; class ContentNegotiationSubscriber implements EventSubscriberInterface { - private $app; + /** @var Negotiator */ + private $negotiator; + /** @var array */ + private $priorities; - public function __construct(Application $app) + public function __construct(Negotiator $negotiator, array $priorities) { - $this->app = $app; + $this->negotiator = $negotiator; + $this->priorities = $priorities; } public static function getSubscribedEvents() @@ -34,11 +41,10 @@ class ContentNegotiationSubscriber implements EventSubscriberInterface public function onKernelRequest(GetResponseEvent $event) { - $priorities = array('text/html', 'application/vnd.phraseanet.record-extended+json', 'application/json'); - $format = $this->app['negotiator']->getBest($event->getRequest()->headers->get('accept', '*/*'), $priorities); + $format = $this->negotiator->getBest($event->getRequest()->headers->get('accept', '*/*'), $this->priorities); - if (null === $format) { - $this->app->abort(406, 'Not acceptable'); + if (!$format instanceof Accept) { + throw new HttpException(406); } $event->getRequest()->setRequestFormat($event->getRequest()->getFormat($format->getValue())); diff --git a/lib/Alchemy/Phrasea/Core/Provider/PhraseaEventServiceProvider.php b/lib/Alchemy/Phrasea/Core/Provider/PhraseaEventServiceProvider.php index ba556228e9..7b1f5c4f84 100644 --- a/lib/Alchemy/Phrasea/Core/Provider/PhraseaEventServiceProvider.php +++ b/lib/Alchemy/Phrasea/Core/Provider/PhraseaEventServiceProvider.php @@ -40,8 +40,15 @@ class PhraseaEventServiceProvider implements ServiceProviderInterface $app['phraseanet.session-manager-subscriber'] = $app->share(function (Application $app) { return new SessionManagerSubscriber($app); }); + $app['phraseanet.content-negotiation.priorities'] = [ + 'text/html', + 'application/json', + ]; $app['phraseanet.content-negotiation-subscriber'] = $app->share(function (Application $app) { - return new ContentNegotiationSubscriber($app); + return new ContentNegotiationSubscriber( + $app['negotiator'], + $app['phraseanet.content-negotiation.priorities'] + ); }); $app['phraseanet.record-edit-subscriber'] = $app->share(function (Application $app) { return new RecordEditSubscriber(); diff --git a/tests/Alchemy/Tests/Phrasea/Core/Event/Subscriber/ContentNegotiationSubscriberTest.php b/tests/Alchemy/Tests/Phrasea/Core/Event/Subscriber/ContentNegotiationSubscriberTest.php index fa8f99fbc2..b703046dee 100644 --- a/tests/Alchemy/Tests/Phrasea/Core/Event/Subscriber/ContentNegotiationSubscriberTest.php +++ b/tests/Alchemy/Tests/Phrasea/Core/Event/Subscriber/ContentNegotiationSubscriberTest.php @@ -31,7 +31,7 @@ class ContentNegotiationSubscriberTest extends \PHPUnit_Framework_TestCase private function request($accept) { $app = new Application(Application::ENV_TEST); - $app['dispatcher']->addSubscriber(new ContentNegotiationSubscriber($app)); + $app['dispatcher']->addSubscriber(new ContentNegotiationSubscriber($app['negotiator'], $app['phraseanet.content-negotiation.priorities'])); $app->get('/content/negociation', function () { return ''; });