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: ?>