Development

/branches/1.1/lib/plugins/sfCompat10Plugin/lib/util/sfFillInForm.class.php

You must first sign up to be able to contribute.

root/branches/1.1/lib/plugins/sfCompat10Plugin/lib/util/sfFillInForm.class.php

Revision 10270, 7.7 kB (checked in by Carl.Vondrick, 6 years ago)

1.1: added deprecated warnings to all sfCompatPlugin classes (closes #3882)

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