Subversion-Projekte lars-tiefland.php_share

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 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: UrlHelper.php 31396 2010-11-15 16:08:26Z fabien $
18
 */
19
 
20
/**
21
 * @ignore
22
 */
23
function link_to2($name, $routeName, $params, $options = array())
24
{
25
  $params = array_merge(array('sf_route' => $routeName), is_object($params) ? array('sf_subject' => $params) : $params);
26
 
27
  return link_to1($name, $params, $options);
28
}
29
 
30
/**
31
 * @ignore
32
 */
33
function link_to1($name, $internal_uri, $options = array())
34
{
35
  $html_options = _parse_attributes($options);
36
 
37
  $html_options = _convert_options_to_javascript($html_options);
38
 
39
  $absolute = false;
40
  if (isset($html_options['absolute_url']))
41
  {
42
    $html_options['absolute'] = $html_options['absolute_url'];
43
    unset($html_options['absolute_url']);
44
  }
45
  if (isset($html_options['absolute']))
46
  {
47
    $absolute = (boolean) $html_options['absolute'];
48
    unset($html_options['absolute']);
49
  }
50
 
51
  $html_options['href'] = url_for($internal_uri, $absolute);
52
 
53
  if (isset($html_options['query_string']))
54
  {
55
    $html_options['href'] .= '?'.$html_options['query_string'];
56
    unset($html_options['query_string']);
57
  }
58
 
59
  if (isset($html_options['anchor']))
60
  {
61
    $html_options['href'] .= '#'.$html_options['anchor'];
62
    unset($html_options['anchor']);
63
  }
64
 
65
  if (is_object($name))
66
  {
67
    if (method_exists($name, '__toString'))
68
    {
69
      $name = $name->__toString();
70
    }
71
    else
72
    {
73
      throw new sfException(sprintf('Object of class "%s" cannot be converted to string (Please create a __toString() method).', get_class($name)));
74
    }
75
  }
76
 
77
  if (!strlen($name))
78
  {
79
    $name = $html_options['href'];
80
  }
81
 
82
  return content_tag('a', $name, $html_options);
83
}
84
 
85
/**
86
 * @ignore
87
 */
88
function url_for2($routeName, $params = array(), $absolute = false)
89
{
90
  $params = array_merge(array('sf_route' => $routeName), is_object($params) ? array('sf_subject' => $params) : $params);
91
 
92
  return url_for1($params, $absolute);
93
}
94
 
95
/**
96
 * @ignore
97
 */
98
function url_for1($internal_uri, $absolute = false)
99
{
100
  return sfContext::getInstance()->getController()->genUrl($internal_uri, $absolute);
101
}
102
 
103
/**
104
 * Returns a routed URL based on the module/action passed as argument
105
 * and the routing configuration.
106
 *
107
 * <b>Examples:</b>
108
 * <code>
109
 *  echo url_for('my_module/my_action');
110
 *    => /path/to/my/action
111
 *  echo url_for('@my_rule');
112
 *    => /path/to/my/action
113
 *  echo url_for('@my_rule', true);
114
 *    => http://myapp.example.com/path/to/my/action
115
 * </code>
116
 *
117
 * @param  string $internal_uri  'module/action' or '@rule' of the action
118
 * @param  bool   $absolute      return absolute path?
119
 * @return string routed URL
120
 */
121
function url_for()
122
{
123
  // for BC with 1.1
124
  $arguments = func_get_args();
125
  if (is_array($arguments[0]) || '@' == substr($arguments[0], 0, 1) || false !== strpos($arguments[0], '/'))
126
  {
127
    return call_user_func_array('url_for1', $arguments);
128
  }
129
  else
130
  {
131
    return call_user_func_array('url_for2', $arguments);
132
  }
133
}
134
 
