Skip to content

Commit

Permalink
Use config() for viewClassMap and inputTypeMap
Browse files Browse the repository at this point in the history
This replaces two snowflake methods with generic config() method and
some additional runtime validation. In addition to these changes,
developers can now entirely replace the default types and remove the
defaults if they want. This is helpful when you want to disable XML
handling entirely.

Refs #7212
  • Loading branch information
markstory committed Aug 27, 2015
1 parent fa47273 commit b59c667
Showing 1 changed file with 33 additions and 39 deletions.
72 changes: 33 additions & 39 deletions src/Controller/Component/RequestHandlerComponent.php
Expand Up @@ -26,6 +26,7 @@
use Cake\Utility\Exception\XmlException;
use Cake\Utility\Inflector;
use Cake\Utility\Xml;
use RuntimeException;

/**
* Request object for handling alternative HTTP requests
Expand Down Expand Up @@ -74,35 +75,17 @@ class RequestHandlerComponent extends Component
* These are merged with user-provided config when the component is used.
*
* - `checkHttpCache` - Whether to check for HTTP cache.
* - `viewClassMap` - Mapping between type and view class.
* - `viewClassMap` - Mapping between type and view classes. If undefined
* json, xml, and ajax will be mapped. Defining any types will omit the defaults.
* - `inputTypeMap` - A mapping between types and deserializers for request bodies.
* If undefined json & xml will be mapped. Defining any types will omit the defaults.
*
* @var array
*/
protected $_defaultConfig = [
'checkHttpCache' => true,
'viewClassMap' => '',
];

/**
* A mapping between extensions and deserializers for request bodies of that type.
* By default only JSON and XML are mapped, use RequestHandlerComponent::addInputType()
*
* @var array
*/
protected $_inputTypeMap = [
'json' => ['json_decode', true]
];

/**
* A mapping between type and viewClass. By default only JSON, XML, and AJAX are mapped.
* Use RequestHandlerComponent::viewClassMap() to manipulate this map.
*
* @var array
*/
protected $_viewClassMap = [
'json' => 'Json',
'xml' => 'Xml',
'ajax' => 'Ajax'
'viewClassMap' => [],
'inputTypeMap' => []
];

/**
Expand All @@ -113,8 +96,20 @@ class RequestHandlerComponent extends Component
*/
public function __construct(ComponentRegistry $registry, array $config = [])
{
if (!isset($config['viewClassMap'])) {
$config['viewClassMap'] = [
'json' => 'Json',
'xml' => 'Xml',
'ajax' => 'Ajax'
];
}
if (!isset($config['inputTypeMap'])) {
$config['inputTypeMap'] = [
'json' => ['json_decode', true],
'xml' => [[$this, 'convertXml']],
];
}
parent::__construct($registry, $config);
$this->addInputType('xml', [[$this, 'convertXml']]);
}

/**
Expand Down Expand Up @@ -146,10 +141,6 @@ public function initialize(array $config)
{
$controller = $this->_registry->getController();
$this->response =& $controller->response;

if ($this->_config['viewClassMap']) {
$this->viewClassMap($this->_config['viewClassMap']);
}
}

/**
Expand Down Expand Up @@ -217,7 +208,10 @@ public function startup(Event $event)

$request->params['isAjax'] = $this->request->is('ajax');

foreach ($this->_inputTypeMap as $type => $handler) {
foreach ($this->config('inputTypeMap') as $type => $handler) {
if (!is_callable($handler[0])) {
throw new RuntimeException(sprintf("Invalid callable for '%s' type.", $type));
}
if ($this->requestedWith($type)) {
$input = call_user_func_array([$request, 'input'], $handler);
$request->data = (array)$input;
Expand Down Expand Up @@ -539,7 +533,7 @@ public function prefers($type = null)
public function renderAs(Controller $controller, $type, array $options = [])
{
$defaults = ['charset' => 'UTF-8'];
$viewClassMap = $this->viewClassMap();
$viewClassMap = $this->config('viewClassMap');

if (Configure::read('App.encoding') !== null) {
$defaults['charset'] = Configure::read('App.encoding');
Expand Down Expand Up @@ -682,13 +676,14 @@ public function mapAlias($alias)
* for the handler.
* @return void
* @throws \Cake\Core\Exception\Exception
* @deprecated 3.1.0 Use config('addInputType', ...) instead.
*/
public function addInputType($type, $handler)
{
if (!is_array($handler) || !isset($handler[0]) || !is_callable($handler[0])) {
throw new Exception('You must give a handler callback.');
}
$this->_inputTypeMap[$type] = $handler;
$this->config('inputTypeMap.' . $type, $handler);
}

/**
Expand All @@ -697,19 +692,18 @@ public function addInputType($type, $handler)
* @param array|string|null $type The type string or array with format `['type' => 'viewClass']` to map one or more
* @param array|null $viewClass The viewClass to be used for the type without `View` appended
* @return array|string Returns viewClass when only string $type is set, else array with viewClassMap
* @deprecated 3.1.0 Use config('viewClassMap', ...) instead.
*/
public function viewClassMap($type = null, $viewClass = null)
{
if (!$viewClass && is_string($type) && isset($this->_viewClassMap[$type])) {
return $this->_viewClassMap[$type];
if (!$viewClass && is_string($type)) {
return $this->config('viewClassMap.' . $type);
}
if (is_string($type)) {
$this->_viewClassMap[$type] = $viewClass;
$this->config('viewClassMap.' . $type, $viewClass);
} elseif (is_array($type)) {
foreach ($type as $key => $value) {
$this->viewClassMap($key, $value);
}
$this->config('viewClassMap', $type, true);
}
return $this->_viewClassMap;
return $this->config('viewClassMap');
}
}

0 comments on commit b59c667

Please sign in to comment.