Development

/branches/1.1/lib/widget/sfWidget.class.php

You must first sign up to be able to contribute.

root/branches/1.1/lib/widget/sfWidget.class.php

Revision 17473, 8.8 kB (checked in by fabien, 5 years ago)

[1.1, 1.2, 1.3] made some small performance optimization on widgets and validators (closes #6311)

  • 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  * sfWidget is the base class for all 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 sfWidget
20 {
21   protected
22     $requiredOptions = array(),
23     $attributes      = array(),
24     $options         = array();
25
26   protected static
27     $xhtml   = true,
28     $charset = 'UTF-8';
29
30   /**
31    * Constructor.
32    *
33    * @param array $options     An array of options
34    * @param array $attributes  An array of default HTML attributes
35    */
36   public function __construct($options = array(), $attributes = array())
37   {
38     $this->configure($options, $attributes);
39
40     $currentOptionKeys = array_keys($this->options);
41     $optionKeys = array_keys($options);
42
43     // check option names
44     if ($diff = array_diff($optionKeys, array_merge($currentOptionKeys, $this->requiredOptions)))
45     {
46       throw new InvalidArgumentException(sprintf('%s does not support the following options: \'%s\'.', get_class($this), implode('\', \'', $diff)));
47     }
48
49     // check required options
50     if ($diff = array_diff($this->requiredOptions, array_merge($currentOptionKeys, $optionKeys)))
51     {
52       throw new RuntimeException(sprintf('%s requires the following options: \'%s\'.', get_class($this), implode('\', \'', $diff)));
53     }
54
55     $this->options = array_merge($this->options, $options);
56     $this->attributes = array_merge($this->attributes, $attributes);
57   }
58
59   /**
60    * Configures the current widget.
61    *
62    * This method allows each widget to add options or HTML attributes
63    * during widget creation.
64    *
65    * If some options and HTML attributes are given in the sfWidget constructor
66    * they will take precedence over the options and HTML attributes you configure
67    * in this method.
68    *
69    * @param array $options     An array of options
70    * @param array $attributes  An array of HTML attributes
71    *
72    * @see __construct()
73    */
74   protected function configure($options = array(), $attributes = array())
75   {
76   }
77
78   /**
79    * Renders the widget as HTML.
80    *
81    * All subclasses must implement this method.
82    *
83    * @param  string $name       The name of the HTML widget
84    * @param  mixed  $value      The value of the widget
85    * @param  array  $attributes An array of HTML attributes
86    * @param  array  $errors     An array of errors
87    *
88    * @return string A HTML representation of the widget
89    */
90   abstract public function render($name, $value = null, $attributes = array(), $errors = array());
91
92   /**
93    * Adds a required option.
94    *
95    * @param string $name  The option name
96    */
97   public function addRequiredOption($name)
98   {
99     $this->requiredOptions[] = $name;
100   }
101
102   /**
103    * Returns all required option names.
104    *
105    * @param array An array of required option names
106    */
107   public function getRequiredOptions()
108   {
109     return $this->requiredOptions;
110   }
111
112   /**
113    * Adds a new option value with a default value.
114    *
115    * @param string $name   The option name
116    * @param mixed  $value  The default value
117    */
118   public function addOption($name, $value = null)
119   {
120     $this->options[$name] = $value;
121   }
122
123   /**
124    * Changes an option value.
125    *
126    * @param string $name   The option name
127    * @param mixed  $value  The value
128    */
129   public function setOption($name, $value)
130   {
131     if (!in_array($name, array_merge(array_keys($this->options), $this->requiredOptions)))
132     {
133       throw new InvalidArgumentException(sprintf('%s does not support the following option: \'%s\'.', get_class($this), $name));
134     }
135
136     $this->options[$name] = $value;
137   }
138
139   /**
140    * Gets an option value.
141    *
142    * @param  string The option name
143    *
144    * @return mixed  The option value
145    */
146   public function getOption($name)
147   {
148     return isset($this->options[$name]) ? $this->options[$name] : null;
149   }
150
151   /**
152    * Returns true if the option exists.
153    *
154    * @param  string $name  The option name
155    *
156    * @return bool true if the option exists, false otherwise
157    */
158   public function hasOption($name)
159   {
160     return array_key_exists($name, $this->options);
161   }
162
163   /**
164    * Gets all options.
165    *
166    * @return array  An array of named options
167    */
168   public function getOptions()
169   {
170     return $this->options;
171   }
172
173   /**
174    * Sets the options.
175    *
176    * @param array $options  An array of options
177    */
178   public function setOptions($options)
179   {
180     $this->options = $options;
181   }
182
183   /**
184    * Returns the default HTML attributes.
185    *
186    * @param array An array of HTML attributes
187    */
188   public function getAttributes()
189   {
190     return $this->attributes;
191   }
192
193   /**
194    * Sets a default HTML attribute.
195    *
196    * @param string $name   The attribute name
197    * @param string $value  The attribute value
198    */
199   public function setAttribute($name, $value)
200   {
201     $this->attributes[$name] = $value;
202   }
203
204   /**
205    * Returns the HTML attribute value for a given attribute name.
206    *
207    * @param  string $name  The attribute name.
208    *
209    * @return string The attribute value, or null if the attribute does not exist
210    */
211   public function getAttribute($name)
212   {
213     return isset($this->attributes[$name]) ? $this->attributes[$name] : null;
214   }
215
216   /**
217    * Sets the HTML attributes.
218    *
219    * @param array $attributes  An array of HTML attributes
220    */
221   public function setAttributes($attributes)
222   {
223     $this->attributes = $attributes;
224   }
225
226   /**
227    * Sets the charset to use when rendering widgets.
228    *
229    * @param string $charset  The charset
230    */
231   static public function setCharset($charset)
232   {
233     self::$charset = $charset;
234   }
235
236   /**
237    * Returns the charset to use when rendering widgets.
238    *
239    * @return string The charset (defaults to UTF-8)
240    */
241   static public function getCharset()
242   {
243     return self::$charset;
244   }
245
246   /**
247    * Sets the XHTML generation flag.
248    *
249    * @param bool $boolean  true if widgets must be generated as XHTML, false otherwise
250    */
251   static public function setXhtml($boolean)
252   {
253     self::$xhtml = (boolean) $boolean;
254   }
255
256   /**
257    * Returns whether to generate XHTML tags or not.
258    *
259    * @return bool true if widgets must be generated as XHTML, false otherwise
260    */
261   static public function isXhtml()
262   {
263     return self::$xhtml;
264   }
265
266   /**
267    * Renders a HTML tag.
268    *
269    * @param string $tag         The tag name
270    * @param array  $attributes  An array of HTML attributes to be merged with the default HTML attributes
271    *
272    * @param string An HTML tag string
273    */
274   public function renderTag($tag, $attributes = array())
275   {
276     if (empty($tag))
277     {
278       return '';
279     }
280
281     return sprintf('<%s%s%s', $tag, $this->attributesToHtml($attributes), self::$xhtml ? ' />' : ('input' != $tag ? sprintf('></%s>', $tag) : '>'));
282   }
283
284   /**
285    * Renders a HTML content tag.
286    *
287    * @param string $tag         The tag name
288    * @param string $content     The content of the tag
289    * @param array  $attributes  An array of HTML attributes to be merged with the default HTML attributes
290    *
291    * @param string An HTML tag string
292    */
293   public function renderContentTag($tag, $content = null, $attributes = array())
294   {
295     if (empty($tag))
296     {
297       return '';
298     }
299
300     return sprintf('<%s%s>%s</%s>', $tag, $this->attributesToHtml($attributes), $content, $tag);
301   }
302
303   /**
304    * Escapes a string.
305    *
306    * @param  string $value  string to escape
307    * @return string escaped string
308    */
309   static public function escapeOnce($value)
310   {
311     $value = is_object($value) ? $value->__toString() : (string) $value;
312
313     return self::fixDoubleEscape(htmlspecialchars($value, ENT_QUOTES, self::getCharset()));
314   }
315
316   /**
317    * Fixes double escaped strings.
318    *
319    * @param  string $escaped  string to fix
320    * @return string single escaped string
321    */
322   static public function fixDoubleEscape($escaped)
323   {
324     return preg_replace('/&amp;([a-z]+|(#\d+)|(#x[\da-f]+));/i', '&$1;', $escaped);
325   }
326
327   /**
328    * Converts an array of attributes to its HTML representation.
329    *
330    * @param  array  $attributes An array of attributes
331    *
332    * @return string The HTML representation of the HTML attribute array.
333    */
334   public function attributesToHtml($attributes)
335   {
336     $attributes = array_merge($this->attributes, $attributes);
337
338     return implode('', array_map(array($this, 'attributesToHtmlCallback'), array_keys($attributes), array_values($attributes)));
339   }
340
341   /**
342    * Prepares an attribute key and value for HTML representation.
343    *
344    * @param  string $k  The attribute key
345    * @param  string $v  The attribute value
346    *
347    * @return string The HTML representation of the HTML key attribute pair.
348    */
349   protected function attributesToHtmlCallback($k, $v)
350   {
351     return is_null($v) || '' === $v ? '' : sprintf(' %s="%s"', $k, $this->escapeOnce($v));
352   }
353 }
354
Note: See TracBrowser for help on using the browser.