135
/**
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
 * It's also possible to pass a string instead of a module/action pair to
139
 * get a link tag that just points without consideration.
140
 * If null is passed as a name, the link itself will become the name.
141
 * If an object is passed as a name, the object string representation is used.
142
 * One of the options serves for for creating javascript confirm alerts where
143
 * if you pass 'confirm' => 'Are you sure?', the link will be guarded
144
 * with a JS popup asking that question. If the user accepts, the link is processed,
145
 * otherwise not.
146
 *
147
 * <b>Options:</b>
148
 * - 'absolute' - if set to true, the helper outputs an absolute URL
149
 * - 'query_string' - to append a query string (starting by ?) to the routed url
150
 * - 'anchor' - to append an anchor (starting by #) to the routed url
151
 * - 'confirm' - displays a javascript confirmation alert when the link is clicked
152
 * - 'popup' - if set to true, the link opens a new browser window
153
 * - 'post' - if set to true, the link submits a POST request instead of GET (caution: do not use inside a form)
154
 * - 'method' - if set to post, delete, or put, the link submits a request with the given HTTP method instead of GET (caution: do not use inside a form)
155
 *
156
 * <b>Note:</b> The 'popup', 'post', and 'method' options are not compatible with each other.
157
 *
158
 * <b>Examples:</b>
159
 * <code>
160
 *  echo link_to('Delete this page', 'my_module/my_action');
161
 *    => <a href="/path/to/my/action">Delete this page</a>
162
 *  echo link_to('Visit Hoogle', 'http://www.hoogle.com');
163
 *    => <a href="http://www.hoogle.com">Visit Hoogle</a>
164
 *  echo link_to('Delete this page', 'my_module/my_action', array('id' => 'myid', 'confirm' => 'Are you sure?', 'absolute' => true));
165
 *    => <a href="http://myapp.example.com/path/to/my/action" id="myid" onclick="return confirm('Are you sure?');">Delete this page</a>
166
 * </code>
167
 *
168
 * @param  string $name          name of the link, i.e. string to appear between the <a> tags
169
 * @param  string $internal_uri  'module/action' or '@rule' of the action
170
 * @param  array  $options       additional HTML compliant <a> tag parameters
171
 * @return string XHTML compliant <a href> tag
172
 * @see    url_for
173
 */
174
function link_to()
175
{
176
  // for BC with 1.1
177
  $arguments = func_get_args();
178
  if (empty($arguments[1]) || is_array($arguments[1]) || '@' == substr($arguments[1], 0, 1) || false !== strpos($arguments[1], '/'))
179
  {
180
    return call_user_func_array('link_to1', $arguments);
181
  }
182
  else
183
  {
184
    if (!array_key_exists(2, $arguments))
185
    {
186
      $arguments[2] = array();
187
    }
188
    return call_user_func_array('link_to2', $arguments);
189
  }
190
}
191
 
192
function url_for_form(sfFormObject $form, $routePrefix)
193
{
194
  $format = '%s/%s';
195
  if ('@' == $routePrefix[0])
196
  {
197
    $format = '%s_%s';
198
    $routePrefix = substr($routePrefix, 1);
199
  }
200
 
201
  $uri = sprintf($format, $routePrefix, $form->getObject()->isNew() ? 'create' : 'update');
202
 
203
  return url_for($uri, $form->getObject());
204
}
205
 
206
function form_tag_for(sfForm $form, $routePrefix, $attributes = array())
207
{
208
  return $form->renderFormTag(url_for_form($form, $routePrefix), $attributes);
209
}
210
 
211
/**
212
 * If the condition passed as first argument is true,
213
 * creates a <a> link tag of the given name using a routed URL
214
 * based on the module/action passed as argument and the routing configuration.
215
 * If the condition is false, the given name is returned between <span> tags
216
 *
217
 * <b>Options:</b>
218
 * - 'tag' - the HTML tag that must enclose the name if the condition is false, defaults to <span>
219
 * - 'absolute' - if set to true, the helper outputs an absolute URL
220
 * - 'query_string' - to append a query string (starting by ?) to the routed url
221
 * - 'anchor' - to append an anchor (starting by #) to the routed url
222
 * - 'confirm' - displays a javascript confirmation alert when the link is clicked
223
 * - 'popup' - if set to true, the link opens a new browser window
224
 * - 'post' - if set to true, the link submits a POST request instead of GET (caution: do not use inside a form)
225
 *
226
 * <b>Examples:</b>
227
 * <code>
228
 *  echo link_to_if($user->isAdministrator(), 'Delete this page', 'my_module/my_action');
229
 *    => <a href="/path/to/my/action">Delete this page</a>
230
 *  echo link_to_if(!$user->isAdministrator(), 'Delete this page', 'my_module/my_action');
231
 *    => <span>Delete this page</span>
232
 * </code>
233
 *
234
 * @param  bool   $condition     condition
235
 * @param  string $name          name of the link, i.e. string to appear between the <a> tags
236
 * @param  string $internal_uri  'module/action' or '@rule' of the action
237
 * @param  array  $options       additional HTML compliant <a> tag parameters
238
 *
239
 * @return string XHTML compliant <a href> tag or name
240
 *
241
 * @see    link_to
242
 */
