Created
January 11, 2011 10:16
-
-
Save jaytaph/774267 to your computer and use it in GitHub Desktop.
Gists for blogpost
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[production] | |
settings.context.formats = "xml,json" | |
[staging : production] | |
[testing : staging] | |
settings.context.formats = "xml,json,html" | |
[development : testing] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class Service_Controller_Action_Helper_RestContextSwitch extends Zend_Controller_Action_Helper_ContextSwitch | |
{ | |
public function getActionContexts($action = null) | |
{ | |
// All actions point back to the global action, or return the complete list of actions | |
return parent::getActionContexts($action ? 'global' : null); | |
} | |
// Every action has context | |
public function hasActionContext($action, $context) | |
{ | |
return true; | |
} | |
// It's not possible to add specific action contexts | |
public function addActionContext($action, $context) | |
{ | |
// You cannot add context to actions | |
throw new Zend_Controller_Action_Exception('You must call addGlobalContext() instead of addActionContext()'); | |
} | |
// Add global context, this will trigger for ALL actions found | |
public function addGlobalContext($contexts) | |
{ | |
return parent::addActionContext('global', $contexts); | |
} | |
// This is almosts an exact 1:1 copy of the Zend_Controller_Action_Helper_ContextSwitch::initContext(). | |
// We just need to modify 2 or 3 lines inside. | |
public function initContext($format = null) | |
{ | |
$this->_currentContext = null; | |
$controller = $this->getActionController(); | |
$request = $this->getRequest(); | |
$action = $request->getActionName(); | |
// Return if no context switching enabled, or no context switching | |
// enabled for this action | |
$contexts = $this->getActionContexts($action); | |
if (empty($contexts)) { | |
return; | |
} | |
// Return if no context parameter provided | |
if (!$context = $request->getParam($this->getContextParam())) { | |
if ($format === null) { | |
return; | |
} | |
$context = $format; | |
$format = null; | |
} | |
// Check if context allowed by action controller | |
if (!$this->hasActionContext($action, $context)) { | |
return; | |
} | |
// Return if invalid context parameter provided and no format or invalid | |
// format provided | |
if (!$this->hasContext($context)) { | |
$context = $this->getDefaultContext(); | |
} | |
// Use provided format if passed | |
if (!empty($format) && $this->hasContext($format)) { | |
$context = $format; | |
} | |
$suffix = $this->getSuffix($context); | |
$this->_getViewRenderer()->setViewSuffix($suffix); | |
$headers = $this->getHeaders($context); | |
if (!empty($headers)) { | |
$response = $this->getResponse(); | |
foreach ($headers as $header => $content) { | |
$response->setHeader($header, $content); | |
} | |
} | |
if ($this->getAutoDisableLayout()) { | |
/** | |
* @see Zend_Layout | |
*/ | |
// require_once 'Zend/Layout.php'; | |
$layout = Zend_Layout::getMvcInstance(); | |
if (null !== $layout) { | |
$layout->disableLayout(); | |
} | |
} | |
if (null !== ($callback = $this->getCallback($context, self::TRIGGER_INIT))) { | |
if (is_string($callback) && method_exists($this, $callback)) { | |
$this->$callback(); | |
} | |
else if (is_string($callback) && function_exists($callback)) | |
{ | |
$callback(); | |
} | |
else if (is_array($callback)) | |
{ | |
call_user_func($callback); | |
} | |
else | |
{ | |
/** | |
* @see Zend_Controller_Action_Exception | |
*/ | |
// require_once 'Zend/Controller/Action/Exception.php'; | |
throw new Zend_Controller_Action_Exception( | |
sprintf('Invalid context callback registered for context "%s"', $context)); | |
} | |
} | |
$this->_currentContext = $context; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class Service_Controller_Plugin_AcceptHandler extends Zend_Controller_Plugin_Abstract | |
{ | |
public function routeShutdown (Zend_Controller_Request_Abstract $request) | |
{ | |
// Skip header check when we don't have a HTTP request (for instance: cli-scripts) | |
if (! $request instanceof Zend_Controller_Request_Http) { | |
return; | |
} | |
$this->getResponse()->setHeader('Vary', 'Accept'); | |
// Get the Accept header | |
$header = $request->getHeader('Accept'); | |
switch (true) { | |
// Depending on the value, set the correct format | |
case (strstr($header, HTTP_HEADER_APPLICATION_TYPE.'+json')) : | |
$request->setParam('format', 'json'); | |
break; | |
case (strstr($header, HTTP_HEADER_APPLICATION_TYPE.'+xml')) : | |
$request->setParam('format', 'xml'); | |
break; | |
case (strstr($header, HTTP_HEADER_APPLICATION_TYPE.'+html')) : | |
$request->setParam('format', 'html'); | |
break; | |
default: | |
// Default: return whatever is default, but only when the format is not set | |
$format = $request->getParam('format'); | |
if (! isset ($format)) { | |
/* Format is not found, so we use HTML. Used so we don't need to specify | |
* a format when checking the REST server at the browser */ | |
$request->setParam('format', 'html'); | |
} | |
break; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class Service_Controller_Plugin_Mediaformat extends Zend_Controller_Plugin_Abstract | |
{ | |
public function routeShutdown(Zend_Controller_Request_Abstract $request) | |
{ | |
$config = Zend_Config::getConfig(); | |
// Check if format is valid | |
$format = $request->getParam('format'); | |
if (! in_array($format, explode(',', $config->settings->context->formats))) { | |
// Trigger a HTTP 415 status code: MEDIA TYPE NOT SUPPORTED | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
abstract class Service_Rest_Controller extends Zend_Controller_Action | |
{ | |
public function init() | |
{ | |
// We remove ALL contexts before adding our own. This makes sure we ONLY use the contexts we supply here. | |
$this->_helper->restContextSwitch() | |
->clearContexts() | |
->addContext( | |
'xml', | |
array('suffix' => 'xml', 'headers' => array('Content-Type' => 'text/xml'))) | |
->addContext( | |
'html', | |
array('suffix' => '', 'headers' => array('Content-Type' => 'text/html'))) | |
->addContext( | |
'json', | |
array('suffix' => 'json', 'headers' => array('Content-Type' => 'application/json'))) | |
->clearActionContexts() | |
->addGlobalContext(array('xml', 'html', 'json')) | |
->setDefaultContext('xml') | |
->initContext(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment