Skip to content

Commit

Permalink
Make Component::initialize() work like other initialize() methods.
Browse files Browse the repository at this point in the history
Make Component::initialize() consistent with Controller and Table, this
makes the framework easier to understand as methods with the same name
work consistently everywhere. While I'm not totally sure about what to
do with the Controller.initialize event hook in components, I feel this
change is a good one even though it breaks existing API compatibility.

The primary use of this event hook was RequestHandler which has been
updated to not rely on the event hook. I've also ensure that
Controllers always have a request and response object as that was
causing me some grief and logically makes sense.
  • Loading branch information
markstory committed Oct 6, 2014
1 parent c71f919 commit 293b4b0
Show file tree
Hide file tree
Showing 7 changed files with 154 additions and 132 deletions.
16 changes: 13 additions & 3 deletions src/Controller/Component.php
Expand Up @@ -28,8 +28,6 @@
* Components can provide several callbacks that are fired at various stages of the request
* cycle. The available callbacks are:
*
* - `initialize(Event $event)`
* Called before the controller's beforeFilter method.
* - `startup(Event $event)`
* Called after the controller's beforeFilter method, and before the
* controller action is called.
Expand Down Expand Up @@ -99,6 +97,18 @@ public function __construct(ComponentRegistry $registry, array $config = []) {
if (!empty($this->components)) {
$this->_componentMap = $registry->normalizeArray($this->components);
}
$this->initialize($config);
}

/**
* Constructor hook method.
*
* Implement this method to avoid having to overwrite
* the constructor and call parent.
*
* @return void
*/
public function initialize(array $config) {
}