243
function link_to_if()
244
{
245
  $arguments = func_get_args();
246
  if (empty($arguments[2]) || '@' == substr($arguments[2], 0, 1) || false !== strpos($arguments[2], '/'))
247
  {
248
    list($condition, $name, $params, $options) = array_pad($arguments, 4, null);
249
  }
250
  else
251
  {
252
    list($condition, $name, $routeName, $params, $options) = array_pad($arguments, 5, null);
253
    $params = array_merge(array('sf_route' => $routeName), is_object($params) ? array('sf_subject' => $params) : (array) $params);
254
  }
255
 
256
  $html_options = _parse_attributes($options);
257
  if ($condition)
258
  {
259
    unset($html_options['tag']);
260
    return link_to1($name, $params, $html_options);
261
  }
262
  else
263
  {
264
    unset($html_options['query_string']);
265
    unset($html_options['absolute_url']);
266
    unset($html_options['absolute']);
267
 
268
    $tag = _get_option($html_options, 'tag', 'span');
269
 
270
    return content_tag($tag, $name, $html_options);
271
  }
272
}
273
 
274
/**
275
 * If the condition passed as first argument is false,
276
 * creates a <a> link tag of the given name using a routed URL
277
 * based on the module/action passed as argument and the routing configuration.
278
 * If the condition is true, the given name is returned between <span> tags
279
 *
280
 * <b>Options:</b>
281
 * - 'tag' - the HTML tag that must enclose the name if the condition is true, defaults to <span>
282
 * - 'absolute' - if set to true, the helper outputs an absolute URL
283
 * - 'query_string' - to append a query string (starting by ?) to the routed url
284
 * - 'anchor' - to append an anchor (starting by #) to the routed url
285
 * - 'confirm' - displays a javascript confirmation alert when the link is clicked
286
 * - 'popup' - if set to true, the link opens a new browser window
287
 * - 'post' - if set to true, the link submits a POST request instead of GET (caution: do not use inside a form)
288
 *
289
 * <b>Examples:</b>
290
 * <code>
291
 *  echo link_to_unless($user->isAdministrator(), 'Delete this page', 'my_module/my_action');
292
 *    => <span>Delete this page</span>
293
 *  echo link_to_unless(!$user->isAdministrator(), 'Delete this page', 'my_module/my_action');
294
 *    => <a href="/path/to/my/action">Delete this page</a>
295
 * </code>
296
 *
297
 * @param  bool   $condition     condition
298
 * @param  string $name          name of the link, i.e. string to appear between the <a> tags
299
 * @param  string $internal_uri  'module/action' or '@rule' of the action
300
 * @param  array  $options       additional HTML compliant <a> tag parameters
301
 *
302
 * @return string XHTML compliant <a href> tag or name
303
 *
304
 * @see    link_to
305
 */
306
function link_to_unless()
307
{
308
  $arguments = func_get_args();
309
  $arguments[0] = !$arguments[0];
310
  return call_user_func_array('link_to_if', $arguments);
311
}
312
 
313
/**
314
 * Returns a URL rooted at the web root
315
 *
316
 * @param   string  $path     The route to append
317
 * @param   bool    $absolute If true, an absolute path is returned (optional)
318
 * @return  The web URL root
319
 */
