Add content negociation provider

This commit is contained in:
Nicolas Le Goff
2014-06-03 11:16:20 +02:00
parent e17493aa0b
commit 45e53518ed
5 changed files with 49 additions and 78 deletions

View File

@@ -27,7 +27,6 @@ use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
return call_user_func(function ($environment = PhraseaApplication::ENV_PROD) {
$app = new PhraseaApplication($environment);
$app->loadPlugins();
@@ -40,6 +39,7 @@ return call_user_func(function ($environment = PhraseaApplication::ENV_PROD) {
return $monolog;
}));
// handle API content negotiation
$app->before(function(Request $request) use ($app) {
// register custom API format
$request->setFormat(\API_V1_result::FORMAT_JSON_EXTENDED, \API_V1_adapter::$extendedContentTypes['json']);
@@ -57,28 +57,30 @@ return call_user_func(function ($environment = PhraseaApplication::ENV_PROD) {
if (null === $format) {
$app->abort(406);
}
// set request format according to negociated content or override format with jsonp is callback parameter is defined
if (trim($request->query->get('callback')) !== '') {
$request->setRequestFormat('jsonp');
// set request format according to negotiated content or override format with JSONP if callback parameter is defined
if (trim($request->get('callback')) !== '') {
$request->setRequestFormat(\API_V1_result::FORMAT_JSONP);
} else {
$request->setRequestFormat($request->getFormat($format->getValue()));
}
// tells whether asked format is extended or not
$request->attributes->set('_extended', in_array(
$request->getRequestFormat('json'),
$request->getRequestFormat(\API_V1_result::FORMAT_JSON),
array(
\API_V1_result::FORMAT_JSON_EXTENDED,
\API_V1_result::FORMAT_YAML_EXTENDED,
\API_V1_result::FORMAT_JSONP_EXTENDED
)
));
});
}, PhraseaApplication::EARLY_EVENT);
$app->after(function(Request $request, Response $response) use ($app) {
if ($request->getRequestFormat(\API_V1_result::FORMAT_JSON) === \API_V1_result::FORMAT_JSONP && !$response->isOk() && !$response->isServerError()) {
$response->setStatusCode(200);
}
// set response content type
$response->headers->set('Content-Type', $request->getMimeType($request->getRequestFormat()));
$response->headers->set('Content-Type', $request->getMimeType($request->getRequestFormat(\API_V1_result::FORMAT_JSON)));
});
$app->register(new \API_V1_Timer());

View File

@@ -0,0 +1,37 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2014 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\Core\Provider;
use Silex\Application;
use Silex\ServiceProviderInterface;
class ContentNegociationServiceProvider implements ServiceProviderInterface
{
public function register(Application $app)
{
$app['negociator'] = $app->share(function ($app) {
return new \Negotiation\Negotiator();
});
$app['format.negociator'] = $app->share(function ($app) {
return new \Negotiation\FormatNegotiator();
});
$app['langage.negociator'] = $app->share(function ($app) {
return new \Negotiation\LanguageNegotiator();
});
}
public function boot(Application $app)
{
}
}

View File

@@ -44,9 +44,6 @@ class API_V1_result
/** @var mixed */
protected $response;
/** @var string */
protected $response_type;
/** Constant for response type json */
const FORMAT_JSON = 'json';
/** Constant for response type yaml */
@@ -153,7 +150,7 @@ class API_V1_result
$return_value = false;
switch ($this->request->getRequestFormat('json')) {
switch ($this->request->getRequestFormat(self::FORMAT_JSON)) {
case self::FORMAT_JSON:
case self::FORMAT_JSON_EXTENDED:
default:
@@ -296,12 +293,8 @@ class API_V1_result
*/
public function get_http_code()
{
if ($this->response_type == self::FORMAT_JSONP && $this->http_code !== 500) {
return 200;
} else {
return $this->http_code;
}
}
/**
*

View File

@@ -24,32 +24,26 @@ class API_V1_adapterTest extends PhraseanetPHPUnitAuthenticatedAbstract
$result = $this->object->get_error_code($request, 400);
$this->assertTrue(is_array(json_decode($result->format(), true)));
$this->assertEquals(400, $result->get_http_code());
$this->assertEquals('application/json', $result->get_content_type());
$result = $this->object->get_error_code($request, 403);
$this->assertTrue(is_array(json_decode($result->format(), true)));
$this->assertEquals(403, $result->get_http_code());
$this->assertEquals('application/json', $result->get_content_type());
$result = $this->object->get_error_code($request, 500);
$this->assertTrue(is_array(json_decode($result->format(), true)));
$this->assertEquals(500, $result->get_http_code());
$this->assertEquals('application/json', $result->get_content_type());
$result = $this->object->get_error_code($request, 405);
$this->assertTrue(is_array(json_decode($result->format(), true)));
$this->assertEquals(405, $result->get_http_code());
$this->assertEquals('application/json', $result->get_content_type());
$result = $this->object->get_error_code($request, 404);
$this->assertTrue(is_array(json_decode($result->format(), true)));
$this->assertEquals(404, $result->get_http_code());
$this->assertEquals('application/json', $result->get_content_type());
$result = $this->object->get_error_code($request, 401);
$this->assertTrue(is_array(json_decode($result->format(), true)));
$this->assertEquals(401, $result->get_http_code());
$this->assertEquals('application/json', $result->get_content_type());
}
public function testGet_error_message()
@@ -58,32 +52,26 @@ class API_V1_adapterTest extends PhraseanetPHPUnitAuthenticatedAbstract
$result = $this->object->get_error_message($request, API_V1_result::ERROR_BAD_REQUEST, 'detaillage');
$this->assertTrue(is_array(json_decode($result->format(), true)));
$this->assertEquals(400, $result->get_http_code());
$this->assertEquals('application/json', $result->get_content_type());
$result = $this->object->get_error_message($request, API_V1_result::ERROR_FORBIDDEN, 'detaillage');
$this->assertTrue(is_array(json_decode($result->format(), true)));
$this->assertEquals(403, $result->get_http_code());
$this->assertEquals('application/json', $result->get_content_type());
$result = $this->object->get_error_message($request, API_V1_result::ERROR_INTERNALSERVERERROR, 'detaillage');
$this->assertTrue(is_array(json_decode($result->format(), true)));
$this->assertEquals(500, $result->get_http_code());
$this->assertEquals('application/json', $result->get_content_type());
$result = $this->object->get_error_message($request, API_V1_result::ERROR_METHODNOTALLOWED, 'detaillage');
$this->assertTrue(is_array(json_decode($result->format(), true)));
$this->assertEquals(405, $result->get_http_code());
$this->assertEquals('application/json', $result->get_content_type());
$result = $this->object->get_error_message($request, API_V1_result::ERROR_NOTFOUND, 'detaillage');
$this->assertTrue(is_array(json_decode($result->format(), true)));
$this->assertEquals(404, $result->get_http_code());
$this->assertEquals('application/json', $result->get_content_type());
$result = $this->object->get_error_message($request, API_V1_result::ERROR_UNAUTHORIZED, 'detaillage');
$this->assertTrue(is_array(json_decode($result->format(), true)));
$this->assertEquals(401, $result->get_http_code());
$this->assertEquals('application/json', $result->get_content_type());
}
public function testGet_version()
@@ -96,7 +84,6 @@ class API_V1_adapterTest extends PhraseanetPHPUnitAuthenticatedAbstract
$request = new Request(array(), array(), array(), array(), array(), array('HTTP_Accept' => 'application/json'));
$result = $this->object->get_databoxes($request);
$this->assertEquals(200, $result->get_http_code());
$this->assertEquals('application/json', $result->get_content_type());
$this->assertTrue(is_array(json_decode($result->format(), true)));
}
@@ -106,7 +93,6 @@ class API_V1_adapterTest extends PhraseanetPHPUnitAuthenticatedAbstract
foreach (self::$DI['app']['phraseanet.appbox']->get_databoxes() as $databox) {
$result = $this->object->get_databox_collections($request, $databox->get_sbas_id());
$this->assertEquals(200, $result->get_http_code());
$this->assertEquals('application/json', $result->get_content_type());
$this->assertTrue(is_array(json_decode($result->format(), true)));
}
}
@@ -121,7 +107,6 @@ class API_V1_adapterTest extends PhraseanetPHPUnitAuthenticatedAbstract
$request = new Request(array(), array(), array(), array(), array(), array('HTTP_Accept' => 'application/json'));
$result = $this->object->get_record($request, self::$DI['record_1']->get_sbas_id(), self::$DI['record_1']->get_record_id());
$this->assertEquals(200, $result->get_http_code());
$this->assertEquals('application/json', $result->get_content_type());
$this->assertTrue(is_array(json_decode($result->format(), true)));
}
@@ -131,7 +116,6 @@ class API_V1_adapterTest extends PhraseanetPHPUnitAuthenticatedAbstract
foreach (self::$DI['app']['phraseanet.appbox']->get_databoxes() as $databox) {
$result = $this->object->get_databox_status($request, $databox->get_sbas_id());
$this->assertEquals(200, $result->get_http_code());
$this->assertEquals('application/json', $result->get_content_type());
$this->assertTrue(is_array(json_decode($result->format(), true)));
}
}
@@ -142,7 +126,6 @@ class API_V1_adapterTest extends PhraseanetPHPUnitAuthenticatedAbstract
foreach (self::$DI['app']['phraseanet.appbox']->get_databoxes() as $databox) {
$result = $this->object->get_databox_metadatas($request, $databox->get_sbas_id());
$this->assertEquals(200, $result->get_http_code());
$this->assertEquals('application/json', $result->get_content_type());
$this->assertTrue(is_array(json_decode($result->format(), true)));
}
}
@@ -153,7 +136,6 @@ class API_V1_adapterTest extends PhraseanetPHPUnitAuthenticatedAbstract
foreach (self::$DI['app']['phraseanet.appbox']->get_databoxes() as $databox) {
$result = $this->object->get_databox_terms($request, $databox->get_sbas_id());
$this->assertEquals(200, $result->get_http_code());
$this->assertEquals('application/json', $result->get_content_type());
$this->assertTrue(is_array(json_decode($result->format(), true)));
}
}
@@ -167,7 +149,6 @@ class API_V1_adapterTest extends PhraseanetPHPUnitAuthenticatedAbstract
$request = new Request(array('record_type' => "image", 'search_type' => 0), array(), array(), array(), array(), array('HTTP_Accept' => 'application/json'));
$result = $this->object->search_records($request);
$this->assertEquals(200, $result->get_http_code());
$this->assertEquals('application/json', $result->get_content_type());
$this->assertTrue(is_array(json_decode($result->format(), true)));
$data = json_decode($result->format(), true);
@@ -190,7 +171,6 @@ class API_V1_adapterTest extends PhraseanetPHPUnitAuthenticatedAbstract
$request = new Request(array(), array(), array(), array(), array(), array('HTTP_Accept' => 'application/json'));
$result = $this->object->search_records($request);
$this->assertEquals(200, $result->get_http_code());
$this->assertEquals('application/json', $result->get_content_type());
$this->assertTrue(is_array(json_decode($result->format(), true)));
$data = json_decode($result->format(), true);
@@ -251,7 +231,6 @@ class API_V1_adapterTest extends PhraseanetPHPUnitAuthenticatedAbstract
$request = new Request(array('search_type' => 1), array(), array(), array(), array(), array('HTTP_Accept' => 'application/json'));
$result = $this->object->search_records($request);
$this->assertEquals(200, $result->get_http_code());
$this->assertEquals('application/json', $result->get_content_type());
$this->assertTrue(is_array(json_decode($result->format(), true)));
$data = json_decode($result->format(), true);
@@ -283,7 +262,6 @@ class API_V1_adapterTest extends PhraseanetPHPUnitAuthenticatedAbstract
$request = new Request(array('search_type' => 1), array(), array(), array(), array(), array('HTTP_Accept' => 'application/json'));
$result = $this->object->search($request);
$this->assertEquals(200, $result->get_http_code());
$this->assertEquals('application/json', $result->get_content_type());
$this->assertTrue(is_array(json_decode($result->format(), true)));
$data = json_decode($result->format(), true);
@@ -314,7 +292,6 @@ class API_V1_adapterTest extends PhraseanetPHPUnitAuthenticatedAbstract
$request = new Request(array('search_type' => 0), array(), array(), array(), array(), array('HTTP_Accept' => 'application/json'));
$result = $this->object->search($request);
$this->assertEquals(200, $result->get_http_code());
$this->assertEquals('application/json', $result->get_content_type());
$this->assertTrue(is_array(json_decode($result->format(), true)));
$data = json_decode($result->format(), true);
@@ -353,7 +330,6 @@ class API_V1_adapterTest extends PhraseanetPHPUnitAuthenticatedAbstract
$request = new Request(array(), array(), array(), array(), array(), array('HTTP_Accept' => 'application/json'));
$result = $this->object->get_record_related($request, self::$DI['record_1']->get_sbas_id(), self::$DI['record_1']->get_record_id());
$this->assertEquals(200, $result->get_http_code());
$this->assertEquals('application/json', $result->get_content_type());
$this->assertTrue(is_array(json_decode($result->format(), true)));
$data = json_decode($result->format(), true);
@@ -392,7 +368,6 @@ class API_V1_adapterTest extends PhraseanetPHPUnitAuthenticatedAbstract
$request = new Request(array(), array(), array(), array(), array(), array('HTTP_Accept' => 'application/json'));
$result = $this->object->get_record_metadatas($request, self::$DI['record_1']->get_sbas_id(), self::$DI['record_1']->get_record_id());
$this->assertEquals(200, $result->get_http_code());
$this->assertEquals('application/json', $result->get_content_type());
$this->assertTrue(is_array(json_decode($result->format(), true)));
}
@@ -403,7 +378,6 @@ class API_V1_adapterTest extends PhraseanetPHPUnitAuthenticatedAbstract
$request = new Request(array(), array(), array(), array(), array(), array('HTTP_Accept' => 'application/json'));
$result = $this->object->get_record_status($request, self::$DI['record_1']->get_sbas_id(), self::$DI['record_1']->get_record_id());
$this->assertEquals(200, $result->get_http_code());
$this->assertEquals('application/json', $result->get_content_type());
$this->assertTrue(is_array(json_decode($result->format(), true)));
}
@@ -413,7 +387,6 @@ class API_V1_adapterTest extends PhraseanetPHPUnitAuthenticatedAbstract
$request = new Request(array(), array(), array(), array(), array(), array('HTTP_Accept' => 'application/json'));
$result = $this->object->get_record_embed($request, self::$DI['record_1']->get_sbas_id(), self::$DI['record_1']->get_record_id());
$this->assertEquals(200, $result->get_http_code());
$this->assertEquals('application/json', $result->get_content_type());
$this->assertTrue(is_array(json_decode($result->format(), true)));
}
@@ -540,7 +513,6 @@ class API_V1_adapterTest extends PhraseanetPHPUnitAuthenticatedAbstract
$request = new Request(array(), array(), array(), array(), array(), array('HTTP_Accept' => 'application/json'));
$result = $this->object->search_baskets($request);
$this->assertEquals(200, $result->get_http_code());
$this->assertEquals('application/json', $result->get_content_type());
$this->assertTrue(is_array(json_decode($result->format(), true)));
}
@@ -549,7 +521,6 @@ class API_V1_adapterTest extends PhraseanetPHPUnitAuthenticatedAbstract
$request = new Request(array(), array(), array('name' => 'BIG BASKET'), array(), array(), array('HTTP_Accept' => 'application/json'));
$result = $this->object->create_basket($request);
$this->assertEquals(200, $result->get_http_code());
$this->assertEquals('application/json', $result->get_content_type());
$this->assertTrue(is_array(json_decode($result->format(), true)));
$n = 0;
@@ -586,7 +557,6 @@ class API_V1_adapterTest extends PhraseanetPHPUnitAuthenticatedAbstract
$request = new Request(array(), array(), array(), array(), array(), array('HTTP_Accept' => 'application/json'));
$result = $this->object->delete_basket($request, $ssel_id);
$this->assertEquals(200, $result->get_http_code());
$this->assertEquals('application/json', $result->get_content_type());
$this->assertTrue(is_array(json_decode($result->format(), true)));
$repo = $em->getRepository('\Entities\Basket');
@@ -608,7 +578,6 @@ class API_V1_adapterTest extends PhraseanetPHPUnitAuthenticatedAbstract
$request = new Request(array(), array(), array(), array(), array(), array('HTTP_Accept' => 'application/json'));
$result = $this->object->get_basket($request, $basket->getId());
$this->assertEquals(200, $result->get_http_code());
$this->assertEquals('application/json', $result->get_content_type());
$this->assertTrue(is_array(json_decode($result->format(), true)));
}
@@ -621,7 +590,6 @@ class API_V1_adapterTest extends PhraseanetPHPUnitAuthenticatedAbstract
$request = new Request(array(), array(), array('name' => 'PROUTO'), array(), array(), array('HTTP_Accept' => 'application/json'));
$result = $this->object->set_basket_title($request, $basket->getId());
$this->assertEquals(200, $result->get_http_code());
$this->assertEquals('application/json', $result->get_content_type());
$this->assertTrue(is_array(json_decode($result->format(), true)));
$repository = self::$DI['app']['EM']->getRepository('\Entities\Basket');
@@ -640,7 +608,6 @@ class API_V1_adapterTest extends PhraseanetPHPUnitAuthenticatedAbstract
$request = new Request(array(), array(), array('description' => 'une belle description'), array(), array(), array('HTTP_Accept' => 'application/json'));
$result = $this->object->set_basket_description($request, $basket->getId());
$this->assertEquals(200, $result->get_http_code());
$this->assertEquals('application/json', $result->get_content_type());
$this->assertTrue(is_array(json_decode($result->format(), true)));
$repository = self::$DI['app']['EM']->getRepository('\Entities\Basket');

View File

@@ -242,34 +242,6 @@ class API_V1_resultTest extends PhraseanetPHPUnitAuthenticatedAbstract
$this->assertEquals($expected_value, $response->response->$field);
}
public function testGet_content_type()
{
$server = array("HTTP_ACCEPT" => "application/json");
$request = new Request(array("callback" => ""), array(), array(), array(), array(), $server);
$api_result = new API_V1_result(self::$DI['app'], $request, $this->api);
$this->assertEquals("application/json", $api_result->get_content_type());
$server = array("HTTP_ACCEPT" => "application/yaml");
$request = new Request(array("callback" => ""), array(), array(), array(), array(), $server);
$api_result = new API_V1_result(self::$DI['app'], $request, $this->api);
$this->assertEquals('application/yaml', $api_result->get_content_type());
$server = array("HTTP_ACCEPT" => "text/yaml");
$request = new Request(array("callback" => ""), array(), array(), array(), array(), $server);
$api_result = new API_V1_result(self::$DI['app'], $request, $this->api);
$this->assertEquals('application/yaml', $api_result->get_content_type());
$server = array("HTTP_ACCEPT" => "");
$request = new Request(array("callback" => "hello"), array(), array(), array(), array(), $server);
$api_result = new API_V1_result(self::$DI['app'], $request, $this->api);
$this->assertEquals('text/javascript', $api_result->get_content_type());
$server = array("HTTP_ACCEPT" => "unknow");
$request = new Request(array("callback" => ""), array(), array(), array(), array(), $server);
$api_result = new API_V1_result(self::$DI['app'], $request, $this->api);
$this->assertEquals("application/json", $api_result->get_content_type());
}
/**
* @depends testFormatJson
*/