Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save jaytaph/774267 to your computer and use it in GitHub Desktop.
Save jaytaph/774267 to your computer and use it in GitHub Desktop.
Gists for blogpost
[production]
settings.context.formats = "xml,json"
[staging : production]
[testing : staging]
settings.context.formats = "xml,json,html"
[development : testing]
<?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;
}
}
<?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;
}
}
}
<?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
}
}
}
<?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