Fix checkRpItemsPosition
[ryzomcore.git] / web / public_php / webtt / cake / libs / view / helper.php
blobb8bc471fec7a0c3759dbebf31cd079db0d641d5f
1 <?php
2 /**
3 * Backend for helpers.
5 * Internal methods for the Helpers.
7 * PHP versions 4 and 5
9 * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
10 * Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
12 * Licensed under The MIT License
13 * Redistributions of files must retain the above copyright notice.
15 * @copyright Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
16 * @link http://cakephp.org CakePHP(tm) Project
17 * @package cake
18 * @subpackage cake.cake.libs.view
19 * @since CakePHP(tm) v 0.2.9
20 * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
23 /**
24 * Included libs
26 App::import('Core', 'Overloadable');
28 /**
29 * Abstract base class for all other Helpers in CakePHP.
30 * Provides common methods and features.
32 * @package cake
33 * @subpackage cake.cake.libs.view
35 class Helper extends Overloadable {
37 /**
38 * List of helpers used by this helper
40 * @var array
42 var $helpers = null;
44 /**
45 * Base URL
47 * @var string
49 var $base = null;
51 /**
52 * Webroot path
54 * @var string
56 var $webroot = null;
58 /**
59 * The current theme name if any.
61 * @var string
63 var $theme = null;
65 /**
66 * URL to current action.
68 * @var string
70 var $here = null;
72 /**
73 * Parameter array.
75 * @var array
77 var $params = array();
79 /**
80 * Current action.
82 * @var string
84 var $action = null;
86 /**
87 * Plugin path
89 * @var string
91 var $plugin = null;
93 /**
94 * POST data for models
96 * @var array
98 var $data = null;
101 * List of named arguments
103 * @var array
105 var $namedArgs = null;
108 * URL argument separator character
110 * @var string
112 var $argSeparator = null;
115 * Contains model validation errors of form post-backs
117 * @access public
118 * @var array
120 var $validationErrors = null;
123 * Holds tag templates.
125 * @access public
126 * @var array
128 var $tags = array();
131 * Holds the content to be cleaned.
133 * @access private
134 * @var mixed
136 var $__tainted = null;
139 * Holds the cleaned content.
141 * @access private
142 * @var mixed
144 var $__cleaned = null;
147 * Default overload methods
149 * @access protected
151 function get__($name) {}
152 function set__($name, $value) {}
153 function call__($method, $params) {
154 trigger_error(sprintf(__('Method %1$s::%2$s does not exist', true), get_class($this), $method), E_USER_WARNING);
158 * Parses tag templates into $this->tags.
160 * @param $name file name inside app/config to load.
161 * @return array merged tags from config/$name.php
162 * @access public
164 function loadConfig($name = 'tags') {
165 if (file_exists(CONFIGS . $name .'.php')) {
166 require(CONFIGS . $name .'.php');
167 if (isset($tags)) {
168 $this->tags = array_merge($this->tags, $tags);
171 return $this->tags;
175 * Finds URL for specified action.
177 * Returns a URL pointing at the provided parameters.
179 * @param mixed $url Either a relative string url like `/products/view/23` or
180 * an array of url parameters. Using an array for urls will allow you to leverage
181 * the reverse routing features of CakePHP.
182 * @param boolean $full If true, the full base URL will be prepended to the result
183 * @return string Full translated URL with base path.
184 * @access public
185 * @link http://book.cakephp.org/view/1448/url
187 function url($url = null, $full = false) {
188 return h(Router::url($url, $full));
192 * Checks if a file exists when theme is used, if no file is found default location is returned
194 * @param string $file The file to create a webroot path to.
195 * @return string Web accessible path to file.
196 * @access public
198 function webroot($file) {
199 $asset = explode('?', $file);
200 $asset[1] = isset($asset[1]) ? '?' . $asset[1] : null;
201 $webPath = "{$this->webroot}" . $asset[0];
202 $file = $asset[0];
204 if (!empty($this->theme)) {
205 $file = trim($file, '/');
206 $theme = $this->theme . '/';
208 if (DS === '\\') {
209 $file = str_replace('/', '\\', $file);
212 if (file_exists(Configure::read('App.www_root') . 'theme' . DS . $this->theme . DS . $file)) {
213 $webPath = "{$this->webroot}theme/" . $theme . $asset[0];
214 } else {
215 $viewPaths = App::path('views');
217 foreach ($viewPaths as $viewPath) {
218 $path = $viewPath . 'themed'. DS . $this->theme . DS . 'webroot' . DS . $file;
220 if (file_exists($path)) {
221 $webPath = "{$this->webroot}theme/" . $theme . $asset[0];
222 break;
227 if (strpos($webPath, '//') !== false) {
228 return str_replace('//', '/', $webPath . $asset[1]);
230 return $webPath . $asset[1];
234 * Adds a timestamp to a file based resource based on the value of `Asset.timestamp` in
235 * Configure. If Asset.timestamp is true and debug > 0, or Asset.timestamp == 'force'
236 * a timestamp will be added.
238 * @param string $path The file path to timestamp, the path must be inside WWW_ROOT
239 * @return string Path with a timestamp added, or not.
240 * @access public
242 function assetTimestamp($path) {
243 $timestampEnabled = (
244 (Configure::read('Asset.timestamp') === true && Configure::read() > 0) ||
245 Configure::read('Asset.timestamp') === 'force'
247 if (strpos($path, '?') === false && $timestampEnabled) {
248 $filepath = preg_replace('/^' . preg_quote($this->webroot, '/') . '/', '', $path);
249 $webrootPath = WWW_ROOT . str_replace('/', DS, $filepath);
250 if (file_exists($webrootPath)) {
251 return $path . '?' . @filemtime($webrootPath);
253 $segments = explode('/', ltrim($filepath, '/'));
254 if ($segments[0] === 'theme') {
255 $theme = $segments[1];
256 unset($segments[0], $segments[1]);
257 $themePath = App::themePath($theme) . 'webroot' . DS . implode(DS, $segments);
258 return $path . '?' . @filemtime($themePath);
259 } else {
260 $plugin = $segments[0];
261 unset($segments[0]);
262 $pluginPath = App::pluginPath($plugin) . 'webroot' . DS . implode(DS, $segments);
263 return $path . '?' . @filemtime($pluginPath);
266 return $path;
270 * Used to remove harmful tags from content. Removes a number of well known XSS attacks
271 * from content. However, is not guaranteed to remove all possiblities. Escaping
272 * content is the best way to prevent all possible attacks.
274 * @param mixed $output Either an array of strings to clean or a single string to clean.
275 * @return cleaned content for output
276 * @access public
278 function clean($output) {
279 $this->__reset();
280 if (empty($output)) {
281 return null;
283 if (is_array($output)) {
284 foreach ($output as $key => $value) {
285 $return[$key] = $this->clean($value);
287 return $return;
289 $this->__tainted = $output;
290 $this->__clean();
291 return $this->__cleaned;
295 * Returns a space-delimited string with items of the $options array. If a
296 * key of $options array happens to be one of:
298 * - 'compact'
299 * - 'checked'
300 * - 'declare'
301 * - 'readonly'
302 * - 'disabled'
303 * - 'selected'
304 * - 'defer'
305 * - 'ismap'
306 * - 'nohref'
307 * - 'noshade'
308 * - 'nowrap'
309 * - 'multiple'
310 * - 'noresize'
312 * And its value is one of:
314 * - '1' (string)
315 * - 1 (integer)
316 * - true (boolean)
317 * - 'true' (string)
319 * Then the value will be reset to be identical with key's name.
320 * If the value is not one of these 3, the parameter is not output.
322 * 'escape' is a special option in that it controls the conversion of
323 * attributes to their html-entity encoded equivalents. Set to false to disable html-encoding.
325 * If value for any option key is set to `null` or `false`, that option will be excluded from output.
327 * @param array $options Array of options.
328 * @param array $exclude Array of options to be excluded, the options here will not be part of the return.
329 * @param string $insertBefore String to be inserted before options.
330 * @param string $insertAfter String to be inserted after options.
331 * @return string Composed attributes.
332 * @access public
334 function _parseAttributes($options, $exclude = null, $insertBefore = ' ', $insertAfter = null) {
335 if (is_array($options)) {
336 $options = array_merge(array('escape' => true), $options);
338 if (!is_array($exclude)) {
339 $exclude = array();
341 $keys = array_diff(array_keys($options), array_merge($exclude, array('escape')));
342 $values = array_intersect_key(array_values($options), $keys);
343 $escape = $options['escape'];
344 $attributes = array();
346 foreach ($keys as $index => $key) {
347 if ($values[$index] !== false && $values[$index] !== null) {
348 $attributes[] = $this->__formatAttribute($key, $values[$index], $escape);
351 $out = implode(' ', $attributes);
352 } else {
353 $out = $options;
355 return $out ? $insertBefore . $out . $insertAfter : '';
359 * Formats an individual attribute, and returns the string value of the composed attribute.
360 * Works with minimized attributes that have the same value as their name such as 'disabled' and 'checked'
362 * @param string $key The name of the attribute to create
363 * @param string $value The value of the attribute to create.
364 * @return string The composed attribute.
365 * @access private
367 function __formatAttribute($key, $value, $escape = true) {
368 $attribute = '';
369 $attributeFormat = '%s="%s"';
370 $minimizedAttributes = array('compact', 'checked', 'declare', 'readonly', 'disabled',
371 'selected', 'defer', 'ismap', 'nohref', 'noshade', 'nowrap', 'multiple', 'noresize');
372 if (is_array($value)) {
373 $value = '';
376 if (in_array($key, $minimizedAttributes)) {
377 if ($value === 1 || $value === true || $value === 'true' || $value === '1' || $value == $key) {
378 $attribute = sprintf($attributeFormat, $key, $key);
380 } else {
381 $attribute = sprintf($attributeFormat, $key, ($escape ? h($value) : $value));
383 return $attribute;
387 * Sets this helper's model and field properties to the dot-separated value-pair in $entity.
389 * @param mixed $entity A field name, like "ModelName.fieldName" or "ModelName.ID.fieldName"
390 * @param boolean $setScope Sets the view scope to the model specified in $tagValue
391 * @return void
392 * @access public
394 function setEntity($entity, $setScope = false) {
395 $view =& ClassRegistry::getObject('view');
397 if ($setScope) {
398 $view->modelScope = false;
399 } elseif (!empty($view->entityPath) && $view->entityPath == $entity) {
400 return;
403 if ($entity === null) {
404 $view->model = null;
405 $view->association = null;
406 $view->modelId = null;
407 $view->modelScope = false;
408 $view->entityPath = null;
409 return;
412 $view->entityPath = $entity;
413 $model = $view->model;
414 $sameScope = $hasField = false;
415 $parts = array_values(Set::filter(explode('.', $entity), true));
417 if (empty($parts)) {
418 return;
421 $count = count($parts);
422 if ($count === 1) {
423 $sameScope = true;
424 } else {
425 if (is_numeric($parts[0])) {
426 $sameScope = true;
428 $reverse = array_reverse($parts);
429 $field = array_shift($reverse);
430 while(!empty($reverse)) {
431 $subject = array_shift($reverse);
432 if (is_numeric($subject)) {
433 continue;
435 if (ClassRegistry::isKeySet($subject)) {
436 $model = $subject;
437 break;
442 if (ClassRegistry::isKeySet($model)) {
443 $ModelObj =& ClassRegistry::getObject($model);
444 for ($i = 0; $i < $count; $i++) {
445 if (
446 is_a($ModelObj, 'Model') &&
447 ($ModelObj->hasField($parts[$i]) ||
448 array_key_exists($parts[$i], $ModelObj->validate))
450 $hasField = $i;
451 if ($hasField === 0 || ($hasField === 1 && is_numeric($parts[0]))) {
452 $sameScope = true;
454 break;
458 if ($sameScope === true && in_array($parts[0], array_keys($ModelObj->hasAndBelongsToMany))) {
459 $sameScope = false;
463 if (!$view->association && $parts[0] == $view->field && $view->field != $view->model) {
464 array_unshift($parts, $model);
465 $hasField = true;
467 $view->field = $view->modelId = $view->fieldSuffix = $view->association = null;
469 switch (count($parts)) {
470 case 1:
471 if ($view->modelScope === false) {
472 $view->model = $parts[0];
473 } else {
474 $view->field = $parts[0];
475 if ($sameScope === false) {
476 $view->association = $parts[0];
479 break;
480 case 2:
481 if ($view->modelScope === false) {
482 list($view->model, $view->field) = $parts;
483 } elseif ($sameScope === true && $hasField === 0) {
484 list($view->field, $view->fieldSuffix) = $parts;
485 } elseif ($sameScope === true && $hasField === 1) {
486 list($view->modelId, $view->field) = $parts;
487 } else {
488 list($view->association, $view->field) = $parts;
490 break;
491 case 3:
492 if ($sameScope === true && $hasField === 1) {
493 list($view->modelId, $view->field, $view->fieldSuffix) = $parts;
494 } elseif ($hasField === 2) {
495 list($view->association, $view->modelId, $view->field) = $parts;
496 } else {
497 list($view->association, $view->field, $view->fieldSuffix) = $parts;
499 break;
500 case 4:
501 if ($parts[0] === $view->model) {
502 list($view->model, $view->modelId, $view->field, $view->fieldSuffix) = $parts;
503 } else {
504 list($view->association, $view->modelId, $view->field, $view->fieldSuffix) = $parts;
506 break;
507 default:
508 $reverse = array_reverse($parts);
510 if ($hasField) {
511 $view->field = $field;
512 if (!is_numeric($reverse[1]) && $reverse[1] != $model) {
513 $view->field = $reverse[1];
514 $view->fieldSuffix = $field;
517 if (is_numeric($parts[0])) {
518 $view->modelId = $parts[0];
519 } elseif ($view->model == $parts[0] && is_numeric($parts[1])) {
520 $view->modelId = $parts[1];
522 $view->association = $model;
523 break;
526 if (!isset($view->model) || empty($view->model)) {
527 $view->model = $view->association;
528 $view->association = null;
529 } elseif ($view->model === $view->association) {
530 $view->association = null;
533 if ($setScope) {
534 $view->modelScope = true;
539 * Gets the currently-used model of the rendering context.
541 * @return string
542 * @access public
544 function model() {
545 $view =& ClassRegistry::getObject('view');
546 if (!empty($view->association)) {
547 return $view->association;
548 } else {
549 return $view->model;
554 * Gets the ID of the currently-used model of the rendering context.
556 * @return mixed
557 * @access public
559 function modelID() {
560 $view =& ClassRegistry::getObject('view');
561 return $view->modelId;
565 * Gets the currently-used model field of the rendering context.
567 * @return string
568 * @access public
570 function field() {
571 $view =& ClassRegistry::getObject('view');
572 return $view->field;
576 * Returns false if given FORM field has no errors. Otherwise it returns the constant set in
577 * the array Model->validationErrors.
579 * @param string $model Model name as a string
580 * @param string $field Fieldname as a string
581 * @param integer $modelID Unique index identifying this record within the form
582 * @return boolean True on errors.
584 function tagIsInvalid($model = null, $field = null, $modelID = null) {
585 $view =& ClassRegistry::getObject('view');
586 $errors = $this->validationErrors;
587 $entity = $view->entity();
588 if (!empty($entity)) {
589 return Set::extract($errors, join('.', $entity));
594 * Generates a DOM ID for the selected element, if one is not set.
595 * Uses the current View::entity() settings to generate a CamelCased id attribute.
597 * @param mixed $options Either an array of html attributes to add $id into, or a string
598 * with a view entity path to get a domId for.
599 * @param string $id The name of the 'id' attribute.
600 * @return mixed If $options was an array, an array will be returned with $id set. If a string
601 * was supplied, a string will be returned.
602 * @todo Refactor this method to not have as many input/output options.
604 function domId($options = null, $id = 'id') {
605 $view =& ClassRegistry::getObject('view');
607 if (is_array($options) && array_key_exists($id, $options) && $options[$id] === null) {
608 unset($options[$id]);
609 return $options;
610 } elseif (!is_array($options) && $options !== null) {
611 $this->setEntity($options);
612 return $this->domId();
615 $entity = $view->entity();
616 $model = array_shift($entity);
617 $dom = $model . join('', array_map(array('Inflector', 'camelize'), $entity));
619 if (is_array($options) && !array_key_exists($id, $options)) {
620 $options[$id] = $dom;
621 } elseif ($options === null) {
622 return $dom;
624 return $options;
628 * Gets the input field name for the current tag. Creates input name attributes
629 * using CakePHP's data[Model][field] formatting.
631 * @param mixed $options If an array, should be an array of attributes that $key needs to be added to.
632 * If a string or null, will be used as the View entity.
633 * @param string $field
634 * @param string $key The name of the attribute to be set, defaults to 'name'
635 * @return mixed If an array was given for $options, an array with $key set will be returned.
636 * If a string was supplied a string will be returned.
637 * @access protected
638 * @todo Refactor this method to not have as many input/output options.
640 function _name($options = array(), $field = null, $key = 'name') {
641 $view =& ClassRegistry::getObject('view');
642 if ($options === null) {
643 $options = array();
644 } elseif (is_string($options)) {
645 $field = $options;
646 $options = 0;
649 if (!empty($field)) {
650 $this->setEntity($field);
653 if (is_array($options) && array_key_exists($key, $options)) {
654 return $options;
657 switch ($field) {
658 case '_method':
659 $name = $field;
660 break;
661 default:
662 $name = 'data[' . implode('][', $view->entity()) . ']';
663 break;
666 if (is_array($options)) {
667 $options[$key] = $name;
668 return $options;
669 } else {
670 return $name;
675 * Gets the data for the current tag
677 * @param mixed $options If an array, should be an array of attributes that $key needs to be added to.
678 * If a string or null, will be used as the View entity.
679 * @param string $field
680 * @param string $key The name of the attribute to be set, defaults to 'value'
681 * @return mixed If an array was given for $options, an array with $key set will be returned.
682 * If a string was supplied a string will be returned.
683 * @access public
684 * @todo Refactor this method to not have as many input/output options.
686 function value($options = array(), $field = null, $key = 'value') {
687 if ($options === null) {
688 $options = array();
689 } elseif (is_string($options)) {
690 $field = $options;
691 $options = 0;
694 if (is_array($options) && isset($options[$key])) {
695 return $options;
698 if (!empty($field)) {
699 $this->setEntity($field);
702 $view =& ClassRegistry::getObject('view');
703 $result = null;
705 $entity = $view->entity();
706 if (!empty($this->data) && !empty($entity)) {
707 $result = Set::extract($this->data, join('.', $entity));
710 $habtmKey = $this->field();
711 if (empty($result) && isset($this->data[$habtmKey][$habtmKey]) && is_array($this->data[$habtmKey])) {
712 $result = $this->data[$habtmKey][$habtmKey];
713 } elseif (empty($result) && isset($this->data[$habtmKey]) && is_array($this->data[$habtmKey])) {
714 if (ClassRegistry::isKeySet($habtmKey)) {
715 $model =& ClassRegistry::getObject($habtmKey);
716 $result = $this->__selectedArray($this->data[$habtmKey], $model->primaryKey);
720 if (is_array($result)) {
721 if (array_key_exists($view->fieldSuffix, $result)) {
722 $result = $result[$view->fieldSuffix];
726 if (is_array($options)) {
727 if ($result === null && isset($options['default'])) {
728 $result = $options['default'];
730 unset($options['default']);
733 if (is_array($options)) {
734 $options[$key] = $result;
735 return $options;
736 } else {
737 return $result;
742 * Sets the defaults for an input tag. Will set the
743 * name, value, and id attributes for an array of html attributes. Will also
744 * add a 'form-error' class if the field contains validation errors.
746 * @param string $field The field name to initialize.
747 * @param array $options Array of options to use while initializing an input field.
748 * @return array Array options for the form input.
749 * @access protected
751 function _initInputField($field, $options = array()) {
752 if ($field !== null) {
753 $this->setEntity($field);
755 $options = (array)$options;
756 $options = $this->_name($options);
757 $options = $this->value($options);
758 $options = $this->domId($options);
759 if ($this->tagIsInvalid()) {
760 $options = $this->addClass($options, 'form-error');
762 return $options;
766 * Adds the given class to the element options
768 * @param array $options Array options/attributes to add a class to
769 * @param string $class The classname being added.
770 * @param string $key the key to use for class.
771 * @return array Array of options with $key set.
772 * @access public
774 function addClass($options = array(), $class = null, $key = 'class') {
775 if (isset($options[$key]) && trim($options[$key]) != '') {
776 $options[$key] .= ' ' . $class;
777 } else {
778 $options[$key] = $class;
780 return $options;
784 * Returns a string generated by a helper method
786 * This method can be overridden in subclasses to do generalized output post-processing
788 * @param string $str String to be output.
789 * @return string
790 * @deprecated This method will be removed in future versions.
792 function output($str) {
793 return $str;
797 * Before render callback. beforeRender is called before the view file is rendered.
799 * Overridden in subclasses.
801 * @return void
802 * @access public
804 function beforeRender() {
808 * After render callback. afterRender is called after the view file is rendered
809 * but before the layout has been rendered.
811 * Overridden in subclasses.
813 * @return void
814 * @access public
816 function afterRender() {
820 * Before layout callback. beforeLayout is called before the layout is rendered.
822 * Overridden in subclasses.
824 * @return void
825 * @access public
827 function beforeLayout() {
831 * After layout callback. afterLayout is called after the layout has rendered.
833 * Overridden in subclasses.
835 * @return void
836 * @access public
838 function afterLayout() {
842 * Transforms a recordset from a hasAndBelongsToMany association to a list of selected
843 * options for a multiple select element
845 * @param mixed $data
846 * @param string $key
847 * @return array
848 * @access private
850 function __selectedArray($data, $key = 'id') {
851 if (!is_array($data)) {
852 $model = $data;
853 if (!empty($this->data[$model][$model])) {
854 return $this->data[$model][$model];
856 if (!empty($this->data[$model])) {
857 $data = $this->data[$model];
860 $array = array();
861 if (!empty($data)) {
862 foreach ($data as $var) {
863 $array[$var[$key]] = $var[$key];
866 return $array;
870 * Resets the vars used by Helper::clean() to null
872 * @return void
873 * @access private
875 function __reset() {
876 $this->__tainted = null;
877 $this->__cleaned = null;
881 * Removes harmful content from output
883 * @return void
884 * @access private
886 function __clean() {
887 if (get_magic_quotes_gpc()) {
888 $this->__cleaned = stripslashes($this->__tainted);
889 } else {
890 $this->__cleaned = $this->__tainted;
893 $this->__cleaned = str_replace(array("&amp;", "&lt;", "&gt;"), array("&amp;amp;", "&amp;lt;", "&amp;gt;"), $this->__cleaned);
894 $this->__cleaned = preg_replace('#(&\#*\w+)[\x00-\x20]+;#u', "$1;", $this->__cleaned);
895 $this->__cleaned = preg_replace('#(&\#x*)([0-9A-F]+);*#iu', "$1$2;", $this->__cleaned);
896 $this->__cleaned = html_entity_decode($this->__cleaned, ENT_COMPAT, "UTF-8");
897 $this->__cleaned = preg_replace('#(<[^>]+[\x00-\x20\"\'\/])(on|xmlns)[^>]*>#iUu', "$1>", $this->__cleaned);
898 $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);
899 $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);
900 $this->__cleaned = preg_replace('#([a-z]*)[\x00-\x20]*=*([\'\"]*)[\x00-\x20]*-moz-binding[\x00-\x20]*:#iUu','$1=$2nomozbinding...', $this->__cleaned);
901 $this->__cleaned = preg_replace('#([a-z]*)[\x00-\x20]*=([\'\"]*)[\x00-\x20]*data[\x00-\x20]*:#Uu', '$1=$2nodata...', $this->__cleaned);
902 $this->__cleaned = preg_replace('#(<[^>]+)style[\x00-\x20]*=[\x00-\x20]*([\`\'\"]*).*expression[\x00-\x20]*\([^>]*>#iU', "$1>", $this->__cleaned);
903 $this->__cleaned = preg_replace('#(<[^>]+)style[\x00-\x20]*=[\x00-\x20]*([\`\'\"]*).*behaviour[\x00-\x20]*\([^>]*>#iU', "$1>", $this->__cleaned);
904 $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);
905 $this->__cleaned = preg_replace('#</*\w+:\w[^>]*>#i', "", $this->__cleaned);
906 do {
907 $oldstring = $this->__cleaned;
908 $this->__cleaned = preg_replace('#</*(applet|meta|xml|blink|link|style|script|embed|object|iframe|frame|frameset|ilayer|layer|bgsound|title|base)[^>]*>#i', "", $this->__cleaned);
909 } while ($oldstring != $this->__cleaned);
910 $this->__cleaned = str_replace(array("&amp;", "&lt;", "&gt;"), array("&amp;amp;", "&amp;lt;", "&amp;gt;"), $this->__cleaned);