1: <?php
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: class JsHelper extends Overloadable2 {
34: var $base = null;
35: var $webroot = null;
36: var $here = null;
37: var $params = null;
38: var $action = null;
39: var $data = null;
40: var $themeWeb = null;
41: var $plugin = null;
42:
43: var $helpers = array();
44:
45: var $hook = null;
46:
47: var $__objects = array();
48:
49: var $effectMap = array(
50: 'Appear', 'Fade', 'Puff', 'BlindDown', 'BlindUp', 'SwitchOff', 'SlideDown', 'SlideUp',
51: 'DropOut', 'Shake', 'Pulsate', 'Squish', 'Fold', 'Grow', 'Shrink', 'Highlight', 'toggle'
52: );
53:
54: var $output = false;
55:
56: function __construct() {
57: $this->effectMap = array_combine(
58: array_map('strtolower', $this->effectMap),
59: $this->effectMap
60: );
61: parent::__construct();
62: }
63:
64: function call__($method, $params) {
65: if (is_object($this->hook) && method_exists($this->hook, $method)) {
66: $this->hook->dispatchMethod($method . '_', $params);
67: }
68: if (method_exists($this, $method . '_')) {
69: return $this->dispatchMethod($method . '_', $params);
70: }
71: }
72:
73: function alert_($message) {
74: return 'alert("' . $this->escape($message) . '");';
75: }
76:
77: function if_($if, $then, $else = null, $elseIf = array()) {
78: $len = strlen($if) - 1;
79: if ($if{$len} == ';') {
80: $if{$len} = null;
81: }
82:
83: $out = 'if (' . $if . ') { ' . $then . ' }';
84:
85: foreach ($elseIf as $cond => $exec) {
86:
87: }
88:
89: if (!empty($else)) {
90: $out .= ' else { ' . $else . ' }';
91: }
92:
93: return $out;
94: }
95:
96: function confirm_($message) {
97: return 'confirm("' . $this->escape($message) . '");';
98: }
99:
100: function prompt_($message, $default = '') {
101: return 'prompt("' . $this->escape($message) . '", "' . $this->escape($default) . '");';
102: }
103: 104: 105: 106: 107: 108:
109: function tryThese_($expr1, $expr2, $expr3) {
110: }
111: 112: 113: 114: 115: 116: 117:
118: function load_($url = null, $options = array()) {
119:
120: if (isset($options['update'])) {
121: if (!is_array($options['update'])) {
122: $func = "new Ajax.Updater('{$options['update']}',";
123: } else {
124: $func = "new Ajax.Updater(document.createElement('div'),";
125: }
126: if (!isset($options['requestHeaders'])) {
127: $options['requestHeaders'] = array();
128: }
129: if (is_array($options['update'])) {
130: $options['update'] = implode(' ', $options['update']);
131: }
132: $options['requestHeaders']['X-Update'] = $options['update'];
133: } else {
134: $func = "new Ajax.Request(";
135: }
136:
137: $func .= "'" . Router::url($url) . "'";
138: $ajax =& new AjaxHelper();
139: $func .= ", " . $ajax->__optionsForAjax($options) . ")";
140:
141: if (isset($options['before'])) {
142: $func = "{$options['before']}; $func";
143: }
144: if (isset($options['after'])) {
145: $func = "$func; {$options['after']};";
146: }
147: if (isset($options['condition'])) {
148: $func = "if ({$options['condition']}) { $func; }";
149: }
150: if (isset($options['confirm'])) {
151: $func = "if (confirm('" . $this->Javascript->escapeString($options['confirm'])
152: . "')) { $func; } else { return false; }";
153: }
154: return $func;
155: }
156: 157: 158: 159: 160: 161: 162:
163: function redirect_($url = null) {
164: return 'window.location = "' . Router::url($url) . '";';
165: }
166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178:
179: function escape($string) {
180: $escape = array("\r\n" => '\n', "\r" => '\n', "\n" => '\n', '"' => '\"', "'" => "\\'");
181: return str_replace(array_keys($escape), array_values($escape), $string);
182: }
183:
184: function get__($name) {
185: return $this->__object($name, 'id');
186: }
187:
188: function select($pattern) {
189: return $this->__object($pattern, 'pattern');
190: }
191:
192: function real($var) {
193: return $this->__object($var, 'real');
194: }
195:
196: function __object($name, $var) {
197: if (!isset($this->__objects[$name])) {
198: $this->__objects[$name] = new JsHelperObject($this);
199: $this->__objects[$name]->{$var} = $name;
200: }
201: return $this->__objects[$name];
202: }
203: 204: 205: 206: 207: 208: 209: 210: 211: 212: 213: 214: 215:
216: function object($data = array(), $block = false, $prefix = '', $postfix = '', $stringKeys = array(), $quoteKeys = true, $q = "\"") {
217: if (is_object($data)) {
218: $data = get_object_vars($data);
219: }
220:
221: $out = array();
222: $key = array();
223:
224: if (is_array($data)) {
225: $keys = array_keys($data);
226: }
227:
228: $numeric = true;
229:
230: if (!empty($keys)) {
231: foreach ($keys as $key) {
232: if (!is_numeric($key)) {
233: $numeric = false;
234: break;
235: }
236: }
237: }
238:
239: foreach ($data as $key => $val) {
240: if (is_array($val) || is_object($val)) {
241: $val = $this->object($val, false, '', '', $stringKeys, $quoteKeys, $q);
242: } else {
243: if ((!count($stringKeys) && !is_numeric($val) && !is_bool($val)) || ($quoteKeys && in_array($key, $stringKeys)) || (!$quoteKeys && !in_array($key, $stringKeys)) && $val !== null) {
244: $val = $q . $this->escapeString($val) . $q;
245: }
246: if ($val == null) {
247: $val = 'null';
248: }
249: }
250:
251: if (!$numeric) {
252: $val = $q . $key . $q . ':' . $val;
253: }
254:
255: $out[] = $val;
256: }
257:
258: if (!$numeric) {
259: $rt = '{' . implode(', ', $out) . '}';
260: } else {
261: $rt = '[' . implode(', ', $out) . ']';
262: }
263: $rt = $prefix . $rt . $postfix;
264:
265: if ($block) {
266: $rt = $this->codeBlock($rt);
267: }
268:
269: return $rt;
270: }
271: }
272:
273: class JsHelperObject {
274: var $__parent = null;
275:
276: var $id = null;
277:
278: var $pattern = null;
279:
280: var $real = null;
281:
282: function __construct(&$parent) {
283: if (is_object($parent)) {
284: $this->setParent($parent);
285: }
286: }
287:
288: function toString() {
289: return $this->__toString();
290: }
291:
292: function __toString() {
293: return $this->literal;
294: }
295:
296: function ref($ref = null) {
297: if ($ref == null) {
298: foreach (array('id', 'pattern', 'real') as $ref) {
299: if ($this->{$ref} !== null) {
300: return $this->{$ref};
301: }
302: }
303: } else {
304: return ($this->{$ref} !== null);
305: }
306: return null;
307: }
308:
309: function literal($append = null) {
310: if (!empty($this->id)) {
311: $data = '$("' . $this->id . '")';
312: }
313: if (!empty($this->pattern)) {
314: $data = '$$("' . $this->pattern . '")';
315: }
316: if (!empty($this->real)) {
317: $data = $this->real;
318: }
319: if (!empty($append)) {
320: $data .= '.' . $append;
321: }
322: return $data;
323: }
324:
325: function __call($name, $args) {
326: $data = '';
327:
328: if (isset($this->__parent->effectMap[strtolower($name)])) {
329: array_unshift($args, $this->__parent->effectMap[strtolower($name)]);
330: $name = 'effect';
331: }
332:
333: switch ($name) {
334: case 'effect':
335: case 'visualEffect':
336:
337: if (strpos($args[0], '_') || $args[0]{0} != strtoupper($args[0]{0})) {
338: $args[0] = Inflector::camelize($args[0]);
339: }
340:
341: if (strtolower($args[0]) == 'highlight') {
342: $data .= 'new ';
343: }
344: if ($this->pattern == null) {
345: $data .= 'Effect.' . $args[0] . '(' . $this->literal();
346: } else {
347: $data .= 'Effect.' . $args[0] . '(item';
348: }
349:
350: if (isset($args[1]) && is_array($args[1])) {
351: $data .= ', {' . $this->__options($args[1]) . '}';
352: }
353: $data .= ');';
354:
355: if ($this->pattern !== null) {
356: $data = $this->each($data);
357: }
358: break;
359: case 'remove':
360: case 'toggle':
361: case 'show':
362: case 'hide':
363: if (empty($args)) {
364: $obj = 'Element';
365: $params = '';
366: } else {
367: $obj = 'Effect';
368: $params = ', "' . $args[0] . '"';
369: }
370:
371: if ($this->pattern != null) {
372: $data = $this->each($obj . ".{$name}(item);");
373: } else {
374: $data = $obj . ".{$name}(" . $this->literal() . ');';
375: }
376: break;
377: case 'visible':
378: $data = $this->literal() . '.visible();';
379: break;
380: case 'update':
381: $data = $this->literal() . ".update({$args[0]});";
382: break;
383: case 'load':
384: $data = 'new Ajax.Updater("' . $this->id . '", "' . $args[0] . '"';
385: if (isset($args[1]) && is_array($args[1])) {
386: $data .= ', {' . $this->__options($args[1]) . '}';
387: }
388: $data .= ');';
389: break;
390: case 'each':
391: case 'all':
392: case 'any':
393: case 'detect':
394: case 'findAll':
395: if ($this->pattern != null) {
396: $data = $this->__iterate($name, $args[0]);
397: }
398: break;
399: case 'addClass':
400: case 'removeClass':
401: case 'hasClass':
402: case 'toggleClass':
403: $data = $this->literal() . ".{$name}Name(\"{$args[0]}\");";
404: break;
405: case 'clone':
406: case 'inspect':
407: case 'keys':
408: case 'values':
409: $data = "Object.{$name}(" . $this->literal() . ");";
410: break;
411: case 'extend':
412: $data = "Object.extend(" . $this->literal() . ", {$args[0]});";
413: break;
414: case '...':
415:
416:
417:
418: break;
419: default:
420: $data = $this->literal() . '.' . $name . '();';
421: break;
422: }
423:
424: if ($this->__parent->output) {
425: echo $data;
426: } else {
427: return $data;
428: }
429: }
430:
431: function __iterate($method, $data) {
432: return '$$("' . $this->pattern . '").' . $method . '(function(item) {' . $data . '});';
433: }
434:
435: function setParent(&$parent) {
436: $this->__parent =& $parent;
437: }
438:
439: function __options($opts) {
440: $options = array();
441: foreach ($opts as $key => $val) {
442: if (!is_int($val)) {
443: $val = '"' . $val . '"';
444: }
445: $options[] = $key . ':' . $val;
446: }
447: return implode(', ', $options);
448: }
449: }
450: ?>