320
function public_path($path, $absolute = false)
321
{
322
  $request = sfContext::getInstance()->getRequest();
323
  $root = $request->getRelativeUrlRoot();
324
 
325
  if ($absolute)
326
  {
327
    $source = 'http';
328
    if ($request->isSecure())
329
    {
330
      $source .= 's';
331
    }
332
    $source .='://'.$request->getHost().$root;
333
  }
334
  else
335
  {
336
    $source = $root;
337
  }
338
 
339
  if (substr($path, 0, 1) != '/')
340
  {
341
    $path = '/'.$path;
342
  }
343
 
344
  return $source.$path;
345
}
346
 
347
/**
348
 * Creates an <input> button tag of the given name pointing to a routed URL
349
 * based on the module/action passed as argument and the routing configuration.
350
 * The syntax is similar to the one of link_to.
351
 *
352
 * <b>Options:</b>
353
 * - 'absolute' - if set to true, the helper outputs an absolute URL
354
 * - 'query_string' - to append a query string (starting by ?) to the routed url
355
 * - 'anchor' - to append an anchor (starting by #) to the routed url
356
 * - 'confirm' - displays a javascript confirmation alert when the button is clicked
357
 * - 'popup' - if set to true, the button opens a new browser window
358
 * - 'post' - if set to true, the button submits a POST request instead of GET (caution: do not use inside a form)
359
 *
360
 * <b>Examples:</b>
361
 * <code>
362
 *  echo button_to('Delete this page', 'my_module/my_action');
363
 *    => <input value="Delete this page" type="button" onclick="document.location.href='/path/to/my/action';" />
364
 * </code>
365
 *
366
 * @param  string $name          name of the button
367
 * @param  string $internal_uri  'module/action' or '@rule' of the action
368
 * @param  array  $options       additional HTML compliant <input> tag parameters
369
 * @return string XHTML compliant <input> tag
370
 * @see    url_for, link_to
371
 */
372
function button_to($name, $internal_uri, $options = array())
373
{
374
  $html_options = _parse_attributes($options);
375
  $html_options['value'] = $name;
376
 
377
  if (isset($html_options['post']) && $html_options['post'])
378
  {
379
    if (isset($html_options['popup']))
380
    {
381
      throw new sfConfigurationException('You can\'t use "popup" and "post" together.');
382
    }
383
    $html_options['type'] = 'submit';
384
    unset($html_options['post']);
385
    $html_options = _convert_options_to_javascript($html_options);
386
 
387
    return form_tag($internal_uri, array('method' => 'post', 'class' => 'button_to')).content_tag('div', tag('input', $html_options)).'</form>';
388
  }
389
 
390
  $url = url_for($internal_uri);
391
  if (isset($html_options['query_string']))
392
  {
393
    $url = $url.'?'.$html_options['query_string'];
394
    unset($html_options['query_string']);
395
  }
396
  if (isset($html_options['anchor']))
397
  {
398
    $url = $url.'#'.$html_options['anchor'];
399
    unset($html_options['anchor']);
400
  }
401
  $url = "'".$url."'";
402
  $html_options['type'] = 'button';
403
 
404
  if (isset($html_options['popup']))
405
  {
406
    $html_options = _convert_options_to_javascript($html_options, $url);
407
    unset($html_options['popup']);
408
  }
409
  else
410
  {
411
    $html_options['onclick'] = "document.location.href=".$url.";";
412
    $html_options = _convert_options_to_javascript($html_options);
413
  }
414
 
415
  return tag('input', $html_options);
416
}
417
 
418
/**
419
 * Returns an HTML <form> tag that points to a valid action, route or URL as defined by <i>$url_for_options</i>.
420
 *
421
 * By default, the form tag is generated in POST format, but can easily be configured along with any additional
422
 * HTML parameters via the optional <i>$options</i> parameter. If you are using file uploads, be sure to set the
423
 * <i>multipart</i> option to true.
424
 *
425
 * <b>Options:</b>
426
 * - multipart - When set to true, enctype is set to "multipart/form-data".
427
 *
428
 * <b>Examples:</b>
429
 *   <code><?php echo form_tag('@myroute'); ?></code>
430
 *   <code><?php echo form_tag('/module/action', array('name' => 'myformname', 'multipart' => true)); ?></code>
431
 *
432
 * @param  string $url_for_options  valid action, route or URL
433
 * @param  array  $options          optional HTML parameters for the <form> tag
434
 *
435
 * @return string opening HTML <form> tag with options
436
 */
