[ Index ]

PHP Cross Reference of Akelos Framework

title

Body

[close]

/AkActionView/helpers/ -> url_helper.php (source)

   1  <?php
   2  /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
   3  
   4  // +----------------------------------------------------------------------+
   5  // | Akelos Framework - http://www.akelos.org                             |
   6  // +----------------------------------------------------------------------+
   7  // | Copyright (c) 2002-2006, Akelos Media, S.L.  & Bermi Ferrer Martinez |
   8  // | Released under the GNU Lesser General Public License, see LICENSE.txt|
   9  // +----------------------------------------------------------------------+
  10  
  11  /**
  12   * @package ActionView
  13   * @subpackage Helpers
  14   * @author Bermi Ferrer <bermi a.t akelos c.om>
  15   * @copyright Copyright (c) 2002-2006, Akelos Media, S.L. http://www.akelos.org
  16   * @license GNU Lesser General Public License <http://www.gnu.org/copyleft/lesser.html>
  17   */
  18  
  19  require_once (AK_LIB_DIR.DS.'AkActionView'.DS.'helpers'.DS.'javascript_helper.php');
  20  
  21  class UrlHelper extends AkObject
  22  {
  23      function setController(&$controller)
  24      {
  25          $this->_controller =& $controller;
  26      }
  27  
  28      /**
  29      * Returns the URL for the set of +$options+ provided. This takes the same options 
  30      * as url_for. For a list, see the documentation for AKActionController::urlFor.
  31      * Note that it'll set ('only_path' => true) so you'll get /controller/action instead of the 
  32      * http://example.com/controller/action part (makes it harder to parse httpd log files)
  33      */
  34      function url_for($options = array(), $parameters_for_method_reference = null)
  35      {
  36          $default_options = array(
  37          'only_path' => true
  38          );
  39          $options = array_merge($default_options, $options);
  40          return $this->_controller->urlFor($options, $parameters_for_method_reference);
  41      }
  42  
  43  
  44      function modify_current_url($options_to_add = array(), $options_to_exclude = array(), $remove_unnecesary_options = true)
  45      {
  46          $options_to_exclude = $remove_unnecesary_options ? array_merge(array('ak','lang',AK_SESSION_NAME,'AK_SESSID','PHPSESSID'), $options_to_exclude) : $options_to_exclude;
  47          $options_to_add = array_merge(array_merge(array('action'=>$this->_controller->Request->getAction(), 'controller' => $this->_controller->Request->getController()),$this->_controller->Request->getUrlParams()),$options_to_add);
  48          foreach ($options_to_exclude as $option_to_exclude){
  49              unset($options_to_add[$option_to_exclude]);
  50          }
  51          return $this->url_for($options_to_add);
  52      }
  53  
  54      /**
  55      * Creates a link tag of the given +name+ using an URL created by the set of +options+. See the valid options in
  56      * the documentation for ActionController::urlFor. It's also possible to pass a string instead of an array of options
  57      * to get a link tag that just points without consideration. If null is passed as a name, the link itself will become 
  58      * the name.
  59      *
  60      * The html_options has three special features. One for creating javascript confirm alerts where if you pass
  61      * 'confirm' => 'Are you sure?', the link will be guarded with a JS popup asking that question. 
  62      * If the user accepts, the link is processed, otherwise not.
  63      *
  64      * Another for creating a popup window, which is done by either passing 'popup' with true or the options of the window in 
  65      * Javascript form.
  66      *
  67      * And a third for making the link do a POST request (instead of the regular GET) through a dynamically added form 
  68      * element that is instantly submitted. Note that if the user has turned off Javascript, the request will fall back on 
  69      * the GET. So its your responsibility to determine what the action should be once it arrives at the controller. 
  70      * The POST form is turned on by passing 'post' as true. Note, it's not possible to use POST requests and popup targets 
  71      * at the same time (an exception will be thrown).
  72      *
  73      * Examples:
  74      *   $url_helper->link_to('Delete this page', array('action' => 'destroy', 'id' => $page->id ), array('confirm' => 'Are you sure?'));
  75      *   $url_helper->link_to('Help', array('action' => 'help'), array('popup' => true));
  76      *   $url_helper->link_to('Busy loop', array('action' => 'busy'), array('popup' => array('new_window', 'height=300,width=600')));
  77      *   $url_helper->link_to('Destroy account', array('action' => 'destroy'), array('confirm' => 'Are you sure?'), array('post' => true));
  78      */
  79      function link_to($name = null, $options = array(), $html_options = array(), $parameters_for_method_reference = null)
  80      {
  81          if (!empty($html_options)) {
  82              $this->convert_options_to_javascript($html_options);
  83              $tag_options = TagHelper::_tag_options($html_options);            
  84          }
  85          else{
  86              $tag_options = null;
  87          }
  88          $url = is_string($options) ? $options : $this->url_for($options, $parameters_for_method_reference);
  89          $name = empty($name) ? $url : $name;
  90          return  "<a href=\"{$url}\"{$tag_options}>{$name}</a>";
  91      }
  92  
  93      /**
  94      * Generates a form containing a sole button that submits to the
  95      * URL given by _$options_.  Use this method instead of +link_to+
  96      * for actions that do not have the safe HTTP GET semantics
  97      * implied by using a hypertext link.
  98      *
  99      * The parameters are the same as for +link_to+.  Any _html_options_
 100      * that you pass will be applied to the inner +input+ element.
 101      * In particular, pass
 102      * 
 103      *   'disabled' => true/false
 104      *
 105      * as part of _html_options_ to control whether the button is
 106      * disabled.  The generated form element is given the class
 107      * 'button-to', to which you can attach CSS styles for display
 108      * purposes.
 109      *
 110      * Example 1:
 111      *
 112      *   // inside of controller for "feeds"
 113      *   $url_helper->button_to('Edit', array('action' => 'edit', 'id' => 3));
 114      *
 115      * Generates the following HTML (sans formatting):
 116      *
 117      *   <form method="post" action="/feeds/edit/3" class="button-to">
 118      *     <div><input type="submit" value="Edit"  /></div>
 119      *   </form>
 120      *
 121      * Example 2:
 122      *
 123      *   $url_helper->button_to('Destroy', array('action' => 'destroy', 'id' => 3 , 'confirm' => 'Are you sure?'));
 124      *
 125      * Generates the following HTML (sans formatting):
 126      *
 127      *   <form method="post" action="/feeds/destroy/3" class="button-to">
 128      *     <div><input onclick="return confirm('Are you sure?');" value="Destroy" type="submit" /></div>
 129      *   </form>
 130      *
 131      * Note: This method generates HTML code that represents a form.
 132      * Forms are "block" content, which means that you should not try to
 133      * insert them into your HTML where only inline content is expected.
 134      * For example, you can legally insert a form inside of a <div> or
 135      * <td> element or in between <p> elements, but not in the middle of
 136      * a run of text, nor can you place a form within another form.
 137      * (Bottom line: Always validate your HTML before going public.)
 138      */
 139      function button_to($name, $options = array(), $html_options = array())
 140      {
 141          $html_options = $this->_convert_boolean_attributes($html_options, 'disabled');
 142  
 143          if(!empty($html_options['confirm'])){
 144              $html_options['onclick'] = 'return '.$this->_confirm_javascript_function($html_options['confirm']).';';
 145              unset($html_options['confirm']);
 146          }
 147  
 148          $url = is_string($options) ? $options : $this->url_for($options);
 149  
 150          $name = !empty($name) ? $name : (is_string($options) ?  $options : TagHelper::escape_once($this->url_for($options)));
 151  
 152          $html_options = array_merge($html_options,array('type'=>'submit','value'=>$name));
 153          return '<form method="post" action="'.$url.'" class="button-to"><div>'.
 154          TagHelper::tag('input', $html_options) . '</div></form>';
 155      }
 156  
 157  
 158      /**
 159      * Creates a link tag of the given +$name+ using an URL created by the set of +$options+, unless the current
 160      * request uri is the same as the link's, in which case only the name is returned. 
 161      * This is useful for creating link bars where you don't want to link
 162      * to the page currently being viewed.
 163      */
 164      function link_to_unless_current($name, $options = array(), $html_options = array(), $parameters_for_method_reference)
 165      {
 166          return $this->current_page($options) ? $this->link_to_unless($options, $name, $options, $html_options, $parameters_for_method_reference) : null;
 167      }
 168  
 169      /**
 170      * Create a link tag of the given +$name+ using an URL created by the set of +options+, unless +condition+
 171      * is true, in which case only the name is returned. 
 172      */
 173      function link_to_unless($condition, $name, $options = array(), $html_options = array(), $parameters_for_method_reference)
 174      {
 175          if ($condition !== true) {
 176              return $this->link_to($name, $options, $html_options, $parameters_for_method_reference);
 177          }
 178          return '';
 179      }
 180  
 181      /**
 182      * Create a link tag of the given +name+ using an URL created by the set of +$options+, if +$condition+
 183      * is true, in which case only the name is returned. 
 184      */      
 185      function link_to_if($condition, $name, $options = array(), $html_options = array(), $parameters_for_method_reference)
 186      {
 187          return $condition ? $this->link_to_unless($condition, $name, $options, $html_options, $parameters_for_method_reference) : null;
 188      }
 189  
 190      /**
 191      * Returns true if the current page uri is generated by the options passed (in url_for format).
 192      */
 193      function current_page($options)
 194      {
 195          return ($this->url_for($options) == $this->_controller->_getCompleteRequestUri());
 196      }
 197  
 198      /**
 199      * Creates a link tag for starting an email to the specified <tt>email_address</tt>, which is also used as the name of the
 200      * link unless +$name+ is specified. Additional HTML options, such as class or id, can be passed in the 
 201      * <tt>$html_options</tt> array.
 202      *
 203      * You can also make it difficult for spiders to harvest email address by obfuscating them.
 204      * Examples:
 205      *   $url_helper->mail_to('me@domain.com', 'My email', array('encode' => 'javascript')) =>
 206      *     <script type="text/javascript" language="javascript">eval(unescape('%64%6f%63%75%6d%65%6e%74%2e%77%72%69%74%65%28%27%3c%61%20%68%72%65%66%3d%22%6d%61%69%6c%74%6f%3a%6d%65%40%64%6f%6d%61%69%6e%2e%63%6f%6d%22%3e%4d%79%20%65%6d%61%69%6c%3c%2f%61%3e%27%29%3b'))</script>
 207      *
 208      *   $url_helper->mail_to('me@domain.com', 'My email', array('encode' => 'hex')) =>
 209      *     <a href="mailto:%6d%65@%64%6f%6d%61%69%6e.%63%6f%6d">My email</a>
 210      *
 211      * You can also specify the cc address, bcc address, subject, and body parts of the message header to create a complex e-mail 
 212      * using the corresponding +cc+, +bcc+, +subject+, and +body+ <tt>html_options</tt> keys. Each of these options are URI escaped 
 213      * and then appended to the <tt>email_address</tt> before being output. <b>Be aware that javascript keywords will not be
 214      * escaped and may break this feature when encoding with javascript.</b>
 215      * 
 216      * Examples:
 217      *   $url_helper->mail_to("me@domain.com", "My email", array('cc' => "ccaddress@domain.com", 'bcc' => "bccaddress@domain.com", 'subject' => "This is an example email", 'body' => "This is the body of the message."))   # =>
 218      *     <a href="mailto:me@domain.com?cc="ccaddress@domain.com"&bcc="bccaddress@domain.com"&body="This%20is%20the%20body%20of%20the%20message."&subject="This%20is%20an%20example%20email">My email</a>
 219      */
 220      function mail_to($email_address, $name = null, $html_options = array())
 221      {
 222          $name = empty($name) ? $email_address : $name;
 223  
 224          $default_options = array(
 225          'cc' => null,
 226          'bcc' => null,
 227          'subject' => null,
 228          'body' => null,
 229          'encode' => ''
 230          );
 231  
 232          $options = array_merge($default_options, $html_options);
 233          $encode = $options['encode'];
 234  
 235          $string = '';
 236          $extras = '';
 237          $extras .= !empty($options['cc']) ? "cc=".urlencode(trim($options['cc'])).'&' : '';
 238          $extras .= !empty($options['bcc']) ? "bcc=".urlencode(trim($options['bcc'])).'&' : '';
 239          $extras .= !empty($options['body']) ? "body=".urlencode(trim($options['body'])).'&' : '';
 240          $extras .= !empty($options['subject']) ? "subject=".urlencode(trim($options['subject'])).'&' : '';
 241  
 242          $extras = empty($extras) ? '' : '?'.str_replace('+','%20',rtrim($extras,'&'));
 243  
 244          $html_options = Ak::delete($html_options, 'cc','bcc','subject','body','encode');
 245  
 246          if ($encode == 'javascript'){
 247              $tmp  = "document.write('".TagHelper::content_tag('a', htmlentities($name, null, Ak::locale('charset')), array_merge($html_options,array('href' => 'mailto:'.$email_address.$extras )))."');";
 248              for ($i=0; $i < strlen($tmp); $i++){
 249                  $string.='%'.dechex(ord($tmp[$i]));
 250              }
 251              return "<script type=\"text/javascript\">eval(unescape('$string'))</script>";
 252  
 253          }elseif ($encode == 'hex'){
 254              $encoded_email_address = '';
 255              $encoded_email_for_name = '';
 256              for ($i=0;$i<strlen($email_address);$i++){
 257                  if(preg_match('/\w/',$email_address[$i])){
 258                      $encoded_email_address .= sprintf('%%%x',ord($email_address[$i]));
 259                  }else{                    
 260                      if ($email_address[$i] == '@') {
 261                          $encoded_email_address .= '%40';
 262                      }
 263                      elseif ($email_address[$i] == '.'){
 264                          $encoded_email_address .= '%2e';
 265                      }
 266                      else{
 267                          $encoded_email_address .= $email_address[$i];
 268                      }
 269                  }
 270                  $encoded_email_for_name .= (rand(1,2)%2 ? '&#'.ord($email_address[$i]).';' : '&#x'.dechex(ord($email_address[$i])).';');
 271              }
 272  
 273              $name = str_replace($email_address,$encoded_email_for_name,$name);
 274  
 275              return TagHelper::content_tag('a', $name, array_merge($html_options,array('href' => 'mailto:'.$encoded_email_address.$extras)));
 276  
 277          }else{
 278              return TagHelper::content_tag('a', $name, array_merge($html_options,array('href' => 'mailto:'.$email_address.$extras)));
 279          }
 280      }
 281  
 282  
 283  
 284      function convert_options_to_javascript(&$html_options)
 285      {
 286          foreach (array('confirm', 'popup', 'post') as $option){
 287              $$option = isset($html_options[$option]) ? $html_options[$option] : false;
 288              unset($html_options[$option]);
 289          }
 290  
 291          $onclick = '';
 292          if ($popup && $post){
 293              trigger_error(Ak::t("You can't use popup and post in the same link"), E_USER_ERROR);
 294              
 295          }elseif($confirm && $popup){
 296              $onclick = 'if ('.$this->_confirm_javascript_function($confirm).') { '.$this->_popup_javascript_function($popup).' };return false;';
 297              
 298          }elseif ($confirm && $post) {
 299              $onclick = 'if ('.$this->_confirm_javascript_function($confirm).') { '.$this->_post_javascript_function().' };return false;';
 300              
 301          }elseif ($confirm) {
 302              $onclick = 'return '.$this->_confirm_javascript_function($confirm).';';
 303              
 304          }elseif ($post) {
 305              $onclick = $this->_post_javascript_function().'return false;';
 306              
 307          }elseif ($popup) {
 308              $onclick = $this->_popup_javascript_function($popup).'return false;';
 309              
 310          }
 311          $html_options['onclick'] = empty($html_options['onclick']) ? $onclick : $html_options['onclick'].$onclick;
 312      }
 313  
 314      function _confirm_javascript_function($confirm)
 315      {
 316          return "confirm('".JavaScriptHelper::escape_javascript($confirm)."')";
 317      }
 318  
 319  
 320  
 321      function _popup_javascript_function($popup)
 322      {
 323          return is_array($popup) ? "window.open(this.href,'".array_shift($popup)."','".array_pop($popup)."');" : "window.open(this.href);";
 324      }
 325  
 326      function _post_javascript_function()
 327      {
 328          return "var f = document.createElement('form'); document.body.appendChild(f); f.method = 'POST'; f.action = this.href; f.submit();";
 329      }
 330  
 331      /**
 332      * processes the _html_options_ array, converting the boolean
 333      * attributes from true/false form into the form required by
 334      * html/xhtml.  (an attribute is considered to be boolean if
 335      * its name is listed in the given _$boolean_attributes_ array.)
 336      *
 337      * more specifically, for each boolean attribute in _$html_option_
 338      * given as:
 339      *
 340      *     "attr" => bool_value
 341      *
 342      * if the associated _bool_value_ evaluates to true, it is
 343      * replaced with the attribute's name; otherwise the attribute is
 344      * removed from the _html_options_ array.  (see the xhtml 1.0 spec,
 345      * section 4.5 "attribute minimization" for more:
 346      * http://www.w3.org/tr/xhtml1/    *h-4.5)
 347      *
 348      * returns the updated _$html_options_ array, which is also modified
 349      * in place.
 350      *
 351      * example:
 352      *
 353      *   $url_helper->convert_boolean_attributes( $html_options,
 354      *                                array('checked','disabled','readonly' ) );
 355      */
 356      function _convert_boolean_attributes(&$html_options, $boolean_attributes)
 357      {
 358          $boolean_attributes = (array)$boolean_attributes;
 359          foreach ($boolean_attributes as $boolean_attribute){
 360              if(empty($html_options[$boolean_attribute])){
 361                  unset($html_options[$boolean_attribute]);
 362              }else {
 363                  $html_options[$boolean_attribute] = $boolean_attribute;
 364              }
 365          }
 366          return $html_options;
 367      }
 368  }
 369  
 370  
 371  ?>


Generated: Mon Oct 27 12:43:49 2008 Cross-referenced by PHPXref 0.6