Development

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

You must first sign up to be able to contribute.

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

Revision 33596, 10.0 kB (checked in by fabien, 2 years ago)

[1.4] fixed some PHP 5.4 notices (closes #10010, patch from Tiago.Ribeiro, David.Regade, and bmontuelle)

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