437
function form_tag($url_for_options = '', $options = array())
438
{
439
  $options = _parse_attributes($options);
440
 
441
  $html_options = $options;
442
 
443
  $html_options['method'] = isset($html_options['method']) ? strtolower($html_options['method']) : 'post';
444
 
445
  if (_get_option($html_options, 'multipart'))
446
  {
447
    $html_options['enctype'] = 'multipart/form-data';
448
  }
449
 
450
  $html_options['action'] = url_for($url_for_options);
451
 
452
  $html = '';
453
  if (!in_array($html_options['method'], array('get', 'post')))
454
  {
455
    $html = tag('input', array('type' => 'hidden', 'name' => 'sf_method', 'value' => $html_options['method']));
456
    $html_options['method'] = 'post';
457
  }
458
 
459
  return tag('form', $html_options, true).$html;
460
}
461
 
462
/**
463
 * Creates a <a> link tag to the given email (with href="mailto:...").
464
 * If null is passed as a name, the email itself will become the name.
465
 *
466
 * <b>Options:</b>
467
 * - 'encode' - if set to true, the email address appears with various random encoding for each letter.
468
 * The mail link still works when encoded, but the address doesn't appear in clear
469
 * in the source. Use it to prevent spam (efficiency not guaranteed).
470
 *
471
 * <b>Examples:</b>
472
 * <code>
473
 *  echo mail_to('webmaster@example.com');
474
 *    => <a href="mailto:webmaster@example.com">webmaster@example.com</a>
475
 *  echo mail_to('webmaster@example.com', 'send us an email');
476
 *    => <a href="mailto:webmaster@example.com">send us an email</a>
477
 *  echo mail_to('webmaster@example.com', 'send us an email', array('encode' => true));
478
 *    => <a href="
479
            &#x6d;a&#x69;&#x6c;&#x74;&#111;&#58;&#x77;&#x65;b&#x6d;as&#116;&#x65;&#114;
480
            &#64;&#101;&#x78;&#x61;&#x6d;&#x70;&#108;&#x65;&#46;&#99;&#x6f;&#109;
481
          ">send us an email</a>
482
 * </code>
483
 *
484
 * @param  string $email          target email
485
 * @param  string $name           name of the link, i.e. string to appear between the <a> tags
486
 * @param  array  $options        additional HTML compliant <a> tag parameters
487
 * @param  array  $default_value
488
 * @return string XHTML compliant <a href> tag
489
 * @see    link_to
490
 */
491
function mail_to($email, $name = '', $options = array(), $default_value = array())
492
{
493
  $html_options = _parse_attributes($options);
494
 
495
  $html_options = _convert_options_to_javascript($html_options);
496
 
497
  $default_tmp = _parse_attributes($default_value);
498
  $default = array();
499
  foreach ($default_tmp as $key => $value)
500
  {
501
    $default[] = urlencode($key).'='.urlencode($value);
502
  }
503
  $options = count($default) ? '?'.implode('&', $default) : '';
504
 
505
  if (isset($html_options['encode']) && $html_options['encode'])
506
  {
507
    unset($html_options['encode']);
508
    $html_options['href'] = _encodeText('mailto:'.$email.$options);
509
    if (!$name)
510
    {
511
      $name = _encodeText($email);
512
    }
513
  }
514
  else
515
  {
516
    $html_options['href'] = 'mailto:'.$email.$options;
517
    if (!$name)
518
    {
519
      $name = $email;
520
    }
521
  }
522
 
523
  return content_tag('a', $name, $html_options);
524
}
525
 
