Development

/branches/1.0/lib/helper/UrlHelper.php

You must first sign up to be able to contribute.

root/branches/1.0/lib/helper/UrlHelper.php

Revision 13408, 14.7 kB (checked in by fabien, 6 years ago)

[1.0, 1.1, 1.2] fixed long line in a PHP doc (closes #4750)

  • Property svn:mime-type set to text/x-php
  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Rev Date
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  * UrlHelper.
13  *
14  * @package    symfony
15  * @subpackage helper
16  * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
17  * @version    SVN: $Id$
18  */
19
20
21 /**
22  * Returns a routed URL based on the module/action passed as argument
23  * and the routing configuration.
24  *
25  * <b>Examples:</b>
26  * <code>
27  *  echo url_for('my_module/my_action');
28  *    => /path/to/my/action
29  *  echo url_for('@my_rule');
30  *    => /path/to/my/action
31  *  echo url_for('@my_rule', true);
32  *    => http://myapp.example.com/path/to/my/action
33  * </code>
34  *
35  * @param  string 'module/action' or '@rule' of the action
36  * @param  bool return absolute path?
37  * @return string routed URL
38  */
39 function url_for($internal_uri, $absolute = false)
40 {
41   static $controller;
42
43   if (!isset($controller))
44   {
45     $controller = sfContext::getInstance()->getController();
46   }
47
48   return $controller->genUrl($internal_uri, $absolute);
49 }
50
51 /**
52  * Creates a <a> link tag of the given name using a routed URL
53  * based on the module/action passed as argument and the routing configuration.
54  * It's also possible to pass a string instead of a module/action pair to
55  * get a link tag that just points without consideration.
56  * If null is passed as a name, the link itself will become the name.
57  * If an object is passed as a name, the object string representation is used.
58  * One of the options serves for for creating javascript confirm alerts where
59  * if you pass 'confirm' => 'Are you sure?', the link will be guarded
60  * with a JS popup asking that question. If the user accepts, the link is processed,
61  * otherwise not.
62  *
63  * <b>Options:</b>
64  * - 'absolute' - if set to true, the helper outputs an absolute URL
65  * - 'query_string' - to append a query string (starting by ?) to the routed url
66  * - 'confirm' - displays a javascript confirmation alert when the link is clicked
67  * - 'popup' - if set to true, the link opens a new browser window
68  * - 'post' - if set to true, the link submits a POST request instead of GET (caution: do not use inside a form)
69  *
70  * <b>Note:</b> The 'popup' and 'post' options are not compatible with each other.
71  *
72  * <b>Examples:</b>
73  * <code>
74  *  echo link_to('Delete this page', 'my_module/my_action');
75  *    => <a href="/path/to/my/action">Delete this page</a>
76  *  echo link_to('Visit Hoogle', 'http://www.hoogle.com');
77  *    => <a href="http://www.hoogle.com">Visit Hoogle</a>
78  *  echo link_to('Delete this page', 'my_module/my_action', array('id' => 'myid', 'confirm' => 'Are you sure?', 'absolute' => true));
79  *    => <a href="http://myapp.example.com/path/to/my/action" id="myid" onclick="return confirm('Are you sure?');">Delete this page</a>
80  * </code>
81  *
82  * @param  string name of the link, i.e. string to appear between the <a> tags
83  * @param  string 'module/action' or '@rule' of the action
84  * @param  array additional HTML compliant <a> tag parameters
85  * @return string XHTML compliant <a href> tag
86  * @see    url_for
87  */
88 function link_to($name = '', $internal_uri = '', $options = array())
89 {
90   $html_options = _parse_attributes($options);
91
92   $html_options = _convert_options_to_javascript($html_options);
93
94   $absolute = false;
95   if (isset($html_options['absolute_url']))
96   {
97     $html_options['absolute'] = $html_options['absolute_url'];
98     unset($html_options['absolute_url']);
99   }
100   if (isset($html_options['absolute']))
101   {
102     $absolute = (boolean) $html_options['absolute'];
103     unset($html_options['absolute']);
104   }
105
106   $html_options['href'] = url_for($internal_uri, $absolute);
107
108   if (isset($html_options['query_string']))
109   {
110     $html_options['href'] .= '?'.$html_options['query_string'];
111     unset($html_options['query_string']);
112   }
113
114   if (is_object($name))
115   {
116     if (method_exists($name, '__toString'))
117     {
118       $name = $name->__toString();
119     }
120     else
121     {
122       throw new sfException(sprintf('Object of class "%s" cannot be converted to string (Please create a __toString() method)', get_class($name)));
123     }
124   }
125
126   if (!strlen($name))
127   {
128     $name = $html_options['href'];
129   }
130
131   return content_tag('a', $name, $html_options);
132 }
133
134 /**
135  * If the condition passed as first argument is true,
136  * creates a <a> link tag of the given name using a routed URL
137  * based on the module/action passed as argument and the routing configuration.
138  * If the condition is false, the given name is returned between <span> tags
139  *
140  * <b>Options:</b>
141  * - 'tag' - the HTML tag that must enclose the name if the condition is false, defaults to <span>
142  * - 'absolute' - if set to true, the helper outputs an absolute URL
143  * - 'query_string' - to append a query string (starting by ?) to the routed url
144  * - 'confirm' - displays a javascript confirmation alert when the link is clicked
145  * - 'popup' - if set to true, the link opens a new browser window
146  * - 'post' - if set to true, the link submits a POST request instead of GET (caution: do not use inside a form)
147  *
148  * <b>Examples:</b>
149  * <code>
150  *  echo link_to_if($user->isAdministrator(), 'Delete this page', 'my_module/my_action');
151  *    => <a href="/path/to/my/action">Delete this page</a>
152  *  echo link_to_if(!$user->isAdministrator(), 'Delete this page', 'my_module/my_action');
153  *    => <span>Delete this page</span>
154  * </code>
155  *
156  * @param  bool condition
157  * @param  string name of the link, i.e. string to appear between the <a> tags
158  * @param  string 'module/action' or '@rule' of the action
159  * @param  array additional HTML compliant <a> tag parameters
160  * @return string XHTML compliant <a href> tag or name
161  * @see    link_to
162  */
163 function link_to_if($condition, $name = '', $internal_uri = '', $options = array())
164 {
165   $html_options = _parse_attributes($options);
166   if ($condition)
167   {
168     unset($html_options['tag']);
169     return link_to($name, $internal_uri, $html_options);
170   }
171   else
172   {
173     unset($html_options['query_string']);
174     unset($html_options['absolute_url']);
175     unset($html_options['absolute']);
176
177     $tag = _get_option($html_options, 'tag', 'span');
178
179     return content_tag($tag, $name, $html_options);
180   }
181 }
182
183 /**
184  * If the condition passed as first argument is false,
185  * creates a <a> link tag of the given name using a routed URL
186  * based on the module/action passed as argument and the routing configuration.
187  * If the condition is true, the given name is returned between <span> tags
188  *
189  * <b>Options:</b>
190  * - 'tag' - the HTML tag that must enclose the name if the condition is true, defaults to <span>
191  * - 'absolute' - if set to true, the helper outputs an absolute URL
192  * - 'query_string' - to append a query string (starting by ?) to the routed url
193  * - 'confirm' - displays a javascript confirmation alert when the link is clicked
194  * - 'popup' - if set to true, the link opens a new browser window
195  * - 'post' - if set to true, the link submits a POST request instead of GET (caution: do not use inside a form)
196  *
197  * <b>Examples:</b>
198  * <code>
199  *  echo link_to_unless($user->isAdministrator(), 'Delete this page', 'my_module/my_action');
200  *    => <span>Delete this page</span>
201  *  echo link_to_unless(!$user->isAdministrator(), 'Delete this page', 'my_module/my_action');
202  *    => <a href="/path/to/my/action">Delete this page</a>
203  * </code>
204  *
205  * @param  bool condition
206  * @param  string name of the link, i.e. string to appear between the <a> tags
207  * @param  string 'module/action' or '@rule' of the action
208  * @param  array additional HTML compliant <a> tag parameters
209  * @return string XHTML compliant <a href> tag or name
210  * @see    link_to
211  */
212 function link_to_unless($condition, $name = '', $url = '', $options = array())
213 {
214   return link_to_if(!$condition, $name, $url, $options);
215 }
216
217 /**
218  * Creates an <input> button tag of the given name pointing to a routed URL
219  * based on the module/action passed as argument and the routing configuration.
220  * The syntax is similar to the one of link_to.
221  *
222  * <b>Options:</b>
223  * - 'absolute' - if set to true, the helper outputs an absolute URL
224  * - 'query_string' - to append a query string (starting by ?) to the routed url
225  * - 'confirm' - displays a javascript confirmation alert when the button is clicked
226  * - 'popup' - if set to true, the button opens a new browser window
227  * - 'post' - if set to true, the button submits a POST request instead of GET (caution: do not use inside a form)
228  *
229  * <b>Examples:</b>
230  * <code>
231  *  echo button_to('Delete this page', 'my_module/my_action');
232  *    => <input value="Delete this page" type="button" onclick="document.location.href='/path/to/my/action';" />
233  * </code>
234  *
235  * @param  string name of the button
236  * @param  string 'module/action' or '@rule' of the action
237  * @param  array additional HTML compliant <input> tag parameters
238  * @return string XHTML compliant <input> tag
239  * @see    url_for, link_to
240  */
241 function button_to($name, $internal_uri ='', $options = array())
242 {
243   $html_options = _parse_attributes($options);
244   $html_options['value'] = $name;
245
246   if (isset($html_options['post']) && $html_options['post'])
247   {
248     if (isset($html_options['popup']))
249     {
250       throw new sfConfigurationException('You can\'t use "popup" and "post" together');
251     }
252     $html_options['type'] = 'submit';
253     unset($html_options['post']);
254     $html_options = _convert_options_to_javascript($html_options);
255
256     return form_tag($internal_uri, array('method' => 'post', 'class' => 'button_to')).content_tag('div', tag('input', $html_options)).'</form>';
257   }
258
259   $url = url_for($internal_uri);
260   if (isset($html_options['query_string']))
261   {
262     $url = $url.'?'.$html_options['query_string'];
263     unset($html_options['query_string']);
264   }
265   $url = "'".$url."'";
266   $html_options['type'] = 'button';
267
268   if (isset($html_options['popup']))
269   {
270     $html_options = _convert_options_to_javascript($html_options, $url);
271     unset($html_options['popup']);
272   }
273   else
274   {
275     $html_options['onclick'] = "document.location.href=".$url.";";
276     $html_options = _convert_options_to_javascript($html_options);
277   }
278
279   return tag('input', $html_options);
280 }
281
282 /**
283  * Creates a <a> link tag to the given email (with href="mailto:...").
284  * If null is passed as a name, the email itself will become the name.
285  *
286  * <b>Options:</b>
287  * - 'encode' - if set to true, the email address appears with various random encoding for each letter.
288  * The mail link still works when encoded, but the address doesn't appear in clear
289  * in the source. Use it to prevent spam (efficiency not guaranteed).
290  *
291  * <b>Examples:</b>
292  * <code>
293  *  echo mail_to('webmaster@example.com');
294  *    => <a href="mailto:webmaster@example.com">webmaster@example.com</a>
295  *  echo mail_to('webmaster@example.com', 'send us an email');
296  *    => <a href="mailto:webmaster@example.com">send us an email</a>
297  *  echo mail_to('webmaster@example.com', 'send us an email', array('encode' => true));
298  *    => <a href="
299             &#x6d;a&#x69;&#x6c;&#x74;&#111;&#58;&#x77;&#x65;b&#x6d;as&#116;&#x65;&#114;
300             &#64;&#101;&#x78;&#x61;&#x6d;&#x70;&#108;&#x65;&#46;&#99;&#x6f;&#109;
301           ">send us an email</a>
302  * </code>
303  *
304  * @param  string target email
305  * @param  string name of the link, i.e. string to appear between the <a> tags
306  * @param  array additional HTML compliant <a> tag parameters
307  * @return string XHTML compliant <a href> tag
308  * @see    link_to
309  */
310 function mail_to($email, $name = '', $options = array(), $default_value = array())
311 {
312   $html_options = _parse_attributes($options);
313
314   $html_options = _convert_options_to_javascript($html_options);
315
316   $default_tmp = _parse_attributes($default_value);
317   $default = array();
318   foreach ($default_tmp as $key => $value)
319   {
320     $default[] = urlencode($key).'='.urlencode($value);
321   }
322   $options = count($default) ? '?'.implode('&', $default) : '';
323
324   if (isset($html_options['encode']) && $html_options['encode'])
325   {
326     unset($html_options['encode']);
327     $html_options['href'] = _encodeText('mailto:'.$email.$options);
328     if (!$name)
329     {
330       $name = _encodeText($email);
331     }
332   }
333   else
334   {
335     $html_options['href'] = 'mailto:'.$email.$options;
336     if (!$name)
337     {
338       $name = $email;
339     }
340   }
341
342   return content_tag('a', $name, $html_options);
343 }
344
345 function _convert_options_to_javascript($html_options, $url = 'this.href')
346 {
347   // confirm
348   $confirm = isset($html_options['confirm']) ? $html_options['confirm'] : '';
349   unset($html_options['confirm']);
350
351   // popup
352   $popup = isset($html_options['popup']) ? $html_options['popup'] : '';
353   unset($html_options['popup']);
354
355   // post
356   $post = isset($html_options['post']) ? $html_options['post'] : '';
357   unset($html_options['post']);
358
359   $onclick = isset($html_options['onclick']) ? $html_options['onclick'] : '';
360
361   if ($popup && $post)
362   {
363     throw new sfConfigurationException('You can\'t use "popup" and "post" in the same link');
364   }
365   else if ($confirm && $popup)
366   {
367     $html_options['onclick'] = $onclick.'if ('._confirm_javascript_function($confirm).') { '._popup_javascript_function($popup, $url).' };return false;';
368   }
369   else if ($confirm && $post)
370   {
371     $html_options['onclick'] = $onclick.'if ('._confirm_javascript_function($confirm).') { '._post_javascript_function().' };return false;';
372   }
373   else if ($confirm)
374   {
375     if ($onclick)
376     {
377       $html_options['onclick'] = 'if ('._confirm_javascript_function($confirm).') { return '.$onclick.'} else return false;';
378     }
379     else
380     {
381       $html_options['onclick'] = 'return '._confirm_javascript_function($confirm).';';
382     }
383   }
384   else if ($post)
385   {
386     $html_options['onclick'] = $onclick._post_javascript_function().'return false;';
387   }
388   else if ($popup)
389   {
390     $html_options['onclick'] = $onclick._popup_javascript_function($popup, $url).'return false;';
391   }
392
393   return $html_options;
394 }
395
396 function _confirm_javascript_function($confirm)
397 {
398   return "confirm('".escape_javascript($confirm)."')";
399 }
400
401 function _popup_javascript_function($popup, $url = '')
402 {
403   if (is_array($popup))
404   {
405     if (isset($popup[1]))
406     {
407       return "var w=window.open(".$url.",'".$popup[0]."','".$popup[1]."');w.focus();";
408     }
409     else
410     {
411       return "var w=window.open(".$url.",'".$popup[0]."');w.focus();";
412     }
413   }
414   else
415   {
416     return "var w=window.open(".$url.");w.focus();";
417   }
418 }
419
420 function _post_javascript_function()
421 {
422   return "f = document.createElement('form'); document.body.appendChild(f); f.method = 'POST'; f.action = this.href; f.submit();";
423 }
424
425 function _encodeText($text)
426 {
427   $encoded_text = '';
428
429   for ($i = 0; $i < strlen($text); $i++)
430   {
431     $char = $text{$i};
432     $r = rand(0, 100);
433
434     # roughly 10% raw, 45% hex, 45% dec
435     # '@' *must* be encoded. I insist.
436     if ($r > 90 && $char != '@')
437     {
438       $encoded_text .= $char;
439     }
440     else if ($r < 45)
441     {
442       $encoded_text .= '&#x'.dechex(ord($char)).';';
443     }
444     else
445     {
446       $encoded_text .= '&#'.ord($char).';';
447     }
448   }
449
450   return $encoded_text;
451 }
452
Note: See TracBrowser for help on using the browser.