/**
Expand Down Expand Up @@ -131,7 +141,7 @@ public function __get($name) {
*/
public function implementedEvents() {
$eventMap = [
'Controller.initialize' => 'initialize',
// 'Controller.initialize' => 'initialize',
'Controller.startup' => 'startup',
'Controller.beforeRender' => 'beforeRender',
'Controller.beforeRedirect' => 'beforeRedirect',
Expand Down
104 changes: 60 additions & 44 deletions src/Controller/Component/RequestHandlerComponent.php
Expand Up @@ -120,10 +120,6 @@ class RequestHandlerComponent extends Component {
public function __construct(ComponentRegistry $registry, array $config = array()) {
parent::__construct($registry, $config);
$this->addInputType('xml', array(array($this, 'convertXml')));

$Controller = $registry->getController();
$this->request = $Controller->request;
$this->response = $Controller->response;
}

/**
Expand All @@ -133,7 +129,6 @@ public function __construct(ComponentRegistry $registry, array $config = array()
*/
public function implementedEvents() {
return [
'Controller.initialize' => 'initialize',
'Controller.startup' => 'startup',
'Controller.beforeRender' => 'beforeRender',
'Controller.beforeRedirect' => 'beforeRedirect',
Expand All @@ -147,24 +142,27 @@ public function implementedEvents() {
* of an ajax request indicated using the second header based method above, the type must have
* been configured in {@link Cake\Routing\Router}.
*
* @param Event $event The initialize event that was fired.
* @param array $config The config data.
* @return void
* @see Router::extensions()
*/
public function initialize(Event $event) {
if (isset($this->request->params['_ext'])) {
$this->ext = $this->request->params['_ext'];
public function initialize(array $config) {
$controller = $this->_registry->getController();
$request = $this->request = $controller->request;
$response = $this->response = $controller->response;

if (isset($request->params['_ext'])) {
$this->ext = $request->params['_ext'];
}
if (empty($this->ext) || in_array($this->ext, array('html', 'htm'))) {
$this->_setExtension();
$this->_setExtension($request, $this->response);
}
if (empty($this->ext) && $this->request->is('ajax')) {
if (empty($this->ext) && $request->is('ajax')) {
$this->ext = 'ajax';
}

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

Expand All @@ -179,15 +177,17 @@ public function initialize(Event $event) {
* If html is one of the preferred types, no content type will be set, this
* is to avoid issues with browsers that prefer html and several other content types.
*
* @param \Cake\Network\Request $request The request instance.
* @param \Cake\Network\Response $response The response instance.
* @return void
*/
protected function _setExtension() {
$accept = $this->request->parseAccept();
protected function _setExtension($request, $response) {
$accept = $request->parseAccept();
if (empty($accept)) {
return;
}

$accepts = $this->response->mapType($accept);
$accepts = $response->mapType($accept);
$preferedTypes = current($accepts);
if (array_intersect($preferedTypes, array('html', 'xhtml'))) {
return;
Expand Down Expand Up @@ -267,29 +267,31 @@ public function convertXml($xml) {

/**
* Handles (fakes) redirects for Ajax requests using requestAction()
* Modifies the $_POST and $_SERVER['REQUEST_METHOD'] to simulate a new GET request.
*
* @param Event $event The Controller.beforeRedirect event.
* @param string|array $url A string or array containing the redirect location
* @param \Cake\Network\Response $response The response object.
* @return void
*/
public function beforeRedirect(Event $event, $url, Response $response) {
if (!$this->request->is('ajax')) {
$request = $this->request;
if (!$request->is('ajax')) {
return;
}
if (empty($url)) {
return;
}
$_SERVER['REQUEST_METHOD'] = 'GET';
foreach ($_POST as $key => $val) {
unset($_POST[$key]);
}
if (is_array($url)) {
$url = Router::url($url + array('base' => false));
}
$controller = $event->subject();
$response->body($controller->requestAction($url, array('return', 'bare' => false)));
$response->body($controller->requestAction($url, [
'return',
'bare' => false,
'environment' => [
'REQUEST_METHOD' => 'GET'
]
]));
$response->send();
$response->stop();
}
Expand All @@ -304,7 +306,9 @@ public function beforeRedirect(Event $event, $url, Response $response) {
* @return bool false if the render process should be aborted
*/
public function beforeRender(Event $event) {
if ($this->_config['checkHttpCache'] && $this->response->checkNotModified($this->request)) {
$response = $this->response;
$request = $this->request;
if ($this->_config['checkHttpCache'] && $response->checkNotModified($request)) {
return false;
}
}
Expand Down Expand Up @@ -343,7 +347,8 @@ public function isAtom() {
* @return bool True if user agent is a mobile web browser
*/
public function isMobile() {
return $this->request->is('mobile') || $this->accepts('wap');
$request = $this->request;
return $request->is('mobile') || $this->accepts('wap');
}

/**
Expand Down Expand Up @@ -378,10 +383,12 @@ public function isWap() {
* if the client accepts one or more elements in the array.
*/
public function accepts($type = null) {
$accepted = $this->request->accepts();
$request = $this->request;
$response = $this->response;
$accepted = $request->accepts();

if (!$type) {
return $this->response->mapType($accepted);
return $response->mapType($accepted);
}
if (is_array($type)) {
foreach ($type as $t) {
Expand All @@ -407,9 +414,10 @@ public function accepts($type = null) {
* in the request content type will be returned.
*/
public function requestedWith($type = null) {
if (!$this->request->is('post') &&
!$this->request->is('put') &&
!$this->request->is('delete')
$request = $this->request;
if (!$request->is('post') &&
!$request->is('put') &&
!$request->is('delete')
) {
return null;
}
Expand All @@ -422,15 +430,16 @@ public function requestedWith($type = null) {
return false;
}

list($contentType) = explode(';', $this->request->env('CONTENT_TYPE'));
list($contentType) = explode(';', $request->env('CONTENT_TYPE'));
if ($contentType === '') {
list($contentType) = explode(';', $this->request->header('CONTENT_TYPE'));
list($contentType) = explode(';', $request->header('CONTENT_TYPE'));
}
$response = $this->response;
if (!$type) {
return $this->response->mapType($contentType);
return $response->mapType($contentType);
}
if (is_string($type)) {
return ($type === $this->response->mapType($contentType));
return ($type === $response->mapType($contentType));
}
}

Expand All @@ -451,12 +460,14 @@ public function requestedWith($type = null) {
* If no type is provided the first preferred type is returned.
*/
public function prefers($type = null) {
$acceptRaw = $this->request->parseAccept();
$request = $this->request;
$response = $this->response;
$acceptRaw = $request->parseAccept();

if (empty($acceptRaw)) {
return $this->ext;
}
$accepts = $this->response->mapType(array_shift($acceptRaw));
$accepts = $response->mapType(array_shift($acceptRaw));

if (!$type) {
if (empty($this->ext) && !empty($accepts)) {
Expand Down Expand Up @@ -535,7 +546,8 @@ public function renderAs(Controller $controller, $type, array $options = array()
$controller->layoutPath = $type;
}

if ($this->response->getMimeType($type)) {
$response = $this->response;
if ($response->getMimeType($type)) {
$this->respondAs($type, $options);
}

Expand Down Expand Up @@ -566,8 +578,10 @@ public function respondAs($type, array $options = array()) {
$options += $defaults;

$cType = $type;
$request = $this->request;
$response = $this->response;
if (strpos($type, '/') === false) {
$cType = $this->response->getMimeType($type);
$cType = $response->getMimeType($type);
}
if (is_array($cType)) {
if (isset($cType[$options['index']])) {
Expand All @@ -585,13 +599,13 @@ public function respondAs($type, array $options = array()) {
return false;
}
if (empty($this->request->params['requested'])) {
$this->response->type($cType);
$response->type($cType);
}
if (!empty($options['charset'])) {
$this->response->charset($options['charset']);
$response->charset($options['charset']);
}
if (!empty($options['attachment'])) {
$this->response->download($options['attachment']);
$response->download($options['attachment']);
}
return true;
}
Expand All @@ -603,7 +617,8 @@ public function respondAs($type, array $options = array()) {
* otherwise null
*/
public function responseType() {
return $this->response->mapType($this->response->type());
$response = $this->response;
return $response->mapType($response->type());
}

/**
Expand All @@ -617,7 +632,8 @@ public function mapAlias($alias) {
if (is_array($alias)) {
return array_map(array($this, 'mapAlias'), $alias);
}
$type = $this->response->getMimeType($alias);
$response = $this->response;
$type = $response->getMimeType($alias);
if ($type) {
if (is_array($type)) {
return $type[0];
Expand Down
12 changes: 8 additions & 4 deletions src/Controller/Controller.php
Expand Up @@ -261,12 +261,16 @@ public function __construct(Request $request = null, Response $response = null,
$this->viewPath = $viewPath;
}

if ($request instanceof Request) {
$this->setRequest($request);
if (!($request instanceof Request)) {
$request = new Request();
}
if ($response instanceof Response) {
$this->response = $response;
$this->setRequest($request);

if (!($response instanceof Response)) {
$response = new Response();
}
$this->response = $response;

if ($eventManager) {
$this->eventManager($eventManager);
}
Expand Down

0 comments on commit 293b4b0

Please sign in to comment.