pictcode / lib / Cake / View / Helper / JsHelper.php @ 635eef61
履歴 | 表示 | アノテート | ダウンロード (14.529 KB)
1 | 635eef61 | spyder1211 | <?php
|
---|---|---|---|
2 | /**
|
||
3 | * Javascript Generator class file.
|
||
4 | *
|
||
5 | * CakePHP : Rapid Development Framework (http://cakephp.org)
|
||
6 | * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||
7 | *
|
||
8 | * Licensed under The MIT License
|
||
9 | * For full copyright and license information, please see the LICENSE.txt
|
||
10 | * Redistributions of files must retain the above copyright notice.
|
||
11 | *
|
||
12 | * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||
13 | * @link http://cakephp.org CakePHP(tm) Project
|
||
14 | * @package Cake.View.Helper
|
||
15 | * @since CakePHP(tm) v 1.2
|
||
16 | * @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||
17 | */
|
||
18 | |||
19 | App::uses('AppHelper', 'View/Helper'); |
||
20 | App::uses('JsBaseEngineHelper', 'View/Helper'); |
||
21 | App::uses('Multibyte', 'I18n'); |
||
22 | |||
23 | /**
|
||
24 | * Javascript Generator helper class for easy use of JavaScript.
|
||
25 | *
|
||
26 | * JsHelper provides an abstract interface for authoring JavaScript with a
|
||
27 | * given client-side library.
|
||
28 | *
|
||
29 | * @package Cake.View.Helper
|
||
30 | * @property HtmlHelper $Html
|
||
31 | * @property FormHelper $Form
|
||
32 | */
|
||
33 | class JsHelper extends AppHelper { |
||
34 | |||
35 | /**
|
||
36 | * Whether or not you want scripts to be buffered or output.
|
||
37 | *
|
||
38 | * @var bool
|
||
39 | */
|
||
40 | public $bufferScripts = true; |
||
41 | |||
42 | /**
|
||
43 | * Helper dependencies
|
||
44 | *
|
||
45 | * @var array
|
||
46 | */
|
||
47 | public $helpers = array('Html', 'Form'); |
||
48 | |||
49 | /**
|
||
50 | * Variables to pass to Javascript.
|
||
51 | *
|
||
52 | * @var array
|
||
53 | * @see JsHelper::set()
|
||
54 | */
|
||
55 | protected $_jsVars = array(); |
||
56 | |||
57 | /**
|
||
58 | * Scripts that are queued for output
|
||
59 | *
|
||
60 | * @var array
|
||
61 | * @see JsHelper::buffer()
|
||
62 | */
|
||
63 | protected $_bufferedScripts = array(); |
||
64 | |||
65 | /**
|
||
66 | * Current Javascript Engine that is being used
|
||
67 | *
|
||
68 | * @var string
|
||
69 | */
|
||
70 | protected $_engineName; |
||
71 | |||
72 | /**
|
||
73 | * The javascript variable created by set() variables.
|
||
74 | *
|
||
75 | * @var string
|
||
76 | */
|
||
77 | public $setVariable = 'app'; |
||
78 | |||
79 | /**
|
||
80 | * Constructor - determines engine helper
|
||
81 | *
|
||
82 | * @param View $View the view object the helper is attached to.
|
||
83 | * @param string|array $settings Settings array contains name of engine helper.
|
||
84 | */
|
||
85 | public function __construct(View $View, $settings = array()) { |
||
86 | $className = 'Jquery'; |
||
87 | if (is_array($settings) && isset($settings[0])) { |
||
88 | $className = $settings[0]; |
||
89 | } elseif (is_string($settings)) { |
||
90 | $className = $settings; |
||
91 | } |
||
92 | $engineName = $className; |
||
93 | list(, $className) = pluginSplit($className); |
||
94 | |||
95 | $this->_engineName = $className . 'Engine'; |
||
96 | $engineClass = $engineName . 'Engine'; |
||
97 | $this->helpers[] = $engineClass; |
||
98 | parent::__construct($View, $settings); |
||
99 | } |
||
100 | |||
101 | /**
|
||
102 | * call__ Allows for dispatching of methods to the Engine Helper.
|
||
103 | * methods in the Engines bufferedMethods list will be automatically buffered.
|
||
104 | * You can control buffering with the buffer param as well. By setting the last parameter to
|
||
105 | * any engine method to a boolean you can force or disable buffering.
|
||
106 | *
|
||
107 | * e.g. `$js->get('#foo')->effect('fadeIn', array('speed' => 'slow'), true);`
|
||
108 | *
|
||
109 | * Will force buffering for the effect method. If the method takes an options array you may also add
|
||
110 | * a 'buffer' param to the options array and control buffering there as well.
|
||
111 | *
|
||
112 | * e.g. `$js->get('#foo')->event('click', $functionContents, array('buffer' => true));`
|
||
113 | *
|
||
114 | * The buffer parameter will not be passed onto the EngineHelper.
|
||
115 | *
|
||
116 | * @param string $method Method to be called
|
||
117 | * @param array $params Parameters for the method being called.
|
||
118 | * @return mixed Depends on the return of the dispatched method, or it could be an instance of the EngineHelper
|
||
119 | */
|
||
120 | public function __call($method, $params) { |
||
121 | if ($this->{$this->_engineName} && method_exists($this->{$this->_engineName}, $method)) { |
||
122 | $buffer = false; |
||
123 | $engineHelper = $this->{$this->_engineName}; |
||
124 | if (in_array(strtolower($method), $engineHelper->bufferedMethods)) { |
||
125 | $buffer = true; |
||
126 | } |
||
127 | if (count($params) > 0) { |
||
128 | $lastParam = $params[count($params) - 1]; |
||
129 | $hasBufferParam = (is_bool($lastParam) || is_array($lastParam) && isset($lastParam['buffer'])); |
||
130 | if ($hasBufferParam && is_bool($lastParam)) { |
||
131 | $buffer = $lastParam; |
||
132 | unset($params[count($params) - 1]); |
||
133 | } elseif ($hasBufferParam && is_array($lastParam)) { |
||
134 | $buffer = $lastParam['buffer']; |
||
135 | unset($params['buffer']); |
||
136 | } |
||
137 | } |
||
138 | |||
139 | $out = call_user_func_array(array(&$engineHelper, $method), $params); |
||
140 | if ($this->bufferScripts && $buffer && is_string($out)) { |
||
141 | $this->buffer($out); |
||
142 | return null; |
||
143 | } |
||
144 | if (is_object($out) && $out instanceof JsBaseEngineHelper) { |
||
145 | return $this; |
||
146 | } |
||
147 | return $out; |
||
148 | } |
||
149 | if (method_exists($this, $method . '_')) { |
||
150 | return call_user_func(array(&$this, $method . '_'), $params); |
||
151 | } |
||
152 | trigger_error(__d('cake_dev', 'JsHelper:: Missing Method %s is undefined', $method), E_USER_WARNING); |
||
153 | } |
||
154 | |||
155 | /**
|
||
156 | * Overwrite inherited Helper::value()
|
||
157 | * See JsBaseEngineHelper::value() for more information on this method.
|
||
158 | *
|
||
159 | * @param mixed $val A PHP variable to be converted to JSON
|
||
160 | * @param bool $quoteString If false, leaves string values unquoted
|
||
161 | * @param string $key Key name.
|
||
162 | * @return string a JavaScript-safe/JSON representation of $val
|
||
163 | * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/js.html#JsHelper::value
|
||
164 | */
|
||
165 | public function value($val = array(), $quoteString = null, $key = 'value') { |
||
166 | if ($quoteString === null) { |
||
167 | $quoteString = true; |
||
168 | } |
||
169 | return $this->{$this->_engineName}->value($val, $quoteString); |
||
170 | } |
||
171 | |||
172 | /**
|
||
173 | * Writes all Javascript generated so far to a code block or
|
||
174 | * caches them to a file and returns a linked script. If no scripts have been
|
||
175 | * buffered this method will return null. If the request is an XHR(ajax) request
|
||
176 | * onDomReady will be set to false. As the dom is already 'ready'.
|
||
177 | *
|
||
178 | * ### Options
|
||
179 | *
|
||
180 | * - `inline` - Set to true to have scripts output as a script block inline
|
||
181 | * if `cache` is also true, a script link tag will be generated. (default true)
|
||
182 | * - `cache` - Set to true to have scripts cached to a file and linked in (default false)
|
||
183 | * - `clear` - Set to false to prevent script cache from being cleared (default true)
|
||
184 | * - `onDomReady` - wrap cached scripts in domready event (default true)
|
||
185 | * - `safe` - if an inline block is generated should it be wrapped in <![CDATA[ ... ]]> (default true)
|
||
186 | *
|
||
187 | * @param array $options options for the code block
|
||
188 | * @return mixed Completed javascript tag if there are scripts, if there are no buffered
|
||
189 | * scripts null will be returned.
|
||
190 | * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/js.html#JsHelper::writeBuffer
|
||
191 | */
|
||
192 | public function writeBuffer($options = array()) { |
||
193 | $domReady = !$this->request->is('ajax'); |
||
194 | $defaults = array( |
||
195 | 'onDomReady' => $domReady, 'inline' => true, |
||
196 | 'cache' => false, 'clear' => true, 'safe' => true |
||
197 | ); |
||
198 | $options += $defaults; |
||
199 | $script = implode("\n", $this->getBuffer($options['clear'])); |
||
200 | |||
201 | if (empty($script)) { |
||
202 | return null; |
||
203 | } |
||
204 | |||
205 | if ($options['onDomReady']) { |
||
206 | $script = $this->{$this->_engineName}->domReady($script); |
||
207 | } |
||
208 | $opts = $options; |
||
209 | unset($opts['onDomReady'], $opts['cache'], $opts['clear']); |
||
210 | |||
211 | if ($options['cache'] && $options['inline']) { |
||
212 | $filename = md5($script); |
||
213 | $path = WWW_ROOT . Configure::read('App.jsBaseUrl'); |
||
214 | if (file_exists($path . $filename . '.js') |
||
215 | || cache(str_replace(WWW_ROOT, '', $path) . $filename . '.js', $script, '+999 days', 'public') |
||
216 | ) { |
||
217 | return $this->Html->script($filename); |
||
218 | } |
||
219 | } |
||
220 | |||
221 | $return = $this->Html->scriptBlock($script, $opts); |
||
222 | if ($options['inline']) { |
||
223 | return $return; |
||
224 | } |
||
225 | return null; |
||
226 | } |
||
227 | |||
228 | /**
|
||
229 | * Write a script to the buffered scripts.
|
||
230 | *
|
||
231 | * @param string $script Script string to add to the buffer.
|
||
232 | * @param bool $top If true the script will be added to the top of the
|
||
233 | * buffered scripts array. If false the bottom.
|
||
234 | * @return void
|
||
235 | * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/js.html#JsHelper::buffer
|
||
236 | */
|
||
237 | public function buffer($script, $top = false) { |
||
238 | if ($top) { |
||
239 | array_unshift($this->_bufferedScripts, $script); |
||
240 | } else {
|
||
241 | $this->_bufferedScripts[] = $script; |
||
242 | } |
||
243 | } |
||
244 | |||
245 | /**
|
||
246 | * Get all the buffered scripts
|
||
247 | *
|
||
248 | * @param bool $clear Whether or not to clear the script caches (default true)
|
||
249 | * @return array Array of scripts added to the request.
|
||
250 | * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/js.html#JsHelper::getBuffer
|
||
251 | */
|
||
252 | public function getBuffer($clear = true) { |
||
253 | $this->_createVars();
|
||
254 | $scripts = $this->_bufferedScripts; |
||
255 | if ($clear) { |
||
256 | $this->_bufferedScripts = array(); |
||
257 | $this->_jsVars = array(); |
||
258 | } |
||
259 | return $scripts; |
||
260 | } |
||
261 | |||
262 | /**
|
||
263 | * Generates the object string for variables passed to javascript and adds to buffer
|
||
264 | *
|
||
265 | * @return void
|
||
266 | */
|
||
267 | protected function _createVars() { |
||
268 | if (!empty($this->_jsVars)) { |
||
269 | $setVar = (strpos($this->setVariable, '.')) ? $this->setVariable : 'window.' . $this->setVariable; |
||
270 | $this->buffer($setVar . ' = ' . $this->object($this->_jsVars) . ';', true); |
||
271 | } |
||
272 | } |
||
273 | |||
274 | /**
|
||
275 | * Generate an 'Ajax' link. Uses the selected JS engine to create a link
|
||
276 | * element that is enhanced with Javascript. Options can include
|
||
277 | * both those for HtmlHelper::link() and JsBaseEngine::request(), JsBaseEngine::event();
|
||
278 | *
|
||
279 | * ### Options
|
||
280 | *
|
||
281 | * - `confirm` - Generate a confirm() dialog before sending the event.
|
||
282 | * - `id` - use a custom id.
|
||
283 | * - `htmlAttributes` - additional non-standard htmlAttributes. Standard attributes are class, id,
|
||
284 | * rel, title, escape, onblur and onfocus.
|
||
285 | * - `buffer` - Disable the buffering and return a script tag in addition to the link.
|
||
286 | *
|
||
287 | * @param string $title Title for the link.
|
||
288 | * @param string|array $url Mixed either a string URL or a CakePHP URL array.
|
||
289 | * @param array $options Options for both the HTML element and Js::request()
|
||
290 | * @return string Completed link. If buffering is disabled a script tag will be returned as well.
|
||
291 | * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/js.html#JsHelper::link
|
||
292 | */
|
||
293 | public function link($title, $url = null, $options = array()) { |
||
294 | if (!isset($options['id'])) { |
||
295 | $options['id'] = 'link-' . (int)mt_rand(); |
||
296 | } |
||
297 | list($options, $htmlOptions) = $this->_getHtmlOptions($options); |
||
298 | $out = $this->Html->link($title, $url, $htmlOptions); |
||
299 | $this->get('#' . $htmlOptions['id']); |
||
300 | $requestString = $event = ''; |
||
301 | if (isset($options['confirm'])) { |
||
302 | $requestString = $this->confirmReturn($options['confirm']); |
||
303 | unset($options['confirm']); |
||
304 | } |
||
305 | $buffer = isset($options['buffer']) ? $options['buffer'] : null; |
||
306 | $safe = isset($options['safe']) ? $options['safe'] : true; |
||
307 | unset($options['buffer'], $options['safe']); |
||
308 | |||
309 | $requestString .= $this->request($url, $options); |
||
310 | |||
311 | if (!empty($requestString)) { |
||
312 | $event = $this->event('click', $requestString, $options + array('buffer' => $buffer)); |
||
313 | } |
||
314 | if (isset($buffer) && !$buffer) { |
||
315 | $opts = array('safe' => $safe); |
||
316 | $out .= $this->Html->scriptBlock($event, $opts); |
||
317 | } |
||
318 | return $out; |
||
319 | } |
||
320 | |||
321 | /**
|
||
322 | * Pass variables into Javascript. Allows you to set variables that will be
|
||
323 | * output when the buffer is fetched with `JsHelper::getBuffer()` or `JsHelper::writeBuffer()`
|
||
324 | * The Javascript variable used to output set variables can be controlled with `JsHelper::$setVariable`
|
||
325 | *
|
||
326 | * @param string|array $one Either an array of variables to set, or the name of the variable to set.
|
||
327 | * @param string|array $two If $one is a string, $two is the value for that key.
|
||
328 | * @return void
|
||
329 | * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/js.html#JsHelper::set
|
||
330 | */
|
||
331 | public function set($one, $two = null) { |
||
332 | $data = null; |
||
333 | if (is_array($one)) { |
||
334 | if (is_array($two)) { |
||
335 | $data = array_combine($one, $two); |
||
336 | } else {
|
||
337 | $data = $one; |
||
338 | } |
||
339 | } else {
|
||
340 | $data = array($one => $two); |
||
341 | } |
||
342 | if (!$data) { |
||
343 | return false; |
||
344 | } |
||
345 | $this->_jsVars = array_merge($this->_jsVars, $data); |
||
346 | } |
||
347 | |||
348 | /**
|
||
349 | * Uses the selected JS engine to create a submit input
|
||
350 | * element that is enhanced with Javascript. Options can include
|
||
351 | * both those for FormHelper::submit() and JsBaseEngine::request(), JsBaseEngine::event();
|
||
352 | *
|
||
353 | * Forms submitting with this method, cannot send files. Files do not transfer over XmlHttpRequest
|
||
354 | * and require an iframe or flash.
|
||
355 | *
|
||
356 | * ### Options
|
||
357 | *
|
||
358 | * - `url` The url you wish the XHR request to submit to.
|
||
359 | * - `confirm` A string to use for a confirm() message prior to submitting the request.
|
||
360 | * - `method` The method you wish the form to send by, defaults to POST
|
||
361 | * - `buffer` Whether or not you wish the script code to be buffered, defaults to true.
|
||
362 | * - Also see options for JsHelper::request() and JsHelper::event()
|
||
363 | *
|
||
364 | * @param string $caption The display text of the submit button.
|
||
365 | * @param array $options Array of options to use. See the options for the above mentioned methods.
|
||
366 | * @return string Completed submit button.
|
||
367 | * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/js.html#JsHelper::submit
|
||
368 | */
|
||
369 | public function submit($caption = null, $options = array()) { |
||
370 | if (!isset($options['id'])) { |
||
371 | $options['id'] = 'submit-' . (int)mt_rand(); |
||
372 | } |
||
373 | $formOptions = array('div'); |
||
374 | list($options, $htmlOptions) = $this->_getHtmlOptions($options, $formOptions); |
||
375 | $out = $this->Form->submit($caption, $htmlOptions); |
||
376 | |||
377 | $this->get('#' . $htmlOptions['id']); |
||
378 | |||
379 | $options['data'] = $this->serializeForm(array('isForm' => false, 'inline' => true)); |
||
380 | $requestString = $url = ''; |
||
381 | if (isset($options['confirm'])) { |
||
382 | $requestString = $this->confirmReturn($options['confirm']); |
||
383 | unset($options['confirm']); |
||
384 | } |
||
385 | if (isset($options['url'])) { |
||
386 | $url = $options['url']; |
||
387 | unset($options['url']); |
||
388 | } |
||
389 | if (!isset($options['method'])) { |
||
390 | $options['method'] = 'post'; |
||
391 | } |
||
392 | $options['dataExpression'] = true; |
||
393 | |||
394 | $buffer = isset($options['buffer']) ? $options['buffer'] : null; |
||
395 | $safe = isset($options['safe']) ? $options['safe'] : true; |
||
396 | unset($options['buffer'], $options['safe']); |
||
397 | |||
398 | $requestString .= $this->request($url, $options); |
||
399 | if (!empty($requestString)) { |
||
400 | $event = $this->event('click', $requestString, $options + array('buffer' => $buffer)); |
||
401 | } |
||
402 | if (isset($buffer) && !$buffer) { |
||
403 | $opts = array('safe' => $safe); |
||
404 | $out .= $this->Html->scriptBlock($event, $opts); |
||
405 | } |
||
406 | return $out; |
||
407 | } |
||
408 | |||
409 | /**
|
||
410 | * Parse a set of Options and extract the Html options.
|
||
411 | * Extracted Html Options are removed from the $options param.
|
||
412 | *
|
||
413 | * @param array $options Options to filter.
|
||
414 | * @param array $additional Array of additional keys to extract and include in the return options array.
|
||
415 | * @return array Array of js options and Htmloptions
|
||
416 | */
|
||
417 | protected function _getHtmlOptions($options, $additional = array()) { |
||
418 | $htmlKeys = array_merge( |
||
419 | array('class', 'id', 'escape', 'onblur', 'onfocus', 'rel', 'title', 'style'), |
||
420 | $additional
|
||
421 | ); |
||
422 | $htmlOptions = array(); |
||
423 | foreach ($htmlKeys as $key) { |
||
424 | if (isset($options[$key])) { |
||
425 | $htmlOptions[$key] = $options[$key]; |
||
426 | } |
||
427 | unset($options[$key]); |
||
428 | } |
||
429 | if (isset($options['htmlAttributes'])) { |
||
430 | $htmlOptions = array_merge($htmlOptions, $options['htmlAttributes']); |
||
431 | unset($options['htmlAttributes']); |
||
432 | } |
||
433 | return array($options, $htmlOptions); |
||
434 | } |
||
435 | |||
436 | } |