[ Index ]

PHP Cross Reference of Akelos Framework

title

Body

[close]

/AkActionView/helpers/ -> form_options_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  * Provides a number of methods for turning different kinds of containers into a set of option tags.
  24  * == Options
  25  * The <tt>collection_select</tt>, <tt>country_select</tt>, <tt>select</tt>,
  26  * and <tt>time_zone_select</tt> methods take an <tt>options</tt> parameter,
  27  * an array.
  28  *
  29  * * <tt>include_blank</tt> - set to true if the first option element of the select element is a blank. Useful if there is not a default value required for the select element. For example,
  30  *
  31  *   $form_options_helper->select('post','category', $Post->categories, array('include_blank'=>true));
  32  *
  33  * could become:
  34  *
  35  *   <select name="post[category]">
  36  *     <option></option>
  37  *     <option>joke</option>
  38  *     <option>poem</option>
  39  *   </select>
  40  *
  41  * * <tt>prompt</tt> - set to true or a prompt string. When the select element doesn't have a value yet, this prepends an option with a generic prompt -- "Please select" -- or the given prompt string.
  42  *
  43  * Another common case is a select tag for an <tt>belongs_to</tt>-associated object. For example,
  44  *
  45  *   $form_options_helper->select('post', 'person_id', $Person->collect($Person->find(), 'name', 'id'));
  46  *
  47  * could become:
  48  *
  49  *   <select name="post[person_id]">
  50  *     <option value="1">David</option>
  51  *     <option value="2">Sam</option>
  52  *     <option value="3">Tobias</option>
  53  *   </select>
  54  */
  55  class FormOptionsHelper extends AkActionViewHelper
  56  {
  57  
  58  
  59      /**
  60       * Create a select tag and a series of contained option tags for the provided object and method.
  61       * The option currently held by the object will be selected, provided that the object is available.
  62       * See options_for_select for the required format of the choices parameter.
  63       *
  64       * Example with $Post->person_id => 1:
  65       *   $form_options_helper->select('post', 'person_id', $Person->collect($Person->find(), 'name', 'id'), array(), array('include_blank'=>true));
  66       *
  67       * could become:
  68       *
  69       *   <select name="post[person_id]">
  70       *     <option></option>
  71       *     <option value="1" selected="selected">David</option>
  72       *     <option value="2">Sam</option>
  73       *     <option value="3">Tobias</option>
  74       *   </select>
  75       *
  76       * This can be used to provide a default set of options in the standard way: before rendering the create form, a
  77       * new model instance is assigned the default options and bound to $this->model_name. Usually this model is not saved
  78       * to the database. Instead, a second model object is created when the create request is received.
  79       * This allows the user to submit a form page more than once with the expected results of creating multiple records.
  80       * In addition, this allows a single partial to be used to generate form inputs for both edit and create forms.
  81       *
  82       * By default, $post.person_id is the selected option.  Specify 'selected' => value to use a different selection
  83       * or 'selected' => null to leave all options unselected.
  84       */
  85      function select($object_name,  $column_name, $choices, $options = array(), $html_options = array())
  86      {
  87          $InstanceTag = new AkFormHelperOptionsInstanceTag($object_name,  $column_name, $this, null, $this->_object[$object_name]);
  88          return $InstanceTag->to_select_tag($choices, Ak::delete($options,'object'), $html_options);
  89      }
  90  
  91      /**
  92         * Return select and option tags for the given object and column_name using options_from_collection_for_select to generate the list of option tags.
  93         */
  94      function collection_select($object_name,  $column_name, $collection, $value_column_name, $text_column_name, $options = array(), $html_options = array())
  95      {
  96          $InstanceTag = new AkFormHelperOptionsInstanceTag($object_name,  $column_name, $this, null, $this->_object[$object_name]);
  97          return $InstanceTag->to_collection_select_tag($collection, $value_column_name, $text_column_name, Ak::delete($options,'object'), $html_options);
  98      }
  99  
 100      /**
 101        * Return select and option tags for the given object and column_name, using country_options_for_select to generate the list of option tags.
 102        */
 103      function country_select($object_name,  $column_name, $priority_countries = null, $options = array(), $html_options = array())
 104      {
 105          $InstanceTag = new AkFormHelperOptionsInstanceTag($object_name,  $column_name, $this, null, $this->_object[$object_name]);
 106          return $InstanceTag->to_country_select_tag($priority_countries, Ak::delete($options,'object'), $html_options);
 107      }
 108  
 109      /**
 110         * Return select and option tags for the given object and column_name, using
 111         * #time_zone_options_for_select to generate the list of option tags.
 112         *
 113         * In addition to the <tt>include_blank</tt> option documented above,
 114         * this method also supports a <tt>model</tt> option, which defaults
 115         * to TimeZone. This may be used by users to specify a different time
 116         * zone model object. (See #time_zone_options_for_select for more
 117         * information.)
 118         */
 119      function time_zone_select($object_name,  $column_name, $priority_zones = array(), $options = array(), $html_options = array())
 120      {
 121          $InstanceTag = new AkFormHelperOptionsInstanceTag($object_name,  $column_name, $this, null, $this->_object[$object_name]);
 122          return $InstanceTag->to_time_zone_select_tag($priority_zones, Ak::delete($options,'object'), $html_options);
 123      }
 124  
 125      /**
 126         * Accepts a container array and returns a string of option tags. Given a container where the elements respond to first and 
 127         * last (such as a two-element array), the "lasts" serve as option values and the "firsts" as option text. Arrays are turned 
 128         * into this form automatically, so the keys become "firsts" and values become lasts. If +selected+ is specified, the matching 
 129         * "last" or element will get the selected option-tag.  +Selected+ may also be an array of values to be selected when using 
 130         * a multiple select.
 131         *
 132         * Examples (call, result):
 133         *   $form_options_helper->options_for_select(array('Dollar'=>'$', 'Kroner'=>'DKK'));
 134         *     <option value="$">Dollar</option><option value="DKK">Kroner</option>
 135         *
 136         *   $form_options_helper->options_for_select(array('VISA', 'MasterCard'), 'MasterCard');
 137         *     <option value="VISA">VISA</option><option selected="selected" value="MasterCard">MasterCard</option>
 138         *
 139         *   $form_options_helper->options_for_select(array('Basic'=>'$20','Plus'=>'$40'), '$40');
 140         *     <option value="$20">Basic</option><option selected="selected" value="$40">Plus</option>
 141         *
 142         *   $form_options_helper->options_for_select(array('VISA','MasterCard','Discover'), array('VISA','Discover'));
 143         *     <option selected="selected" value="VISA">VISA</option>
 144         *     <option value="MasterCard">MasterCard</option>
 145         *     <option selected="selected" value="Discover">Discover</option>
 146         *
 147         * NOTE: Only the option tags are returned, you have to wrap this call in a regular HTML select tag.
 148         */
 149      function options_for_select($container, $selected = array(), $options = array())
 150      {
 151          $container = (array)$container;
 152          if (empty($container)) {
 153              return '';
 154          }
 155          $container = array_map('strval',$container);
 156  
 157          $text_is_value = count(array_diff(range(0,count($container)-1),array_keys($container))) == 0;
 158  
 159          $selected = (array)$selected;
 160          $options_for_select = '';
 161          
 162          $compare_captions = !empty($selected) ? is_string(key(array_slice($selected,0,1))) : false;
 163         
 164          foreach ($container as $text=>$value){
 165              $options_for_select .= TagHelper::content_tag('option',$text_is_value ? $value : $text,
 166              array_merge($options, ($compare_captions ? 
 167              (isset($selected[$text]) && $selected[$text] == $value) : 
 168              in_array($value, $selected)) ? array('value'=>$value,'selected'=>'selected') : array('value'=>$value))
 169              )."\n";
 170          }
 171          return $options_for_select;
 172      }
 173  
 174      /**
 175         * Returns a string of option tags that have been compiled by iterating over the +collection+ and assigning the
 176         * the result of a call to the +value_column_name+ as the option value and the +text_column_name+ as the option text.
 177         * If +$selected_value+ is specified, the element returning a match on +value_column_name+ will get the selected option tag.
 178         *
 179         * Example (call, result). Imagine a loop iterating over each +person+ in <tt>$Project->People</tt> to generate an input tag:
 180         *   $form_options_helper->options_from_collection_for_select($Project->People,'id','name');
 181         *     <option value="{$Person->id}">{$Person->name}</option>
 182         *
 183         * NOTE: Only the option tags are returned, you have to wrap this call in a regular HTML select tag.
 184         */
 185      function options_from_collection_for_select($collection, $value_column_name, $text_column_name = null, $selected_value = array(), $options = array())
 186      {
 187          $text_column_name = is_null($text_column_name) ? $value_column_name : $text_column_name;
 188          $collection_options = array();
 189          if($value_column_name[0] == '_' || $text_column_name[0] == '_'){
 190              trigger_error(Ak::t('You cannot call private methods from %helper_name helper',array('%helper_name'=>'options_from_collection_for_select'),'helpers/form'), E_USER_ERROR);
 191              return '';
 192          }else{
 193              foreach ($collection as $item){
 194                  $name = method_exists($item,$text_column_name) ? $item->$text_column_name() : $item->get($text_column_name);
 195                  $collection_options[$name] = method_exists($item,$value_column_name) ? $item->$value_column_name() : $item->get($value_column_name);
 196              }
 197              return $this->options_for_select($collection_options,$selected_value,$options);
 198          }
 199      }
 200  
 201      /**
 202        * Returns a string of option tags, like options_from_collection_for_select, but surrounds them with <optgroup> tags.
 203        *
 204        * An array of group objects are passed. Each group should return an array of options when calling group_method
 205        * Each group should return its name when calling group_label_method.
 206        *
 207        * $form_options_helper->option_groups_from_collection_for_select($continents, 'getCountries', 'getContinentName', 'getCountryId', 'getCountryName', $selected_country->id);
 208        *
 209        * Could become:
 210        *     <optgroup label="Africa">
 211        *         <option value="EGP">Egipt</option>
 212        *         <option value="RWD">Rwanda</option>
 213        *         ....
 214        *     </optgroup>
 215        *     
 216        *     <optgroup label="Asia">
 217        *         <option value="ZHN">China</option>
 218        *         <option value="IND">India</option>
 219        *         <option selected="selected" value="JPN">Japan</option>
 220        *         .....
 221        *     </optgroup>
 222        *
 223        * with objects of the following classes:
 224        * class Continent{
 225        *   function Continent($p_name, $p_countries){ $this->continent_name = $p_name; $this->countries = $p_countries;}
 226        *   function getContinentName(){ return $this->continent_name; }
 227        *   function getCountries(){ return $this->countries; }
 228        * }
 229        * class Country {
 230        *   function Country($id, $name){ $this->id = $id; $this->name = $name; }
 231        *   function getCountryId(){ return $this->id; }
 232        *   function getCountryName(){ return $this->name;}
 233        * }
 234        *
 235        * NOTE: Only the option tags are returned, you have to wrap this call in a regular HTML select tag.
 236        */
 237      function option_groups_from_collection_for_select($collection, $group_method, $group_label_method, $option_key_method, $option_value_method, $selected_key = null)
 238      {
 239  
 240          if($group_label_method[0] == '_' || $group_label_method[0] == '_' || $option_key_method[0] == '_' || $option_value_method[0] == '_'){
 241              trigger_error(Ak::t('You cannot call private methods from %helper_name helper',array('%helper_name'=>'option_groups_from_collection_for_select'),'helpers/form'), E_USER_ERROR);
 242          }else{
 243              $options_for_select = '';
 244              foreach ($collection as $group){
 245  
 246                  if(method_exists($group, $group_method)){
 247                      $options_group = $group->{$group_method}();
 248                  }elseif(isset($group->$group_method)){
 249                      $options_group =& $group->$group_method;
 250                  }
 251  
 252                  $options_for_select .= TagHelper::content_tag('optgroup',
 253                  $this->options_from_collection_for_select($options_group, $option_key_method, $option_value_method, $selected_key),
 254                  array('label'=>
 255                  method_exists($group, $group_label_method) ?
 256                  $group->{$group_label_method}() :
 257                  $group->get($group_label_method)
 258                  ));
 259              }
 260              return $options_for_select;
 261          }
 262      }
 263  
 264  
 265      /**
 266         * Returns a string of option tags for pretty much any country in the world. Supply a country name as +selected+ to
 267         * have it marked as the selected option tag. You can also supply an array of countries as +priority_countries+, so
 268         * that they will be listed above the rest of the (long) list.
 269         *
 270         * NOTE: Only the option tags are returned, you have to wrap this call in a regular HTML select tag.
 271         */
 272      function country_options_for_select($selected = null, $priority_countries = array(), $model = 'AkCountries', $options = array())
 273      {
 274          $country_options = '';
 275  
 276          if($model == 'AkCountries'){
 277              require_once (AK_LIB_DIR.DS.'AkLocalize'.DS.'AkCountries.php');
 278              $countries_form_method = AkCountries::all();
 279          }else{
 280              $countries_form_method = $model->all();
 281          }
 282  
 283          if (!empty($priority_countries)){
 284              $country_options .= $this->options_for_select($priority_countries, $selected, $options);
 285              $country_options .= '<option value="">-------------</option>'."\n";
 286          }
 287  
 288          if (!empty($priority_countries) && in_array($selected,$priority_countries)){
 289              $country_options .= $this->options_for_select(array_diff($countries_form_method, $priority_countries), $selected, $options);
 290          }else{
 291              $country_options .= $this->options_for_select($countries_form_method, $selected, $options);
 292          }
 293          return $country_options;
 294      }
 295  
 296      /**
 297      * Returns a string of option tags for pretty much any time zone in the
 298      * world. Supply a TimeZone name as +selected+ to have it marked as the
 299      * selected option tag. You can also supply an array of TimeZones
 300      * as +$priority_zones+, so that they will be listed above the rest of the
 301      * (long) list. 
 302      * 
 303      * The +selected+ parameter must be either +null+, or a string that names
 304      * a TimeZone.
 305      *
 306      * By default, +model+ is an AkTimeZone instance. The only requirement is that the
 307      * +model+ parameter be an object that responds to #all, and returns
 308      * an object with a toString() method and the TimeZone name provided by a 'name'
 309      * attribute
 310      * 
 311      * For a list of supported timezones see: http://www.php.net/manual/en/timezones.php
 312      *
 313      * NOTE: Only the option tags are returned, you have to wrap this call in
 314      * a regular HTML select tag.
 315      */
 316      function time_zone_options_for_select($selected = null, $priority_zones = array(), $model = 'AkTimeZone')
 317      {
 318          $zone_options = '';
 319          if($model == 'AkTimeZone'){
 320              require_once (AK_LIB_DIR.DS.'AkLocalize'.DS.'AkTimeZone.php');
 321              $Zones = AkTimeZone::all();
 322          }else{
 323              $Zones = $model->all();
 324          }
 325  
 326          $zones_for_options = array();
 327          foreach (array_keys($Zones) as $k){
 328              $zones_for_options[$Zones[$k]->toString()] = $Zones[$k]->name;
 329          }
 330  
 331          if (!empty($priority_zones)){
 332              $zone_options .= $this->options_for_select($priority_zones, $selected);
 333              $zone_options .= '<option value="">-------------</option>'."\n";
 334          }
 335          
 336          $zone_options .= $this->options_for_select(array_diff_assoc($zones_for_options,$priority_zones), $selected);
 337          return $zone_options;
 338  
 339      }
 340  
 341  }
 342  
 343  class AkFormHelperOptionsInstanceTag extends AkFormHelperInstanceTag
 344  {
 345      function AkFormHelperOptionsInstanceTag($object_name, $column_name, &$template_object, $local_binding = null, &$object)
 346      {
 347          $this->AkFormHelperInstanceTag($object_name, $column_name, $template_object, $local_binding, $object);
 348      }
 349  
 350      function to_select_tag($choices, $options=array(), $html_options = array())
 351      {
 352          $this->add_default_name_and_id($html_options);
 353          $selected_value = !empty($options['selected']) ? $options['selected'] : $this->getValue();
 354  
 355          return TagHelper::content_tag('select', $this->_addOptions($this->_template_object->options_for_select($choices, $selected_value, $options),
 356          $html_options, $this->getValue()), Ak::delete($html_options,'prompt','include_blank'));
 357      }
 358  
 359      function to_collection_select_tag($collection, $value_column_name, $text_column_name = null, $options = array(), $html_options = array())
 360      {
 361          $this->add_default_name_and_id($html_options);
 362  
 363          return TagHelper::content_tag('select', $this->_addOptions(
 364          $this->_template_object->options_from_collection_for_select($collection, $value_column_name, $text_column_name, $this->getValue(), array_diff($options,array('prompt'=>true))),
 365          $options, $this->getValue()), $html_options);
 366      }
 367  
 368      function to_country_select_tag($priority_countries = array(), $options = array(), $html_options = array())
 369      {
 370          $this->add_default_name_and_id($html_options);
 371          return TagHelper::content_tag('select', $this->_addOptions($this->_template_object->country_options_for_select($this->getValue(), $priority_countries, 'AkCountries', $options),
 372          $options, $this->getValue()), $html_options);
 373      }
 374  
 375      function to_time_zone_select_tag($priority_zones = array(), $options = array(), $html_options = array())
 376      {
 377          $this->add_default_name_and_id($html_options);
 378  
 379          return TagHelper::content_tag('select',
 380          $this->_addOptions($this->_template_object->time_zone_options_for_select(
 381          $this->getValue(),$priority_zones,(empty($options['model'])?'AkTimeZone':$options['model'])),$options,$this->getValue()),$html_options);
 382      }
 383  
 384      function _addOptions($option_tags, $options, $value = null)
 385      {
 386          $option_tags = (!empty($options['include_blank']) ? "<option value=\"\"></option>\n" : '').$option_tags;
 387          if(empty($value) && !empty($options['prompt'])){
 388              return '<option value="">'.(is_string($options['prompt']) ? $options['prompt'] : Ak::t('Please select',array(),'helpers/form'))."</option>\n".$option_tags;
 389          }else{
 390              return $option_tags;
 391          }
 392      }
 393  }
 394  
 395  class AkFormOptionsHelperBuilder extends FormOptionsHelper
 396  {
 397  
 398      function AkFormOptionsHelperBuilder($object_name, $object, &$template)
 399      {
 400          $this->object_name = $object_name;
 401          $this->object = $object;
 402          $this->template =& $template;
 403          $this->proccessing = $object_name;
 404          $this->template->_remove_object_from_options = true;
 405      }
 406  
 407      function select($column_name, $choices, $options = array(), $html_options = array())
 408      {
 409          return $this->template->select($this->object_name, $column_name, $choices, array_merge($options, array('object' => $this->object)), $html_options);
 410      }
 411  
 412      function collection_select($column_name, $collection, $value_column_name, $text_column_name, $options = array(), $html_options = array())
 413      {
 414          return $this->template->collection_select($this->object_name, $column_name, $collection, $value_column_name, $text_column_name, array_merge($options, array('object' => $this->object)), $html_options);
 415      }
 416  
 417      function country_select($column_name, $priority_countries = null, $options = array(), $html_options = array())
 418      {
 419          return $this->template->country_select($this->object_name, $column_name, $priority_countries, array_merge($options, array('object' => $this->object)), $html_options);
 420      }
 421  
 422      function time_zone_select($column_name, $priority_zones = null, $options = array(), $html_options = array())
 423      {
 424          return $this->template->time_zone_select($this->object_name, $column_name, $priority_zones, array_merge($options, array('object' => $this->object)), $html_options);
 425      }
 426  }
 427  
 428  ?>


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