| [ Index ] |
PHP Cross Reference of Akelos Framework |
[Summary view] [Print] [Text view]
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 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Mon Oct 27 12:43:49 2008 | Cross-referenced by PHPXref 0.6 |