526
function _convert_options_to_javascript($html_options, $url = 'this.href')
527
{
528
  // confirm
529
  $confirm = isset($html_options['confirm']) ? $html_options['confirm'] : '';
530
  unset($html_options['confirm']);
531
 
532
  // popup
533
  $popup = isset($html_options['popup']) ? $html_options['popup'] : '';
534
  unset($html_options['popup']);
535
 
536
  // method
537
  $method = isset($html_options['method']) ? $html_options['method'] : (isset($html_options['post']) && $html_options['post'] ? 'post' : false);
538
  unset($html_options['post'], $html_options['method']);
539
 
540
  $onclick = isset($html_options['onclick']) ? $html_options['onclick'] : '';
541
 
542
  if ($popup && $method)
543
  {
544
    throw new sfConfigurationException('You can\'t use "popup", "method" and "post" in the same link.');
545
  }
546
  else if ($confirm && $popup)
547
  {
548
    $html_options['onclick'] = $onclick.'if ('._confirm_javascript_function($confirm).') { '._popup_javascript_function($popup, $url).' };return false;';
549
  }
550
  else if ($confirm && $method)
551
  {
552
    $html_options['onclick'] = $onclick.'if ('._confirm_javascript_function($confirm).') { '._method_javascript_function($method).' };return false;';
553
  }
554
  else if ($confirm)
555
  {
556
    if ($onclick)
557
    {
558
      $html_options['onclick'] = 'if ('._confirm_javascript_function($confirm).') { return '.$onclick.'} else return false;';
559
    }
560
    else
561
    {
562
      $html_options['onclick'] = 'return '._confirm_javascript_function($confirm).';';
563
    }
564
  }
565
  else if ($method)
566
  {
567
    $html_options['onclick'] = $onclick._method_javascript_function($method).'return false;';
568
  }
569
  else if ($popup)
570
  {
571
    $html_options['onclick'] = $onclick._popup_javascript_function($popup, $url).'return false;';
572
  }
573
 
574
  return $html_options;
575
}
576
 
577
function _confirm_javascript_function($confirm)
578
{
579
  return "confirm('".escape_javascript($confirm)."')";
580
}
581
 
582
function _popup_javascript_function($popup, $url = '')
583
{
584
  if (is_array($popup))
585
  {
586
    if (isset($popup[1]))
587
    {
588
      return "var w=window.open(".$url.",'".$popup[0]."','".$popup[1]."');w.focus();";
589
    }
590
    else
591
    {
592
      return "var w=window.open(".$url.",'".$popup[0]."');w.focus();";
593
    }
594
  }
595
  else
596
  {
597
    return "var w=window.open(".$url.");w.focus();";
598
  }
599
}
600
 
601
function _post_javascript_function()
602
{
603
  return _method_javascript_function('POST');
604
}
605
 
606
function _method_javascript_function($method)
607
{
608
  $function = "var f = document.createElement('form'); f.style.display = 'none'; this.parentNode.appendChild(f); f.method = 'post'; f.action = this.href;";
609
 
610
  if ('post' != strtolower($method))
611
  {
612
    $function .= "var m = document.createElement('input'); m.setAttribute('type', 'hidden'); ";
613
    $function .= sprintf("m.setAttribute('name', 'sf_method'); m.setAttribute('value', '%s'); f.appendChild(m);", strtolower($method));
614
  }
615
 
616
  // CSRF protection
617
  $form = new BaseForm();
618
  if ($form->isCSRFProtected())
619
  {
620
    $function .= "var m = document.createElement('input'); m.setAttribute('type', 'hidden'); ";
621
    $function .= sprintf("m.setAttribute('name', '%s'); m.setAttribute('value', '%s'); f.appendChild(m);", $form->getCSRFFieldName(), $form->getCSRFToken());
622
  }
623
 
624
  $function .= "f.submit();";
625
 
626
  return $function;
627
}
628
 
629
function _encodeText($text)
630
{
631
  $encoded_text = '';
632
 
633
  for ($i = 0; $i < strlen($text); $i++)
634
  {
635
    $char = $text{$i};
636
    $r = rand(0, 100);
637
 
638
    # roughly 10% raw, 45% hex, 45% dec
639
    # '@' *must* be encoded. I insist.
640
    if ($r > 90 && $char != '@')
641
    {
642
      $encoded_text .= $char;
643
    }
644
    else if ($r < 45)
645
    {
646
      $encoded_text .= '&#x'.dechex(ord($char)).';';
647
    }
648
    else
649
    {
650
      $encoded_text .= '&#'.ord($char).';';
651
    }
652
  }
653
 
654
  return $encoded_text;
655
}