Merge branch 'pjax-set-fragments' of https://github.com/mateusz/sapphire into mateusz-pjax-set-fragments

This commit is contained in:
Ingo Schommer 2012-06-13 10:28:25 +02:00
commit 8ecdd0b082
2 changed files with 60 additions and 11 deletions

View File

@ -22,6 +22,11 @@ class PjaxResponseNegotiator {
protected $response = null;
/**
* Overriden fragments (if any). Otherwise uses fragments from the request.
*/
protected $fragmentOverride = null;
/**
* @param RequestHandler $controller
* @param SS_HTTPResponse An existing response to reuse (optional)
@ -49,6 +54,7 @@ class PjaxResponseNegotiator {
* @param array $extraCallbacks List of anonymous functions or callables returning either a string
* or SS_HTTPResponse, keyed by their fragment identifier. The 'default' key can
* be used as a fallback for non-ajax responses.
* @param array $fragmentOverride Change the response fragments.
* @return SS_HTTPResponse
*/
public function respond(SS_HTTPRequest $request, $extraCallbacks = array()) {
@ -57,21 +63,28 @@ class PjaxResponseNegotiator {
$response = $this->getResponse();
$responseParts = array();
if($fragmentStr = $request->getHeader('X-Pjax')) {
if (isset($this->fragmentOverride)) {
$fragments = $this->fragmentOverride;
} elseif ($fragmentStr = $request->getHeader('X-Pjax')) {
$fragments = explode(',', $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);
}
}
$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);
$response->setBody(call_user_func($callbacks['default']));
return $response;
}
// Execute the fragment callbacks and build the response.
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);
}
}
$response->setBody(Convert::raw2json($responseParts));
$response->addHeader('Content-Type', 'text/json');
return $response;
}
@ -82,4 +95,24 @@ class PjaxResponseNegotiator {
public function setCallback($fragment, $callback) {
$this->callbacks[$fragment] = $callback;
}
/**
* Set up fragment overriding - will completely replace the incoming fragments.
*
* @param array $fragments Fragments to insert.
*/
public function setFragmentOverride($fragments) {
if (!is_array($fragments)) throw new InvalidArgumentException();
$this->fragmentOverride = $fragments;
return $this;
}
/**
* @return array
*/
public function getFragmentOverride() {
return $this->fragmentOverride;
}
}

View File

@ -38,4 +38,20 @@ class PjaxResponseNegotiatorTest extends SapphireTest {
$this->assertEquals('otherfragment response', $json->otherfragment);
}
}
function testFragmentsOverride() {
$negotiator = new PjaxResponseNegotiator(array(
'alpha' => function() {return 'alpha response';},
'beta' => function() {return 'beta response';}
));
$request = new SS_HTTPRequest('GET', '/');
$request->addHeader('X-Pjax', 'alpha');
$request->addHeader('Accept', 'text/json');
$response = $negotiator->setFragmentOverride(array('beta'))->respond($request);
$json = json_decode( $response->getBody());
$this->assertFalse(isset($json->alpha));
$this->assertObjectHasAttribute('beta', $json);
}
}