| [ 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 20 require_once (AK_LIB_DIR.DS.'AkActionView'.DS.'helpers'.DS.'form_helper.php'); 21 22 /** 23 * The Active Record Helper makes it easier to create forms for records kept in instance variables. The most far-reaching is the form 24 * method that creates a complete form for all the basic content types of the record (not associations or aggregations, though). This 25 * is a great of making the record quickly available for editing, but likely to prove lackluster for a complicated real-world form. 26 * In that case, it's better to use the input method and the specialized form methods from the FormHelper 27 */ 28 class ActiveRecordHelper extends AkActionViewHelper 29 { 30 31 /** 32 * Returns a default input tag for the type of object returned by the method. Example 33 * (title is a VARCHAR column and holds "Hello World"): 34 * $active_record_helper->input('post', 'title'); => 35 * <input id="post_title" name="post[title]" size="30" type="text" value="Hello World" /> 36 */ 37 function input($record_name, $method, $options = array()) 38 { 39 $InstanceTag = new ActiveRecordInstanceTag($record_name, $method, $this); 40 return $InstanceTag->to_tag($options); 41 } 42 43 /** 44 * Returns an entire form with input tags and everything for a specified Active Record object. Example 45 * (post is a new record that has a title using VARCHAR and a body using TEXT): 46 * $active_record_helper->form('post'); => 47 * <form action='/post/create' method='post'> 48 * <p> 49 * <label for="post_title">Title</label><br /> 50 * <input id="post_title" name="post[title]" size="30" type="text" value="Hello World" /> 51 * </p> 52 * <p> 53 * <label for="post_body">Body</label><br /> 54 * <textarea cols="40" id="post_body" name="post[body]" rows="20"> 55 * Back to the hill and over it again! 56 * </textarea> 57 * </p> 58 * <input type='submit' value='Create' /> 59 * </form> 60 * 61 * It's possible to specialize the form builder by using a different action name and by supplying another 62 * block renderer that will be evaled by PHP. 63 * Example (entry is a new record that has a message attribute using VARCHAR): 64 * 65 * $active_record_helper->form('entry', array('action'=>'sign','input_block' => 66 * '<p><?=AkInflector::humanize($column)?>: <?=$this->input($record_name, $column)?></p><br />' 67 * ); 68 * 69 * <form action='/post/sign' method='post'> 70 * Message: 71 * <input id="post_title" name="post[title]" size="30" type="text" value="Hello World" /><br /> 72 * <input type='submit' value='Sign' /> 73 * </form> 74 */ 75 function form($record_name, $options = array()) 76 { 77 $record =& $this->_controller->$record_name; 78 79 $options['action'] = !empty($options['action']) ? $options['action'] : ($record->isNewRecord() ? 'create' : 'update'); 80 81 $action = $this->_controller->urlFor(array('action'=>$options['action'], 'id' => $record->getId())); 82 83 $submit_value = !empty($options['submit_value']) ? $options['submit_value'] : strtoupper(preg_replace('/[^\w]/','',$options['action'])); 84 85 $contents = ''; 86 $contents .= $record->isNewRecord() ? '' : $this->_controller->form_helper->hidden_field($record_name, 'id'); 87 $contents .= $this->all_input_tags($record, $record_name, $options); 88 $contents .= FormTagHelper::submit_tag(Ak::t($submit_value,array(),'helpers/active_record')); 89 return TagHelper::content_tag('form', $contents, array('action'=>$action, 'method'=>'post', 90 'enctype'=> !empty($options['multipart']) ? 'multipart/form-data': null )); 91 } 92 93 /** 94 * Returns a string containing the error message attached to the +method+ on the +object+, if one exists. 95 * This error message is wrapped in a DIV tag, which can be specialized to include both a +prepend_text+ and +append_text+ 96 * to properly introduce the error and a +css_class+ to style it accordingly. Examples (post has an error message 97 * "can't be empty" on the title attribute): 98 * 99 * <?= $active_record_helper->error_message_on('post', 'title'); ?> 100 * <div class="formError">can't be empty</div> 101 * 102 * <?=$active_record_helper->error_message_on('post','title','Title simply ', " (or it won't work)", 'inputError') ?> => 103 * <div class="inputError">Title simply can't be empty (or it won't work)</div> 104 */ 105 function error_message_on($object_name, $method, $prepend_text = '', $append_text = '', $css_class = 'formError') 106 { 107 if($errors = $this->_controller->$object_name->getErrorsOn($method)){ 108 $text = $prepend_text.(is_array($errors) ? array_shift($errors) : $errors).$append_text; 109 return TagHelper::content_tag('div', Ak::t($text,array(),'helpers/active_record'), array('class'=>$css_class)); 110 } 111 return ''; 112 } 113 114 /** 115 * Returns a string with a div containing all the error messages for the object located as an instance variable by the name 116 * of <tt>object_name</tt>. This div can be tailored by the following options: 117 * 118 * * <tt>header_tag</tt> - Used for the header of the error div (default: h2) 119 * * <tt>id</tt> - The id of the error div (default: errorExplanation) 120 * * <tt>class</tt> - The class of the error div (default: errorExplanation) 121 * 122 * NOTE: This is a pre-packaged presentation of the errors with embedded strings and a certain HTML structure. If what 123 * you need is significantly different from the default presentation, it makes plenty of sense to access the $object->getErrors() 124 * instance yourself and set it up. View the source of this method to see how easy it is. 125 */ 126 function error_messages_for($object_name, $options = array()) 127 { 128 $object =& $this->_controller->$object_name; 129 if($object->hasErrors()){ 130 $error_list = '<ul>'; 131 foreach ($object->getFullErrorMessages() as $field=>$errors){ 132 foreach ($errors as $error){ 133 $error_list .= TagHelper::content_tag('li',Ak::t($error,array(),'helpers/active_record')); 134 } 135 } 136 $error_list .= '</ul>'; 137 return 138 TagHelper::content_tag('div', 139 TagHelper::content_tag( 140 (!empty($options['header_tag']) ? $options['header_tag'] :'h2'), 141 Ak::t('%number_of_errors %errors prohibited this %object_name from being saved' , 142 array('%number_of_errors'=>$object->countErrors(),'%errors'=>Ak::t(AkInflector::conditionalPlural($object->countErrors(),'error'),array(),'helpers/active_record'), 143 '%object_name'=>Ak::t(AkInflector::humanize($object->getModelName()),array(),'helpers/active_record')) 144 ,'helpers/active_record')). 145 TagHelper::content_tag('p', Ak::t('There were problems with the following fields:',array(),'helpers/active_record')). 146 $error_list, 147 array('id'=> !empty($options['id']) ? $options['id'] : 'errorExplanation', 'class' => !empty($options['class']) ? $options['class'] : 'errorExplanation') 148 ); 149 } 150 } 151 152 153 function all_input_tags(&$record, $record_name, $options = array()) 154 { 155 $input_block = !empty($options['input_block']) ? $options['input_block'] : $this->default_input_block(); 156 $columns = empty($options['columns']) ? array_keys($record->getContentColumns()) : $options['columns']; 157 $result = ''; 158 foreach ($columns as $column){ 159 ob_start(); 160 eval("?>$input_block<?php "); 161 $result .= ob_get_clean()."\n"; 162 } 163 return $result; 164 } 165 166 function default_input_block() 167 { 168 return '<p><label for="<?=$record_name?>_<?=$column?>"><?=AkInflector::humanize($column)?></label><br /><?=$this->input($record_name, $column)?></p>'; 169 } 170 } 171 172 class ActiveRecordInstanceTag extends AkFormHelperInstanceTag 173 { 174 var $method_name; 175 176 function ActiveRecordInstanceTag($object_name, $column_name, &$template_object) 177 { 178 $column_name = $this->method_name = $this->_getColumnName($column_name, $object_name, $template_object); 179 $this->AkFormHelperInstanceTag($object_name, $column_name, $template_object); 180 } 181 182 function to_tag($options = array()) 183 { 184 $options = array_merge($this->object->getErrorsOn($this->method_name)==false?array():array("class"=>"fieldError"), $options); 185 186 switch ($this->get_column_type()) { 187 188 case 'string': 189 $field_type = strstr($this->method_name,'password') ? 'password' : 'text'; 190 return $this->to_input_field_tag($field_type, $options); 191 break; 192 193 case 'text': 194 return $this->to_text_area_tag($options); 195 break; 196 197 case 'integer': 198 case 'float': 199 return $this->to_input_field_tag('text', $options); 200 break; 201 202 case 'date': 203 return $this->to_date_select_tag($options); 204 break; 205 206 case 'datetime': 207 case 'timestamp': 208 return $this->to_datetime_select_tag($options); 209 break; 210 211 case 'boolean': 212 return $this->to_check_box_tag($options); 213 break; 214 215 default: 216 return ''; 217 break; 218 } 219 } 220 221 function tag($name, $options) 222 { 223 if($this->object->hasErrors()){ 224 return $this->error_wrapping($this->tag_without_error_wrapping($name, $options), $this->object->getErrorsOn($this->method_name)); 225 }else{ 226 return $this->tag_without_error_wrapping($name, $options); 227 } 228 } 229 230 function tag_without_error_wrapping($name, $options) 231 { 232 return parent::tag($name, $options); 233 } 234 235 236 function content_tag($name, $value, $options) 237 { 238 if($this->object->hasErrors()){ 239 return $this->error_wrapping($this->content_tag_without_error_wrapping($name, $value, $options), $this->object->getErrorsOn($this->method_name)); 240 }else{ 241 return $this->content_tag_without_error_wrapping($name, $value, $options); 242 } 243 } 244 245 function content_tag_without_error_wrapping($name, $value, $options) 246 { 247 return parent::content_tag($name, $value, $options); 248 } 249 250 function to_date_select_tag($options = array()) 251 { 252 if($this->object->hasErrors()){ 253 return $this->error_wrapping($this->to_date_select_tag_without_error_wrapping($options), $this->object->getErrorsOn($this->method_name)); 254 }else{ 255 return $this->to_date_select_tag_without_error_wrapping($options); 256 } 257 } 258 259 function to_date_select_tag_without_error_wrapping($options = array()) 260 { 261 return parent::to_date_select_tag($options); 262 } 263 264 function to_datetime_select_tag($options = array()) 265 { 266 if($this->object->hasErrors()){ 267 return $this->error_wrapping($this->to_datetime_select_tag_without_error_wrapping($options), $this->object->getErrorsOn($this->method_name)); 268 }else{ 269 return $this->to_datetime_select_tag_without_error_wrapping($options); 270 } 271 } 272 273 function to_datetime_select_tag_without_error_wrapping($options = array()) 274 { 275 return parent::to_datetime_select_tag($options); 276 } 277 278 function to_check_box_tag($options = array()) 279 { 280 if($this->object->hasErrors()){ 281 return $this->error_wrapping($this->to_check_box_tag_without_error_wrapping($options), $this->object->getErrorsOn($this->method_name)); 282 }else{ 283 return $this->to_check_box_tag_without_error_wrapping($options); 284 } 285 } 286 287 function to_check_box_tag_without_error_wrapping($options = array()) 288 { 289 return parent::to_check_box_tag($options); 290 } 291 292 function error_wrapping($html_tag, $has_error) 293 { 294 return $has_error ? "<div class=\"fieldWithErrors\">$html_tag</div>" : $html_tag; 295 } 296 297 function error_message() 298 { 299 return $this->object->getErrorsOn($this->method_name); 300 } 301 302 function get_column_type() 303 { 304 return $this->object->getColumnType($this->method_name); 305 } 306 307 function _getColumnName($column_name, $object_name, &$template_object) 308 { 309 $object =& $template_object->_controller->{$object_name}; 310 $internationalized_columns = $object->getInternationalizedColumns(); 311 if(!empty($internationalized_columns[$column_name])) { 312 $current_locale = $object->getCurrentLocale(); 313 if(in_array($current_locale, $internationalized_columns[$column_name])) { 314 $column_name = $current_locale.'_'.$column_name; 315 } 316 } 317 return $column_name; 318 } 319 } 320 321 ?>
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 |