[ Index ]

PHP Cross Reference of Akelos Framework

title

Body

[close]

/AkActionView/helpers/ -> active_record_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  
  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  ?>


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