Development

/branches/1.3/lib/widget/sfWidgetForm.class.php

You must first sign up to be able to contribute.

root/branches/1.3/lib/widget/sfWidgetForm.class.php

Revision 24137, 8.9 kB (checked in by fabien, 4 years ago)

[1.3, 1.4] fixed invalid id attributes generation in sfWidgetForm (closes #6980, based on a patch from Leon.van.der.Ree)

  • 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) 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  * sfWidgetForm is the base class for all form widgets.
13  *
14  * @package    symfony
15  * @subpackage widget
16  * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
17  * @version    SVN: $Id$
18  */
19 abstract class sfWidgetForm extends sfWidget
20 {
21   protected
22     $parent   = null;
23
24   /**
25    * Constructor.
26    *
27    * Available options:
28    *
29    *  * id_format:       The format for the generated HTML id attributes (%s by default)
30    *  * is_hidden:       true if the form widget must be hidden, false otherwise (false by default)
31    *  * needs_multipart: true if the form widget needs a multipart form, false otherwise (false by default)
32    *  * default:         The default value to use when rendering the widget
33    *  * label:           The label to use when the widget is rendered by a widget schema
34    *
35    * @param array $options     An array of options
36    * @param array $attributes  An array of default HTML attributes
37    *
38    * @see sfWidget
39    */
40   public function __construct($options = array(), $attributes = array())
41   {
42     $this->addOption('id_format', '%s');
43     $this->addOption('is_hidden', false);
44     $this->addOption('needs_multipart', false);
45     $this->addOption('default', null);
46     $this->addOption('label', null);
47
48     parent::__construct($options, $attributes);
49   }
50
51   /**
52    * Sets the default value for the widget.
53    *
54    * @param string $value The default value
55    *
56    * @return sfWidget The current widget instance
57    */
58   public function setDefault($value)
59   {
60     $this->setOption('default', $value);
61
62     return $this;
63   }
64
65   /**
66    * Returns the default value for the widget.
67    *
68    * @return string The default value
69    */
70   public function getDefault()
71   {
72     return $this->getOption('default');
73   }
74
75   /**
76    * Sets the label for the widget.
77    *
78    * @param string $value The label
79    *
80    * @return sfWidget The current widget instance
81    */
82   public function setLabel($value)
83   {
84     $this->setOption('label', $value);
85
86     return $this;
87   }
88
89   /**
90    * Returns the label for the widget.
91    *
92    * @return string The label
93    */
94   public function getLabel()
95   {
96     return $this->getOption('label');
97   }
98
99   /**
100    * Sets the format for HTML id attributes.
101    *
102    * @param string $format  The format string (must contain a %s for the id placeholder)
103    *
104    * @return sfWidget The current widget instance
105    */
106   public function setIdFormat($format)
107   {
108     $this->setOption('id_format', $format);
109
110     return $this;
111   }
112
113   /**
114    * Gets the HTML format string for id attributes.
115    *
116    * @return string The format string
117    */
118   public function getIdFormat()
119   {
120     return $this->getOption('id_format');
121   }
122
123   /**
124    * Returns true if the widget is hidden.
125    *
126    * @return Boolean true if the widget is hidden, false otherwise
127    */
128   public function isHidden()
129   {
130     return $this->getOption('is_hidden');
131   }
132
133   /**
134    * Sets the hidden flag for the widget.
135    *
136    * @param bool $boolean  true if the widget must be hidden, false otherwise
137    *
138    * @return sfWidget The current widget instance
139    */
140   public function setHidden($boolean)
141   {
142     $this->setOption('is_hidden', (boolean) $boolean);
143
144     return $this;
145   }
146
147   /**
148    * Returns true if the widget needs a multipart form.
149    *
150    * @return bool true if the widget needs a multipart form, false otherwise
151    */
152   public function needsMultipartForm()
153   {
154     return $this->getOption('needs_multipart');
155   }
156
157   /**
158    * Renders a HTML tag.
159    *
160    * The id attribute is added automatically to the array of attributes if none is specified.
161    * If uses for "id_format" option to generate the id.
162    *
163    * @param  string $tag        The tag name
164    * @param  array  $attributes An array of HTML attributes to be merged with the default HTML attributes
165    *
166    * @return string An HTML tag string
167    */
168   public function renderTag($tag, $attributes = array())
169   {
170     if (empty($tag))
171     {
172       return '';
173     }
174
175     $attributes = $this->fixFormId($attributes);
176
177     return parent::renderTag($tag, $attributes);
178   }
179
180   /**
181    * Renders a HTML content tag.
182    *
183    * The id attribute is added automatically to the array of attributes if none is specified.
184    * If uses for "id_format" option to generate the id.
185    *
186    * @param  string $tag         The tag name
187    * @param  string $content     The content of the tag
188    * @param  array  $attributes  An array of HTML attributes to be merged with the default HTML attributes
189    *
190    * @return string An HTML tag string
191    */
192   public function renderContentTag($tag, $content = null, $attributes = array())
193   {
194     return parent::renderContentTag($tag, $content, $this->fixFormId($attributes));
195   }
196
197   /**
198    * Adds an HTML id attributes to the array of attributes if none is given and a name attribute exists.
199    *
200    * @param  array $attributes  An array of attributes
201    *
202    * @return array An array of attributes with an id.
203    */
204   protected function fixFormId($attributes)
205   {
206     if (!isset($attributes['id']) && isset($attributes['name']))
207     {
208       $attributes['id'] = $this->generateId($attributes['name'], isset($attributes['value']) ? $attributes['value'] : null);
209     }
210
211     return $attributes;
212   }
213
214   /**
215    * Returns a formatted id based on the field name and optionally on the field value.
216    *
217    * This method determines the proper form field id name based on the parameters. If a form field has an
218    * array value as a name we need to convert them to proper and unique ids like so:
219    *
220    * <samp>
221    *  name[] => name (if value == null)
222    *  name[] => name_value (if value != null)
223    *  name[bob] => name_bob
224    *  name[item][total] => name_item_total
225    * </samp>
226    *
227    * This method also changes all invalid characters to an underscore (_):
228    *
229    * Ids must begin with a letter ([A-Za-z]) and may be followed by any number of letters, digits
230    * ([0-9]), hyphens ("-"), underscores ("_"), colons (":"), and periods (".").
231    *
232    * @param  string $name   The field name
233    * @param  string $value  The field value
234    *
235    * @return string The field id or null.
236    */
237   public function generateId($name, $value = null)
238   {
239     if (false === $this->getOption('id_format'))
240     {
241       return null;
242     }
243
244     // check to see if we have an array variable for a field name
245     if (strstr($name, '['))
246     {
247       $name = str_replace(array('[]', '][', '[', ']'), array((null !== $value ? '_'.$value : ''), '_', '_', ''), $name);
248     }
249
250     if (false !== strpos($this->getOption('id_format'), '%s'))
251     {
252       $name = sprintf($this->getOption('id_format'), $name);
253     }
254
255     // remove illegal characters
256     $name = preg_replace(array('/^[^A-Za-z]+/', '/[^A-Za-z0-9\:_\.\-]/'), array('', '_'), $name);
257
258     return $name;
259   }
260
261   /**
262    * Generates a two chars range
263    *
264    * @param  int  $start
265    * @param  int  $stop
266    * @return array
267    */
268   static protected function generateTwoCharsRange($start, $stop)
269   {
270     $results = array();
271     for ($i = $start; $i <= $stop; $i++)
272     {
273       $results[$i] = sprintf('%02d', $i);
274     }
275     return $results;
276   }
277
278   /**
279    * Sets the parent widget schema.
280    *
281    * @param  sfWidgetFormSchema|null $widgetSchema
282    *
283    * @return sfWidgetForm The current widget instance
284    */
285   public function setParent(sfWidgetFormSchema $widgetSchema = null)
286   {
287     $this->parent = $widgetSchema;
288
289     return $this;
290   }
291
292   /**
293    * Returns the parent widget schema.
294    *
295    * If no schema has been set with setWidgetSchema(), NULL is returned.
296    *
297    * @return sfWidgetFormSchema|null
298    */
299   public function getParent()
300   {
301     return $this->parent;
302   }
303
304   /**
305    * Translates the given text.
306    *
307    * @param  string $text       The text with optional placeholders
308    * @param  array $parameters  The values to replace the placeholders
309    *
310    * @return string             The translated text
311    *
312    * @see sfWidgetFormSchemaFormatter::translate()
313    */
314   protected function translate($text, array $parameters = array())
315   {
316     if (null === $this->parent)
317     {
318       return $text;
319     }
320     else
321     {
322       return $this->parent->getFormFormatter()->translate($text, $parameters);
323     }
324   }
325
326   /**
327    * Translates all values of the given array.
328    *
329    * @param  array $texts       The texts with optional placeholders
330    * @param  array $parameters  The values to replace the placeholders
331    *
332    * @return array              The translated texts
333    *
334    * @see sfWidgetFormSchemaFormatter::translate()
335    */
336   protected function translateAll(array $texts, array $parameters = array())
337   {
338     if (null === $this->parent)
339     {
340       return $texts;
341     }
342     else
343     {
344       $result = array();
345
346       foreach ($texts as $key => $text)
347       {
348         $result[$key] = $this->parent->getFormFormatter()->translate($text, $parameters);
349       }
350
351       return $result;
352     }
353   }
354 }
355
Note: See TracBrowser for help on using the browser.