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: App::import('Core', 'Overloadable');
30:
31: 32: 33: 34: 35: 36: 37: 38:
39: class Helper extends Overloadable {
40: 41: 42: 43: 44:
45: var $helpers = null;
46: 47: 48: 49: 50:
51: var $base = null;
52: 53: 54: 55: 56:
57: var $webroot = null;
58: 59: 60: 61: 62:
63: var $themeWeb = null;
64: 65: 66: 67: 68:
69: var $here = null;
70: 71: 72: 73: 74:
75: var $params = array();
76: 77: 78: 79: 80:
81: var $action = null;
82: 83: 84: 85: 86:
87: var $plugin = null;
88: 89: 90: 91: 92:
93: var $data = null;
94: 95: 96: 97: 98:
99: var $namedArgs = null;
100: 101: 102: 103: 104:
105: var $argSeparator = null;
106: 107: 108: 109: 110: 111:
112: var $validationErrors = null;
113: 114: 115: 116: 117: 118:
119: var $tags = array();
120: 121: 122: 123: 124: 125:
126: var $__tainted = null;
127: 128: 129: 130: 131: 132:
133: var $__cleaned = null;
134: 135: 136: 137: 138:
139: function get__($name) {}
140: function set__($name, $value) {}
141: function call__($method, $params) {
142: trigger_error(sprintf(__('Method %1$s::%2$s does not exist', true), get_class($this), $method), E_USER_WARNING);
143: }
144:
145: 146: 147: 148: 149: 150:
151: function loadConfig($name = 'tags') {
152: if (file_exists(CONFIGS . $name .'.php')) {
153: require(CONFIGS . $name .'.php');
154: if (isset($tags)) {
155: $this->tags = array_merge($this->tags, $tags);
156: }
157: }
158: return $this->tags;
159: }
160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175:
176: function url($url = null, $full = false) {
177: return h(Router::url($url, $full));
178: }
179: 180: 181: 182: 183: 184:
185: function webroot($file) {
186: $webPath = "{$this->webroot}" . $file;
187: if (!empty($this->themeWeb)) {
188: $os = env('OS');
189: if (!empty($os) && strpos($os, 'Windows') !== false) {
190: if (strpos(WWW_ROOT . $this->themeWeb . $file, '\\') !== false) {
191: $path = str_replace('/', '\\', WWW_ROOT . $this->themeWeb . $file);
192: }
193: } else {
194: $path = WWW_ROOT . $this->themeWeb . $file;
195: }
196: if (file_exists($path)) {
197: $webPath = "{$this->webroot}" . $this->themeWeb . $file;
198: }
199: }
200: if (strpos($webPath, '//') !== false) {
201: return str_replace('//', '/', $webPath);
202: }
203: return $webPath;
204: }
205:
206: 207: 208: 209: 210: 211: 212:
213: function clean($output) {
214: $this->__reset();
215: if (empty($output)) {
216: return null;
217: }
218: if (is_array($output)) {
219: foreach ($output as $key => $value) {
220: $return[$key] = $this->clean($value);
221: }
222: return $return;
223: }
224: $this->__tainted = $output;
225: $this->__clean();
226: return $this->__cleaned;
227: }
228: 229: 230: 231: 232: 233: 234: 235: 236: 237: 238: 239: 240: 241: 242: 243: 244: 245: 246: 247: 248: 249: 250: 251: 252: 253: 254: 255: 256: 257: 258:
259: function _parseAttributes($options, $exclude = null, $insertBefore = ' ', $insertAfter = null) {
260: if (is_array($options)) {
261: $options = array_merge(array('escape' => true), $options);
262:
263: if (!is_array($exclude)) {
264: $exclude = array();
265: }
266: $keys = array_diff(array_keys($options), array_merge((array)$exclude, array('escape')));
267: $values = array_intersect_key(array_values($options), $keys);
268: $escape = $options['escape'];
269: $attributes = array();
270:
271: foreach ($keys as $index => $key) {
272: $attributes[] = $this->__formatAttribute($key, $values[$index], $escape);
273: }
274: $out = implode(' ', $attributes);
275: } else {
276: $out = $options;
277: }
278: return $out ? $insertBefore . $out . $insertAfter : '';
279: }
280: 281: 282: 283: 284: 285:
286: function __formatAttribute($key, $value, $escape = true) {
287: $attribute = '';
288: $attributeFormat = '%s="%s"';
289: $minimizedAttributes = array('compact', 'checked', 'declare', 'readonly', 'disabled', 'selected', 'defer', 'ismap', 'nohref', 'noshade', 'nowrap', 'multiple', 'noresize');
290: if (is_array($value)) {
291: $value = '';
292: }
293:
294: if (in_array($key, $minimizedAttributes)) {
295: if ($value === 1 || $value === true || $value === 'true' || $value == $key) {
296: $attribute = sprintf($attributeFormat, $key, $key);
297: }
298: } else {
299: $attribute = sprintf($attributeFormat, $key, ($escape ? h($value) : $value));
300: }
301: return $attribute;
302: }
303: 304: 305: 306: 307: 308: 309:
310: function setEntity($entity, $setScope = false) {
311: $view =& ClassRegistry::getObject('view');
312:
313: if ($setScope) {
314: $view->modelScope = false;
315: } elseif (implode('.', $view->entity()) == $entity) {
316: return;
317: }
318:
319: if ($entity === null) {
320: $view->model = null;
321: $view->association = null;
322: $view->modelId = null;
323: $view->modelScope = false;
324: return;
325: }
326:
327: $model = $view->model;
328: $sameScope = $hasField = false;
329: $parts = array_values(Set::filter(explode('.', $entity), true));
330:
331: if (empty($parts)) {
332: return;
333: }
334:
335: if (count($parts) === 1 || is_numeric($parts[0])) {
336: $sameScope = true;
337: } else {
338: if (ClassRegistry::isKeySet($parts[0])) {
339: $model = $parts[0];
340: }
341: }
342:
343: if (ClassRegistry::isKeySet($model)) {
344: $ModelObj =& ClassRegistry::getObject($model);
345: for ($i = 0; $i < count($parts); $i++) {
346: if ($ModelObj->hasField($parts[$i]) || array_key_exists($parts[$i], $ModelObj->validate)) {
347: $hasField = $i;
348: if ($hasField === 0 || ($hasField === 1 && is_numeric($parts[0]))) {
349: $sameScope = true;
350: }
351: break;
352: }
353: }
354:
355: if ($sameScope === true && in_array($parts[0], array_keys($ModelObj->hasAndBelongsToMany))) {
356: $sameScope = false;
357: }
358: }
359:
360: if (!$view->association && $parts[0] == $view->field && $view->field != $view->model) {
361: array_unshift($parts, $model);
362: $hasField = true;
363: }
364: $view->field = $view->modelId = $view->fieldSuffix = $view->association = null;
365:
366: switch (count($parts)) {
367: case 1:
368: if ($view->modelScope === false) {
369: $view->model = $parts[0];
370: } else {
371: $view->field = $parts[0];
372: if ($sameScope === false) {
373: $view->association = $parts[0];
374: }
375: }
376: break;
377: case 2:
378: if ($view->modelScope === false) {
379: list($view->model, $view->field) = $parts;
380: } elseif ($sameScope === true && $hasField === 0) {
381: list($view->field, $view->fieldSuffix) = $parts;
382: } elseif ($sameScope === true && $hasField === 1) {
383: list($view->modelId, $view->field) = $parts;
384: } else {
385: list($view->association, $view->field) = $parts;
386: }
387: break;
388: case 3:
389: if ($sameScope === true && $hasField === 1) {
390: list($view->modelId, $view->field, $view->fieldSuffix) = $parts;
391: } elseif ($hasField === 2) {
392: list($view->association, $view->modelId, $view->field) = $parts;
393: } else {
394: list($view->association, $view->field, $view->fieldSuffix) = $parts;
395: }
396: break;
397: case 4:
398: if ($parts[0] === $view->model) {
399: list($view->model, $view->modelId, $view->field, $view->fieldSuffix) = $parts;
400: } else {
401: list($view->association, $view->modelId, $view->field, $view->fieldSuffix) = $parts;
402: }
403: break;
404: }
405:
406: if (!isset($view->model) || empty($view->model)) {
407: $view->model = $view->association;
408: $view->association = null;
409: } elseif ($view->model === $view->association) {
410: $view->association = null;
411: }
412:
413: if ($setScope) {
414: $view->modelScope = true;
415: }
416: }
417: 418: 419: 420: 421:
422: function model() {
423: $view =& ClassRegistry::getObject('view');
424: if (!empty($view->association)) {
425: return $view->association;
426: } else {
427: return $view->model;
428: }
429: }
430: 431: 432: 433: 434:
435: function modelID() {
436: $view =& ClassRegistry::getObject('view');
437: return $view->modelId;
438: }
439: 440: 441: 442: 443:
444: function field() {
445: $view =& ClassRegistry::getObject('view');
446: return $view->field;
447: }
448: 449: 450: 451: 452: 453: 454: 455:
456: function tagIsInvalid($model = null, $field = null, $modelID = null) {
457: foreach (array('model', 'field', 'modelID') as $key) {
458: if (empty(${$key})) {
459: ${$key} = $this->{$key}();
460: }
461: }
462: $view =& ClassRegistry::getObject('view');
463: $errors = $this->validationErrors;
464:
465: if ($view->model !== $model && isset($errors[$view->model][$model])) {
466: $errors = $errors[$view->model];
467: }
468:
469: if (!isset($modelID)) {
470: return empty($errors[$model][$field]) ? 0 : $errors[$model][$field];
471: } else {
472: return empty($errors[$model][$modelID][$field]) ? 0 : $errors[$model][$modelID][$field];
473: }
474: }
475: 476: 477: 478: 479: 480: 481:
482: function domId($options = null, $id = 'id') {
483: $view =& ClassRegistry::getObject('view');
484:
485: if (is_array($options) && array_key_exists($id, $options) && $options[$id] === null) {
486: unset($options[$id]);
487: return $options;
488: } elseif (!is_array($options) && $options !== null) {
489: $this->setEntity($options);
490: return $this->domId();
491: }
492:
493: $dom = $this->model() . $this->modelID() . Inflector::camelize($view->field) . Inflector::camelize($view->fieldSuffix);
494:
495: if (is_array($options) && !array_key_exists($id, $options)) {
496: $options[$id] = $dom;
497: } elseif ($options === null) {
498: return $dom;
499: }
500: return $options;
501: }
502: 503: 504: 505: 506: 507: 508:
509: function __name($options = array(), $field = null, $key = 'name') {
510: $view =& ClassRegistry::getObject('view');
511:
512: if ($options === null) {
513: $options = array();
514: } elseif (is_string($options)) {
515: $field = $options;
516: $options = 0;
517: }
518:
519: if (!empty($field)) {
520: $this->setEntity($field);
521: }
522:
523: if (is_array($options) && array_key_exists($key, $options)) {
524: return $options;
525: }
526:
527: switch ($field) {
528: case '_method':
529: $name = $field;
530: break;
531: default:
532: $name = 'data[' . implode('][', $view->entity()) . ']';
533: break;
534: }
535:
536: if (is_array($options)) {
537: $options[$key] = $name;
538: return $options;
539: } else {
540: return $name;
541: }
542: }
543: 544: 545: 546: 547: 548: 549: 550:
551: function value($options = array(), $field = null, $key = 'value') {
552: if ($options === null) {
553: $options = array();
554: } elseif (is_string($options)) {
555: $field = $options;
556: $options = 0;
557: }
558:
559: if (!empty($field)) {
560: $this->setEntity($field);
561: }
562:
563: if (is_array($options) && isset($options[$key])) {
564: return $options;
565: }
566:
567: $result = null;
568:
569: $modelName = $this->model();
570: $fieldName = $this->field();
571: $modelID = $this->modelID();
572:
573: if (is_null($fieldName)) {
574: $fieldName = $modelName;
575: $modelName = null;
576: }
577:
578: if (isset($this->data[$fieldName]) && $modelName === null) {
579: $result = $this->data[$fieldName];
580: } elseif (isset($this->data[$modelName][$fieldName])) {
581: $result = $this->data[$modelName][$fieldName];
582: } elseif (isset($this->data[$fieldName]) && is_array($this->data[$fieldName])) {
583: if (ClassRegistry::isKeySet($fieldName)) {
584: $model =& ClassRegistry::getObject($fieldName);
585: $result = $this->__selectedArray($this->data[$fieldName], $model->primaryKey);
586: }
587: } elseif (isset($this->data[$modelName][$modelID][$fieldName])) {
588: $result = $this->data[$modelName][$modelID][$fieldName];
589: }
590:
591: if (is_array($result)) {
592: $view =& ClassRegistry::getObject('view');
593: if (array_key_exists($view->fieldSuffix, $result)) {
594: $result = $result[$view->fieldSuffix];
595: }
596: }
597:
598: if (is_array($options)) {
599: if (empty($result) && isset($options['default'])) {
600: $result = $options['default'];
601: }
602: unset($options['default']);
603: }
604:
605: if (is_array($options)) {
606: $options[$key] = $result;
607: return $options;
608: } else {
609: return $result;
610: }
611: }
612: 613: 614: 615: 616: 617: 618: 619:
620: function _initInputField($field, $options = array()) {
621: if ($field !== null) {
622: $this->setEntity($field);
623: }
624: $options = (array)$options;
625: $options = $this->__name($options);
626: $options = $this->value($options);
627: $options = $this->domId($options);
628: if ($this->tagIsInvalid()) {
629: $options = $this->addClass($options, 'form-error');
630: }
631: return $options;
632: }
633: 634: 635: 636: 637: 638: 639: 640:
641: function addClass($options = array(), $class = null, $key = 'class') {
642: if (isset($options[$key]) && trim($options[$key]) != '') {
643: $options[$key] .= ' ' . $class;
644: } else {
645: $options[$key] = $class;
646: }
647: return $options;
648: }
649: 650: 651: 652: 653: 654: 655: 656:
657: function output($str) {
658: return $str;
659: }
660: 661: 662: 663:
664: function beforeRender() {
665: }
666: 667: 668: 669:
670: function afterRender() {
671: }
672: 673: 674: 675:
676: function beforeLayout() {
677: }
678: 679: 680: 681:
682: function afterLayout() {
683: }
684: 685: 686: 687: 688: 689: 690: 691: 692:
693: function __selectedArray($data, $key = 'id') {
694: if (!is_array($data)) {
695: $model = $data;
696: if (!empty($this->data[$model][$model])) {
697: return $this->data[$model][$model];
698: }
699: if (!empty($this->data[$model])) {
700: $data = $this->data[$model];
701: }
702: }
703: $array = array();
704: if (!empty($data)) {
705: foreach ($data as $var) {
706: $array[$var[$key]] = $var[$key];
707: }
708: }
709: return $array;
710: }
711: 712: 713: 714: 715:
716: function __reset() {
717: $this->__tainted = null;
718: $this->__cleaned = null;
719: }
720: 721: 722: 723: 724:
725: function __clean() {
726: if (get_magic_quotes_gpc()) {
727: $this->__cleaned = stripslashes($this->__tainted);
728: } else {
729: $this->__cleaned = $this->__tainted;
730: }
731:
732: $this->__cleaned = str_replace(array("&", "<", ">"), array("&amp;", "&lt;", "&gt;"), $this->__cleaned);
733: $this->__cleaned = preg_replace('#(&\#*\w+)[\x00-\x20]+;#u', "$1;", $this->__cleaned);
734: $this->__cleaned = preg_replace('#(&\#x*)([0-9A-F]+);*#iu', "$1$2;", $this->__cleaned);
735: $this->__cleaned = html_entity_decode($this->__cleaned, ENT_COMPAT, "UTF-8");
736: $this->__cleaned = preg_replace('#(<[^>]+[\x00-\x20\"\'\/])(on|xmlns)[^>]*>#iUu', "$1>", $this->__cleaned);
737: $this->__cleaned = preg_replace('#([a-z]*)[\x00-\x20]*=[\x00-\x20]*([\`\'\"]*)[\\x00-\x20]*j[\x00-\x20]*a[\x00-\x20]*v[\x00-\x20]*a[\x00-\x20]*s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:#iUu', '$1=$2nojavascript...', $this->__cleaned);
738: $this->__cleaned = preg_replace('#([a-z]*)[\x00-\x20]*=([\'\"]*)[\x00-\x20]*v[\x00-\x20]*b[\x00-\x20]*s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:#iUu', '$1=$2novbscript...', $this->__cleaned);
739: $this->__cleaned = preg_replace('#([a-z]*)[\x00-\x20]*=*([\'\"]*)[\x00-\x20]*-moz-binding[\x00-\x20]*:#iUu','$1=$2nomozbinding...', $this->__cleaned);
740: $this->__cleaned = preg_replace('#([a-z]*)[\x00-\x20]*=([\'\"]*)[\x00-\x20]*data[\x00-\x20]*:#Uu', '$1=$2nodata...', $this->__cleaned);
741: $this->__cleaned = preg_replace('#(<[^>]+)style[\x00-\x20]*=[\x00-\x20]*([\`\'\"]*).*expression[\x00-\x20]*\([^>]*>#iU', "$1>", $this->__cleaned);
742: $this->__cleaned = preg_replace('#(<[^>]+)style[\x00-\x20]*=[\x00-\x20]*([\`\'\"]*).*behaviour[\x00-\x20]*\([^>]*>#iU', "$1>", $this->__cleaned);
743: $this->__cleaned = preg_replace('#(<[^>]+)style[\x00-\x20]*=[\x00-\x20]*([\`\'\"]*).*s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:*[^>]*>#iUu', "$1>", $this->__cleaned);
744: $this->__cleaned = preg_replace('#</*\w+:\w[^>]*>#i', "", $this->__cleaned);
745: do {
746: $oldstring = $this->__cleaned;
747: $this->__cleaned = preg_replace('#</*(applet|meta|xml|blink|link|style|script|embed|object|iframe|frame|frameset|ilayer|layer|bgsound|title|base)[^>]*>#i', "", $this->__cleaned);
748: } while ($oldstring != $this->__cleaned);
749: $this->__cleaned = str_replace(array("&", "<", ">"), array("&amp;", "&lt;", "&gt;"), $this->__cleaned);
750: }
751: }
752: ?>