Development

/branches/1.1/lib/helper/UrlHelper.php

You must first sign up to be able to contribute.

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

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