PageRenderTime 25ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/oiclient/data/symfony/plugins/sfCompat10Plugin/lib/util/sfFillInForm.class.php

http://openirudi.googlecode.com/
PHP | 273 lines | 204 code | 28 blank | 41 comment | 49 complexity | 38093400008c75178156b9e9285afade MD5 | raw file
Possible License(s): LGPL-2.1, AGPL-3.0
  1. <?php
  2. /*
  3. * This file is part of the symfony package.
  4. * (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
  5. *
  6. * For the full copyright and license information, please view the LICENSE
  7. * file that was distributed with this source code.
  8. */
  9. /**
  10. *
  11. * WARNING: This class is deprecated and will be removed in symfony 1.2.
  12. *
  13. * @package symfony
  14. * @subpackage util
  15. * @author Fabien Potencier <fabien.potencier@symfony-project.com>
  16. * @version SVN: $Id: sfFillInForm.class.php 10270 2008-07-13 21:51:03Z Carl.Vondrick $
  17. * @deprecated Deprecated since symfony 1.1
  18. */
  19. class sfFillInForm
  20. {
  21. protected
  22. $converters = array(),
  23. $skipFields = array(),
  24. $types = array('text', 'checkbox', 'radio', 'hidden', 'password');
  25. public function addConverter($callable, $fields)
  26. {
  27. foreach ((array) $fields as $field)
  28. {
  29. $this->converters[$field][] = $callable;
  30. }
  31. }
  32. public function setSkipFields($fields)
  33. {
  34. $this->skipFields = $fields;
  35. }
  36. public function setTypes($types)
  37. {
  38. $this->types = $types;
  39. }
  40. /**
  41. * fills in the values and returns HTML. This is a non validating tolerant mode.
  42. *
  43. * @return HTML with values filled in
  44. */
  45. public function fillInHtml($html, $formName, $formId, $values)
  46. {
  47. $dom = new DomDocument('1.0', sfConfig::get('sf_charset', 'UTF-8'));
  48. $noHead = strpos($html,'<head') === false;
  49. if ($noHead){
  50. // loadHTML needs the conent-type meta for the charset
  51. $html = '<meta http-equiv="Content-Type" content="text/html; charset='.sfConfig::get('sf_charset').'"/>'.$html;
  52. }
  53. @$dom->loadHTML($html);
  54. $dom = $this->fillInDom($dom, $formName, $formId, $values);
  55. if($noHead){
  56. // remove the head element that was created by adding the meta tag.
  57. $headElement = $dom->getElementsByTagName('head')->item(0);
  58. if ($headElement)
  59. {
  60. $dom->getElementsByTagName('html')->item(0)->removeChild($headElement);
  61. }
  62. }
  63. return $dom->saveHTML();
  64. }
  65. /**
  66. * fills in the values and returns XHTML. This is same as XML but stripts the XML Prolog.
  67. *
  68. * @return XHTML without prolog with values filled in
  69. */
  70. public function fillInXhtml($xml, $formName, $formId, $values)
  71. {
  72. $xhtml = $this->fillInXml($xml, $formName, $formId, $values);
  73. $prolog_regexp = '/^' . preg_quote('<?xml version="1.0"?>') . '\s*/';
  74. return preg_replace($prolog_regexp, '', $xhtml);
  75. }
  76. /**
  77. * fills in the values and returns XHTML. It can only work correctly on validating XHTML.
  78. *
  79. * @return XHTML including XML prolog with values filled in
  80. */
  81. public function fillInXml($xml, $formName, $formId, $values)
  82. {
  83. $dom = new DomDocument('1.0', sfConfig::get('sf_charset', 'UTF-8'));
  84. if (strpos($xml,'<!DOCTYPE') === false)
  85. {
  86. $xml = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" '.
  87. '"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'.
  88. $xml;
  89. }
  90. @$dom->loadXML($xml);
  91. $dom = $this->fillInDom($dom, $formName, $formId, $values);
  92. return $dom->saveXML();
  93. }
  94. public function fillInDom($dom, $formName, $formId, $values)
  95. {
  96. $xpath = new DomXPath($dom);
  97. if ($dom->documentElement && $dom->documentElement->namespaceURI)
  98. {
  99. $xpath->registerNamespace('xhtml', $dom->documentElement->namespaceURI);
  100. $ns = 'xhtml:';
  101. }
  102. else
  103. {
  104. $ns = '';
  105. }
  106. // find our form
  107. if ($formName)
  108. {
  109. $xpath_query = '//'.$ns.'form[@name="'.$formName.'"]';
  110. }
  111. elseif ($formId)
  112. {
  113. $xpath_query = '//'.$ns.'form[@id="'.$formId.'"]';
  114. }
  115. else
  116. {
  117. $xpath_query = '//'.$ns.'form';
  118. }
  119. $form = $xpath->query($xpath_query)->item(0);
  120. if (!$form)
  121. {
  122. if (!$formName && !$formId)
  123. {
  124. throw new sfException('No form found in this page.');
  125. }
  126. else
  127. {
  128. throw new sfException(sprintf('The form "%s" cannot be found.', $formName ? $formName : $formId));
  129. }
  130. }
  131. $query = 'descendant::'.$ns.'input[@name and (not(@type)';
  132. foreach ($this->types as $type)
  133. {
  134. $query .= ' or @type="'.$type.'"';
  135. }
  136. $query .= ')] | descendant::'.$ns.'textarea[@name] | descendant::'.$ns.'select[@name]';
  137. foreach ($xpath->query($query, $form) as $element)
  138. {
  139. $name = (string) $element->getAttribute('name');
  140. $value = (string) $element->getAttribute('value');
  141. $type = (string) $element->getAttribute('type');
  142. // skip fields
  143. if (!$this->hasValue($values, $name) || in_array($name, $this->skipFields))
  144. {
  145. continue;
  146. }
  147. if ($element->nodeName == 'input')
  148. {
  149. if ($type == 'checkbox' || $type == 'radio')
  150. {
  151. // checkbox and radio
  152. $element->removeAttribute('checked');
  153. if (is_array($this->getValue($values, $name)) && ($this->hasValue($values, $name) || !$element->hasAttribute('value')))
  154. {
  155. if (in_array($value, $this->getValue($values, $name)))
  156. {
  157. $element->setAttribute('checked', 'checked');
  158. }
  159. }
  160. else if ($this->hasValue($values, $name) && ($this->getValue($values, $name) == $value || !$element->hasAttribute('value')))
  161. {
  162. $element->setAttribute('checked', 'checked');
  163. }
  164. }
  165. else
  166. {
  167. // text input
  168. $element->removeAttribute('value');
  169. $element->setAttribute('value', $this->escapeValue($this->getValue($values, $name, true), $name));
  170. }
  171. }
  172. else if ($element->nodeName == 'textarea')
  173. {
  174. $el = $element->cloneNode(false);
  175. $el->appendChild($dom->createTextNode($this->escapeValue($this->getValue($values, $name, true), $name)));
  176. $element->parentNode->replaceChild($el, $element);
  177. }
  178. else if ($element->nodeName == 'select')
  179. {
  180. // if the name contains [] it is part of an array that needs to be shifted
  181. $value = $this->getValue($values, $name, strpos($name,'[]') !== false);
  182. $multiple = $element->hasAttribute('multiple');
  183. foreach ($xpath->query('descendant::'.$ns.'option', $element) as $option)
  184. {
  185. $option->removeAttribute('selected');
  186. if ($multiple && is_array($value))
  187. {
  188. if (in_array($option->getAttribute('value'), $value))
  189. {
  190. $option->setAttribute('selected', 'selected');
  191. }
  192. }
  193. else if ($value == $option->getAttribute('value'))
  194. {
  195. $option->setAttribute('selected', 'selected');
  196. }
  197. }
  198. }
  199. }
  200. return $dom;
  201. }
  202. protected function hasValue($values, $name)
  203. {
  204. if (array_key_exists($name, $values))
  205. {
  206. return true;
  207. }
  208. return sfToolkit::hasArrayValueForPath($values, $name);
  209. }
  210. // use reference to values so that arrays can be shifted.
  211. protected function getValue(&$values, $name, $shiftArray = false)
  212. {
  213. if (array_key_exists($name, $values))
  214. {
  215. $return = &$values[$name];
  216. } else {
  217. $return = &sfToolkit::getArrayValueForPathByRef($values, $name);
  218. }
  219. if ($shiftArray && is_array($return))
  220. {
  221. // we need to remove the first element from the array. Therefore we need a reference
  222. return array_shift($return);
  223. }
  224. return $return;
  225. }
  226. protected function escapeValue($value, $name)
  227. {
  228. if (function_exists('iconv') && strtolower(sfConfig::get('sf_charset')) != 'utf-8')
  229. {
  230. $new_value = iconv(sfConfig::get('sf_charset'), 'UTF-8', $value);
  231. if (false !== $new_value)
  232. {
  233. $value = $new_value;
  234. }
  235. }
  236. if (isset($this->converters[$name]))
  237. {
  238. foreach ($this->converters[$name] as $callable)
  239. {
  240. $value = call_user_func($callable, $value);
  241. }
  242. }
  243. return $value;
  244. }
  245. }