-
Notifications
You must be signed in to change notification settings - Fork 23
/
AjaxComponent.php
132 lines (112 loc) · 3.65 KB
/
AjaxComponent.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
<?php
namespace Ajax\Controller\Component;
use Cake\Controller\Component;
use Cake\Controller\ComponentRegistry;
use Cake\Controller\Controller;
use Cake\Core\Configure;
use Cake\Routing\Router;
use Cake\Event\Event;
use Cake\Network\Response;
/**
* Ajax Component to respond to AJAX requests.
*
* Works together with the AjaxView to easily switch
* output type from HTML to JSON format.
*
* It will also avoid redirects and pass those down as content
* of the JSON response object.
*
* Don't forget Configure::write('Ajax.flashKey', 'messages');
* if you want to use it with Tools.Flash component.
*
* @author Mark Scherer
* @license http://opensource.org/licenses/mit-license.php MIT
*/
class AjaxComponent extends Component {
public $Controller;
public $respondAsAjax = false;
protected $_defaultConfig = [
'viewClass' => 'Ajax.Ajax',
'autoDetect' => true,
'resolveRedirect' => true,
'flashKey' => 'Flash.flash' // Use "messages" for Tools plugin Flash component, set to false to disable
];
/**
* Constructor.
*
* @param ComponentRegistry $collection
* @param array $config
*/
public function __construct(ComponentRegistry $collection, $config = []) {
$this->Controller = $collection->getController();
$defaults = (array)Configure::read('Ajax') + $this->_defaultConfig;
$config += $defaults;
parent::__construct($collection, $config);
}
public function initialize(array $config = []) {
if (!$this->_config['autoDetect']) {
return;
}
$this->respondAsAjax = $this->Controller->request->is('ajax');
}
/**
* Called before the Controller::beforeRender(), and before
* the view class is loaded, and before Controller::render()
*
* @param Controller $controller Controller with components to beforeRender
* @return void
*/
public function beforeRender(Event $event) {
if (!$this->respondAsAjax) {
return;
}
$this->_respondAsAjax();
}
/**
* AjaxComponent::_respondAsAjax()
*
* @return void
*/
protected function _respondAsAjax() {
$this->Controller->viewBuilder()->className($this->_config['viewClass']);
// Set flash messages to the view
if ($this->_config['flashKey']) {
$message = $this->Controller->request->session()->consume($this->_config['flashKey']);
$this->Controller->set('_message', $message);
}
// If _serialize is true, *all* viewVars will be serialized; no need to add _message.
if (!empty($this->Controller->viewVars['_serialize']) && $this->Controller->viewVars['_serialize'] === true) {
return;
}
$serializeKeys = ['_message'];
if (!empty($this->Controller->viewVars['_serialize'])) {
$serializeKeys = array_merge($serializeKeys, $this->Controller->viewVars['_serialize']);
}
$this->Controller->set('_serialize', $serializeKeys);
}
/**
* Called before Controller::redirect(). Allows you to replace the URL that will
* be redirected to with a new URL.
*
* @param Event $event Event
* @param string|array $url Either the string or URL array that is being redirected to.
* @param Response $response
* @return void
*/
public function beforeRedirect(Event $event, $url, Response $response) {
if (!$this->respondAsAjax || !$this->_config['resolveRedirect']) {
return;
}
$url = Router::url($url, true);
$status = $response->statusCode();
$response->statusCode(200);
$this->Controller->autoRender = true;
$this->Controller->set('_redirect', compact('url', 'status'));
$serializeKeys = ['_redirect'];
if (!empty($this->Controller->viewVars['_serialize'])) {
$serializeKeys = array_merge($serializeKeys, $this->Controller->viewVars['_serialize']);
}
$this->Controller->set('_serialize', $serializeKeys);
$event->stopPropagation();
}
}