ENHANCEMENT Allowing multiple fragments to be returned by PjaxResponseNegotiator through JSON

This commit is contained in:
Ingo Schommer 2012-04-18 21:15:31 +02:00
parent cbf4ad3a75
commit 473eda43cb
2 changed files with 40 additions and 7 deletions

View File

@ -44,19 +44,36 @@ class PjaxResponseNegotiator {
array_change_key_case($this->callbacks, CASE_LOWER),
array_change_key_case($extraCallbacks, CASE_LOWER)
);
$response = new SS_HTTPResponse();
if($fragment = $request->getHeader('X-Pjax')) {
$fragment = strtolower($fragment);
if(isset($callbacks[$fragment])) {
return call_user_func($callbacks[$fragment]);
$responseParts = array();
if($fragmentStr = $request->getHeader('X-Pjax')) {
$fragments = explode(',', strtolower($fragmentStr));
foreach($fragments as $fragment) {
if(isset($callbacks[$fragment])) {
$responseParts[$fragment] = call_user_func($callbacks[$fragment]);
} else {
throw new SS_HTTPResponse_Exception("X-Pjax = '$fragment' not supported for this URL.", 400);
}
}
if(count($responseParts) == 1) {
$response->setBody(array_pop($responseParts));
} else {
throw new SS_HTTPResponse_Exception("X-Pjax = '$fragment' not supported for this URL.", 400);
if($request->getHeader('Accept') != 'text/json') {
throw new SS_HTTPResponse_Exception(
'Multiple comma-separated fragments can only be returne with an "Accept: text/json" header',
400
);
}
$response->setBody(Convert::raw2json($responseParts));
$response->addHeader('Content-Type', 'text/json');
}
} else {
if($request->isAjax()) throw new SS_HTTPResponse_Exception("Ajax requests to this URL require an X-Pjax header.", 400);
return call_user_func($callbacks['default']);
$response->setBody(call_user_func($callbacks['default']));
}
return $response;
}
/**

View File

@ -19,4 +19,20 @@ class PjaxResponseNegotiatorTest extends SapphireTest {
$this->assertEquals('myfragment response', $negotiator->respond($request));
}
function testMultipleFragments() {
$negotiator = new PjaxResponseNegotiator(array(
'default' => function() {return 'default response';},
'myfragment' => function() {return 'myfragment response';},
'otherfragment' => function() {return 'otherfragment response';},
));
$request = new SS_HTTPRequest('GET', '/');
$request->addHeader('X-Pjax', 'myfragment,otherfragment');
$request->addHeader('Accept', 'text/json');
$json = json_decode($negotiator->respond($request));
$this->assertObjectHasAttribute('myfragment', $json);
$this->assertEquals('myfragment response', $json->myfragment);
$this->assertObjectHasAttribute('otherfragment', $json);
$this->assertEquals('otherfragment response', $json->otherfragment);
}
}