[ Index ]
 

Code source de PHPonTrax 2.6.6-svn

Accédez au Source d'autres logiciels libresSoutenez Angelica Josefina !

title

Body

[fermer]

/vendor/trax/action_view/helpers/ -> date_helper.php (source)

   1  <?php
   2  /**
   3   *  File containing the DateHelper class and support functions
   4   *
   5   *  (PHP 5)
   6   *
   7   *  @package PHPonTrax
   8   *  @version $Id: date_helper.php 230 2006-07-18 18:47:39Z john $
   9   *  @copyright (c) 2005 John Peterson
  10   *
  11   *  Permission is hereby granted, free of charge, to any person obtaining
  12   *  a copy of this software and associated documentation files (the
  13   *  "Software"), to deal in the Software without restriction, including
  14   *  without limitation the rights to use, copy, modify, merge, publish,
  15   *  distribute, sublicense, and/or sell copies of the Software, and to
  16   *  permit persons to whom the Software is furnished to do so, subject to
  17   *  the following conditions:
  18   *
  19   *  The above copyright notice and this permission notice shall be
  20   *  included in all copies or substantial portions of the Software.
  21   *
  22   *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  23   *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  24   *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  25   *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  26   *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  27   *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  28   *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  29   */
  30  
  31  /**
  32   *  Utility to help build HTML pulldown menus for date and time
  33   */
  34  class DateHelper extends Helpers {
  35  
  36      /**
  37       *  Year values parsed from $_REQUEST
  38       *
  39       *  Set by {@link check_request_for_value()}.  An array whose keys
  40       *  are the names of attributes of the {@link ActiveRecord}
  41       *  subclass named by {@link $object_name}, and whose values are
  42       *  the strings parsed from $_REQUEST.
  43       *  @var string[]
  44       */
  45      public $request_years;
  46  
  47      /**
  48       *  Month values parsed from $_REQUEST
  49       *
  50       *  Set by {@link check_request_for_value()}.  An array whose keys
  51       *  are the names of attributes of the {@link ActiveRecord}
  52       *  subclass named by {@link $object_name}, and whose values are
  53       *  the strings parsed from $_REQUEST.
  54       *  @var string[]
  55       */
  56      public $request_months = array();
  57  
  58      /**
  59       *  Day of month values parsed from $_REQUEST
  60       *
  61       *  Set by {@link check_request_for_value()}.  An array whose keys
  62       *  are the names of attributes of the {@link ActiveRecord}
  63       *  subclass named by {@link $object_name}, and whose values are
  64       *  the strings parsed from $_REQUEST.
  65       *  @var string[]
  66       */
  67      public $request_days;
  68  
  69      /**
  70       *  Hour values parsed from $_REQUEST
  71       *
  72       *  Set by {@link check_request_for_value()}.  An array whose keys
  73       *  are the names of attributes of the {@link ActiveRecord}
  74       *  subclass named by {@link $object_name}, and whose values are
  75       *  the strings parsed from $_REQUEST.
  76       *  @var string[]
  77       */
  78      public $request_hours;
  79  
  80      /**
  81       *  Minute values parsed from $_REQUEST
  82       *
  83       *  Set by {@link check_request_for_value()}.  An array whose keys
  84       *  are the names of attributes of the {@link ActiveRecord}
  85       *  subclass named by {@link $object_name}, and whose values are
  86       *  the strings parsed from $_REQUEST.
  87       *  @var string[]
  88       */
  89      public $request_minutes;
  90  
  91      /**
  92       *  Second values parsed from $_REQUEST
  93       *
  94       *  Set by {@link check_request_for_value()}.  An array whose keys
  95       *  are the names of attributes of the {@link ActiveRecord}
  96       *  subclass named by {@link $object_name}, and whose values are
  97       *  the strings parsed from $_REQUEST.
  98       *  @var string[]
  99       */
 100      public $request_seconds;
 101  
 102      /**
 103       *  <b>FIXME:</b>  Dead code?
 104       */
 105      public $selected_years = array();
 106  
 107      /**
 108       *  Constructor
 109       *
 110       *  Construct an instance of Helpers with the same arguments
 111       *  @param string Name of an ActiveRecord subclass
 112       *  @param string Name of an attribute of $object
 113       */
 114      function __construct($object_name = null, $attribute_name = null) {
 115          parent::__construct($object_name, $attribute_name);
 116      }
 117      
 118      /**
 119       *  Check whether $_REQUEST holds value for this attribute
 120       *
 121       *  Called with the name of an ActiveRecord subclass in
 122       *  $this->object_name and the name of one of its attributes in
 123       *  $this->attribute_name.  Check whether $_REQUEST contains a
 124       *  value for this attribute; if so return it.
 125       *  @return mixed String value if attribute was found in
 126       *                $_REQUEST, otherwise false
 127       *  @uses attribute_name
 128       *  @uses object_name
 129       *  @uses request_years
 130       *  @uses request_months
 131       *  @uses request_days
 132       *  @uses request_hours
 133       *  @uses request_minutes
 134       *  @uses request_seconds
 135       */
 136      private function check_request_for_value() {
 137          //error_log("check_request_for_value().  object name='"
 138          //          . $this->object_name ."'  attribute name = '"
 139          //          . $this->attribute_name ."'");
 140  
 141          //  If $_REQUEST[$this->object_name] does not exist,
 142          //  return false immediately
 143          if (!isset($_REQUEST) || !is_array($_REQUEST)
 144              || !array_key_exists($this->object_name, $_REQUEST)) {
 145              return false;
 146          }
 147  
 148          //  $_REQUEST[$this->object_name] exists.
 149          //  Look for the requested attribute
 150          if (array_key_exists($this->attribute_name,
 151                               $_REQUEST[$this->object_name])) {
 152  
 153              //  Requested attribute found, return it
 154              return $_REQUEST[$this->object_name][$this->attribute_name];
 155          }
 156  
 157          //  There is an element $_REQUEST[$this->object_name] but not
 158          //  $_REQUEST[$this->object_name][$this->attribute_name] so
 159          //  check for the individual components of a date/time
 160  
 161          //  Keep track of whether we find any components
 162          $found = false;
 163  
 164          //    Check for year component
 165          if (array_key_exists($this->attribute_name."(1i)",
 166                               $_REQUEST[$this->object_name])) {
 167              $this->request_years[$this->attribute_name] =
 168                  $_REQUEST[$this->object_name][$this->attribute_name."(1i)"];
 169              $found = true;
 170          }
 171  
 172          //    Check for month component
 173          if (array_key_exists($this->attribute_name."(2i)",
 174                               $_REQUEST[$this->object_name])) {
 175              $this->request_months[$this->attribute_name] =
 176                  $_REQUEST[$this->object_name][$this->attribute_name."(2i)"];
 177              $found = true;
 178          }
 179  
 180          //    Check for day component
 181          if (array_key_exists($this->attribute_name."(3i)",
 182                               $_REQUEST[$this->object_name])) {
 183              $this->request_days[$this->attribute_name] =
 184                  $_REQUEST[$this->object_name][$this->attribute_name."(3i)"];
 185              $found = true;
 186          }
 187  
 188          //    Check for hour component
 189          if (array_key_exists($this->attribute_name."(4i)",
 190                               $_REQUEST[$this->object_name])) {
 191              $this->request_hours[$this->attribute_name] =
 192                  $_REQUEST[$this->object_name][$this->attribute_name."(4i)"];
 193              $found = true;
 194          }   
 195  
 196          //    Check for minute component
 197          if (array_key_exists($this->attribute_name."(5i)",
 198                               $_REQUEST[$this->object_name])) {
 199              $this->request_minutes[$this->attribute_name] =
 200                  $_REQUEST[$this->object_name][$this->attribute_name."(5i)"];
 201              $found = true;
 202          }              
 203  
 204          //    Check for second component
 205          if (array_key_exists($this->attribute_name."(6i)",
 206                               $_REQUEST[$this->object_name])) {
 207              $this->request_seconds[$this->attribute_name] =
 208                  $_REQUEST[$this->object_name][$this->attribute_name."(6i)"];
 209              $found = true;
 210          }                                                                   
 211          return $found;
 212      }
 213  
 214      /**
 215       *  Generate HTML/XML for select to enclose option list
 216       *
 217       *  @param string   Name attribute for <samp><select name=... ></samp>
 218       *  @param string   <samp><option>...</option><samp> list
 219       *  @param string   Prefix of name attribute, to be enclosed in
 220       *                  square brackets
 221       *  @param boolean  Whether to include a blank in the list of
 222       *                  select options  
 223       *  @param boolean  Whether to discard the type
 224       *  @return string  Generated HTML
 225       */
 226      private function select_html($type, $options, $prefix = null,
 227                                   $include_blank = false,
 228                                   $discard_type = false) {
 229          $select_html  = "<select name=\"$prefix";       
 230          if(!$discard_type) {
 231              if($prefix) $select_html .= "["; 
 232              $select_html .= $type;
 233              if($prefix) $select_html .= "]"; 
 234          }
 235          $select_html .= "\">\n";
 236          if($include_blank) $select_html .= "<option value=\"\"></option>\n";
 237          $select_html .= $options;
 238          $select_html .= "</select>\n";
 239          return $select_html;
 240      }
 241  
 242      /**
 243       *  Prefix a leading zero to single digit numbers
 244       *  @param string   A number
 245       *  @return string  Number with zero prefix if value <= 9
 246       */
 247      private function leading_zero_on_single_digits($number) {
 248          return $number > 9 ? $number : "0$number";
 249      }
 250  
 251      /**
 252       *  Get attribute value from $_REQUEST if there, otherwise from database
 253       *
 254       *  When called, {@link $object_name} describes the
 255       *  {@link ActiveRecord} subclass and {@link $attribute_name}
 256       *  describes the attribute whose value is desired.
 257       *
 258       *  An attempt is made to find the value in $_REQUEST, where it
 259       *  would be found after the browser POSTed a form.  If no value
 260       *  is found there, then the database is accessed for the value.
 261       *  When accessing the database, the assumption is made that the
 262       *  {@link ActionController} object refers to a single
 263       *  {@link ActiveRecord} subclass object which correctly
 264       *  identifies the table and record containing the attribute
 265       *  value.
 266       *  @return mixed Attribute value if found
 267       *  @uses check_request_for_value()
 268       *  @uses attribute_name
 269       *  @uses object()
 270       *  @uses ActiveRecord::send()
 271       */
 272      protected function value() {
 273          //error_log("DateHelper::value()  object name={$this->object_name}"
 274          //          . "   attribute name={$this->attribute_name}");
 275  
 276          //  First try to get attribute value from $_REQUEST
 277          if(!$value = $this->check_request_for_value()) {
 278  
 279              //  Value not found in $_REQUEST so we need to
 280              //  go to the database.  Assume that the controller
 281              //  points to the right ActiveRecord object
 282              $object = $this->object();
 283              if(is_object($object) && $this->attribute_name) {
 284                  $value = $object->send($this->attribute_name);
 285              }
 286          }
 287          return $value;
 288      }
 289      
 290      /**
 291       *  Call to_expiration_date_select_tag()
 292       *
 293       *  Alias for {@link to_expiration_date_select_tag()}
 294       *  @param mixed[]  Output format options
 295       *  @return string Generated HTML
 296       *  @uses to_expiration_date_select_tag()
 297       */
 298      function expiration_date_select($options = array()) {
 299          return $this->to_expiration_date_select_tag($options);      
 300      }
 301          
 302      /**
 303       *  Call to_datetime_select_tag()
 304       *
 305       *  Alias for {@link to_datetime_select_tag()}
 306       *  @param mixed[]  Output format options
 307       *  @return string Generated HTML
 308       *  @uses to_datetime_select_tag()
 309       */
 310      function datetime_select($options = array()) {     
 311          return $this->to_datetime_select_tag($options);
 312      } 
 313      
 314      /**
 315       *  Call to_date_select_tag()
 316       *
 317       *  Alias for {@link to_date_select_tag()}
 318       *  @param mixed[]  Output format options
 319       *  @return string Generated HTML
 320       *  @uses to_date_select_tag()
 321       */
 322      function date_select($options = array()) {   
 323          //error_log("date_select() object=$this->object_name"
 324          //          . "   attribute=$this->attribute_name");
 325          return $this->to_date_select_tag($options);
 326      }  
 327      
 328      /**
 329       *  Generate HTML/XML for expiration month and year selector
 330       *  pulldowns
 331       *
 332       *  Generates HTML for a month and year pulldown.  The year
 333       *  pulldown has a range of years from the initially selected year
 334       *  to seven years after.
 335       *
 336       *  When called, $_REQUEST[] may have initial date values in
 337       *  fields with default names of 'expiration_month' and
 338       *  'expiration_year'.  If these values exist they override the
 339       *  first parameter.
 340       *  @param string   Date to display as initially selected if none
 341       *    was found in $_REQUEST[].  If omitted, default value is the
 342       *    current calendar date.<b>FIXME:</b> this doesn't work
 343       *  @param mixed[]  Output format options:
 344       *  <ul>
 345       *    <li><samp>'field_separator' => '</samp><i>somestring</i><samp>'</samp><br />
 346       *      String to insert between the month and year selectors.  If
 347       *      none is specified, default value is <samp>' / '</samp></li>
 348       *    <li><samp>'month_before_year' => 'false'<br />
 349       *      Output year selector first, then month selector.
 350       *      If option not specified, the month selector will be output
 351       *      first.</li>
 352       *    <li><samp>'month_name' =>'</samp><i>somestring</i><samp>'</samp><br />
 353       *      Set the name of the generated month selector to
 354       *      <i>somestring</i>.  If option not specified, default name is
 355       *      <samp>expiration_month</samp></li>
 356       *    <li><samp>'year_name' => '</samp><i>somestring</i><samp>'</samp><br />
 357       *      Set the name of the generated year selector to
 358       *      <i>somestring</i>.  If option not specified, default name is
 359       *      <samp>expiration_year</samp></li>
 360       *  </ul>
 361       *  @return string Generated HTML
 362       *  @uses select_html()
 363       *  @uses select_month()
 364       *  @uses select_year()
 365       */
 366      function select_expiration_date($date = null, $options = array()) {
 367  //        error_log("select_expiration_date('"
 368  //                  . (is_null($date) ? 'null' : $date)
 369  //                  ."', " . var_export($options,true));
 370          $options['month_before_year'] = true;      
 371          $options['use_month_numbers'] = true;   
 372          $options['start_year'] = date("Y");
 373          $options['end_year'] = date("Y") + 7;
 374          $options['field_separator'] = " / ";        
 375  
 376          //  Find name and initial value of year field,
 377          //  then generate year selector pulldown
 378          $options['field_name'] = array_key_exists('year_name',$options)
 379              ? $options['year_name'] : "expiration_year"; 
 380          $date = array_key_exists($options['field_name'], $_REQUEST)
 381              ? date("Y-m-d",
 382                     strtotime($_REQUEST[$options['field_name']]."-01-01"))
 383              : date("Y-m-d");
 384          $year_select = $this->select_year($date, $options);
 385  
 386          //  Find name and initial value of month field,
 387          //  then generate year selector pulldown
 388          $options['field_name'] = array_key_exists('month_name',$options)
 389              ? $options['month_name'] : "expiration_month";
 390          $date = array_key_exists($options['field_name'], $_REQUEST)
 391              ? date("Y-m-d",
 392                     strtotime("2006-".$_REQUEST[$options['field_name']]."-01"))
 393              : date("Y-m-d");
 394          $month_select = $this->select_month($date, $options);
 395  
 396          //  Output month and year selectors in desired order
 397          if($options['month_before_year']) {
 398              $select_html =  $month_select . $options['field_separator']
 399                  .  $year_select;     
 400          } else {
 401              $select_html =  $year_select . $options['field_separator']
 402                  .  $month_select;
 403          }
 404          return $select_html;
 405      }               
 406  
 407      /**
 408       *  Generate HTML/XML for year, month and day selector pull-down menus
 409       *
 410       *  Returns <samp><select>...</select></samp> HTML with options
 411       *  for a number of years, months and days.  The first argument,
 412       *  if present, specifies the initially selected date.  The second
 413       *  argument controls the format of the generated HTML.
 414       *
 415       *  Examples:
 416       *  <ul>
 417       *   <li><samp>select_date();</samp><br /> Generates a group of
 418       *     three pulldown menus in the order year, month and day with
 419       *     the current date initially selected.</li> 
 420       *   <li>
 421       *  <samp>select_date('August 4, 1998');</samp><br /> Generates a
 422       *    group of   three pulldown menus in the order year, month and
 423       *    day with the date August 4, 1998 initially selected.</li> 
 424       *  </ul>
 425       *
 426       *  @param string   Date to display as initially selected if none
 427       *    was found in
 428       *    {@link $request_years}[{@link $attribute_name}],
 429       *    {@link $request_months}[{@link $attribute_name}] and
 430       *    {@link $request_days}[{@link $attribute_name}].
 431       *    Character string is any US English date representation
 432       *    supported by {@link strtotime()}.  If omitted, the
 433       *    current date is initially selected.
 434       *
 435       *  @param mixed[] Output format options are all of the options of
 436       *    {@link select_year()}, {@link select_month()} and
 437       *    {@link select_day()}.
 438       *  @return string  Generated HTML
 439       *  @uses select_day()
 440       *  @uses select_month()
 441       *  @uses select_year()
 442       */
 443      function select_date($date = null, $options = array()) {
 444          $date = is_null($date) ? date("Y-m-d") : $date;
 445          return $this->select_year($date, $options) .
 446                  $this->select_month($date, $options) .
 447                  $this->select_day($date, $options);
 448      }
 449  
 450      /**
 451       *  Generate HTML/XML for year-month-day-hour-minute selector pulldowns
 452       *
 453       *  Returns <samp><select>...</select></samp> HTML with options
 454       *  for a number of years, months, days, hours and minutes.  The
 455       *  first argument, if present, specifies the initially selected
 456       *  date.  The second argument controls the format of the
 457       *  generated HTML.
 458       *
 459       *  Examples:
 460       *  <ul>
 461       *   <li><samp>select_datetime();</samp><br /> Generates a group of
 462       *     five pulldown menus in the order year, month, day, hour and
 463       *     minute with the current date and time initially
 464       *    selected.</li> 
 465       *   <li>
 466       *  <samp>select_datetime('1998-04-08 13:21:17');</samp><br />
 467       *    Generates a group of five pulldown menus in the order year,
 468       *    month, day, hour and minute with the date/time
 469       *    1998 August 4 13:21 initially selected.</li> 
 470       *  </ul>
 471       *
 472       *  @param string   Date/time to display as initially selected.
 473       *    Character string is any US English date representation
 474       *    supported by {@link strtotime()}.  If omitted, the
 475       *    current date/time is initially selected.
 476       *
 477       *  @param mixed[] Output format options are all of the options of
 478       *    {@link select_year()}, {@link select_month()},
 479       *    {@link select_day()}, {@link select_hour()} and
 480       *    {@link select_minute()}. 
 481       *  @return string  Generated HTML
 482       *  @uses select_day()
 483       *  @uses select_hour()
 484       *  @uses select_minute()
 485       *  @uses select_month()
 486       *  @uses select_year()
 487       */
 488      function select_datetime($datetime = null, $options = array()) {
 489          $datetime = is_null($datetime) ? date("Y-m-d H:i:s") : $datetime;
 490          return $this->select_year($datetime, $options) .
 491                  $this->select_month($datetime, $options) .
 492                  $this->select_day($datetime, $options) .
 493                  $this->select_hour($datetime, $options) .
 494                  $this->select_minute($datetime, $options);
 495      }
 496  
 497      /**
 498       *  Generate HTML/XML for hour, minute and second selector pull-down menus
 499       *
 500       *  Returns <samp><select>...</select></samp> HTML with options
 501       *  for a number of hours, minutes and seconds.  The first argument,
 502       *  if present, specifies the initially selected time.  The second
 503       *  argument controls the format of the generated HTML.
 504       *
 505       *  Examples:
 506       *  <ul>
 507       *   <li><samp>select_time();</samp><br /> Generates two pulldown
 508       *     menus in the order hour : minute with
 509       *     the current time initially selected.</li> 
 510       *   <li>
 511       *  <samp>select_time('August 4, 1998 8:12');</samp><br /> Generates
 512       *    two pulldown menus in the order hour : minute with the 
 513       *    time 8:12 initially selected.</li> 
 514       *  </ul>
 515       *
 516       *  @param string   Time to display as initially selected if none
 517       *    was found in
 518       *    {@link $request_hours}[{@link $attribute_name}],
 519       *    {@link $request_minutes}[{@link $attribute_name}] and
 520       *    {@link $request_seconds}[{@link $attribute_name}].
 521       *    Character string is any US English date/time representation
 522       *    supported by {@link strtotime()}.  If omitted, the
 523       *    current time is initially selected.
 524       *
 525       *  @param mixed[] Output format options are all of the options of
 526       *    {@link select_hour()}, {@link select_minute()} and
 527       *    {@link select_second()}.
 528       *  @return string  Generated HTML
 529       *  @uses select_hour()
 530       *  @uses select_minute()
 531       *  @uses select_second()
 532       */
 533      function select_time($datetime = null, $options = array()) {
 534          $datetime = is_null($datetime) ? date("Y-m-d H:i:s") : $datetime;
 535          return $this->select_hour($datetime, $options) .
 536                 $this->select_minute($datetime, $options) .
 537              (array_key_exists('include_seconds', $options)
 538               && $options['include_seconds']
 539               ? $this->select_second($datetime, $options) : '');
 540      }
 541  
 542      /**
 543       *  Generate HTML/XML for second selector pull-down menu
 544       *
 545       *  Returns <samp><select>...</select></samp> HTML with an option
 546       *  for each of the sixty seconds.  The first argument, if
 547       *  present, specifies the initially selected second.  The second
 548       *  argument controls the format of the generated HTML.
 549       *
 550       *  Examples:
 551       *  <ul>
 552       *   <li><samp>select_second();</samp><br />
 553       *     Generates menu '00', '01', ..., '59'.  Initially selected
 554       *     second is the second in
 555       *     {@link $request_seconds}[{@link $attribute_name}], or if that
 556       *     is not defined, the current second.</li>
 557       *   <li><samp>select_second(null,array('include_blank' => true));</samp>
 558       *    <br />Generates menu ' ', '00', '01',..., '59'.  Initially
 559       *    selected second same as above.</li>
 560       *  </ul>
 561       *
 562       *  @param string  Initially selected second as two-digit number.
 563       *  If a value for this field is specified in
 564       *  {@link $request_seconds}[{@link $attribute_name}], then that second
 565       *  is initially selected regardless of the value of this argument.
 566       *  Otherwise, if the first argument is present and is a character
 567       *  string of two decimal digits with a value in the range
 568       *  '00'..'59' then that second is initially selected.  If this
 569       *  argument is absent or invalid, the current second is
 570       *  initially selected.
 571       *  @param mixed[] Output format options:
 572       *  <ul>
 573       *    <li><samp>'include_blank' => true</samp> Show a blank
 574       *      as the first option.</li>
 575       *    <li><samp>'field_name' => '</samp><i>somestring</i><samp>'</samp>
 576       *      Generate output<br />
 577       *      <samp><select name="</samp><i>somestring</i><samp>">...</select></samp> .
 578       *      <br />If absent, generate output<br />
 579       *      <samp><select name="second">...</select></samp>.</li>
 580       *    <li><samp>'discard_type' => ???</samp> FIXME</li>
 581       *    <li><samp>'prefix' => ???</samp> FIXME</li>
 582       *  </ul>
 583       *
 584       *  @return string  Generated HTML
 585       *  @uses attribute_name
 586       *  @uses leading_zero_on_single_digits()
 587       *  @uses request_seconds
 588       *  @uses select_html()
 589       */
 590      function select_second($datetime=null, $options = array()) {
 591          //error_log("select_second() \$datetime=$datetime  \$options="
 592          //          .var_export($options,true));
 593          $second_options = "";
 594          
 595          if($this->request_seconds[$this->attribute_name]) {
 596              $datetime_sec = $this->request_seconds[$this->attribute_name];    
 597          } elseif(strlen($datetime) == 2 && is_numeric($datetime)) {
 598              $datetime_sec = $datetime;
 599          } else {                  
 600              $datetime = $options['value'] ? $options['value'] :
 601                  ($datetime ? $datetime : date("Y-m-d H:i:s")); 
 602              $datetime_sec = date("s",strtotime($datetime));
 603          }
 604          
 605          for($second = 0; $second <= 59; $second++) {          
 606              $second_options .= ($datetime && ($datetime_sec == $second)) ?
 607              "<option value=\"".$this->leading_zero_on_single_digits($second)."\"  selected=\"selected\">".$this->leading_zero_on_single_digits($second)."</option>\n" :
 608              "<option value=\"".$this->leading_zero_on_single_digits($second)."\">".$this->leading_zero_on_single_digits($second)."</option>\n";
 609          }
 610          $field_name = array_key_exists('field_name',$options)
 611                         ? $options['field_name'] : 'second';
 612          return $this->select_html($field_name, $second_options,
 613                                    array_key_exists('prefix',$options)
 614                                    ? $options['prefix'] : null,
 615                                    array_key_exists('include_blank',$options)
 616                                    ? $options['include_blank'] : false,
 617                                    array_key_exists('discard_type',$options)
 618                                    ? $options['discard_type'] : false);
 619      }
 620  
 621      /**
 622       *  Generate HTML/XML for minute selector pull-down menu
 623       *
 624       *  Returns <samp><select>...</select></samp> HTML with an option
 625       *  for each of the sixty minutes.  The first argument, if
 626       *  present, specifies the initially selected minute.  The second
 627       *  argument controls the format of the generated HTML.
 628       *
 629       *  Examples:
 630       *  <ul>
 631       *   <li><samp>select_minute();</samp><br />
 632       *     Generates menu '00', '01', ..., '59'.  Initially selected
 633       *     minute is the minute in
 634       *     {@link $request_minutes}[{@link $attribute_name}], or if that
 635       *     is not defined, the current minute.</li>
 636       *   <li><samp>select_minute(null,array('include_blank' => true));</samp>
 637       *    <br />Generates menu ' ', '00', '01',..., '59'.  Initially
 638       *    selected minute same as above.</li>
 639       *  </ul>
 640       *
 641       *  @param string  Initially selected minute as two-digit number.
 642       *  If a value for this field is specified in
 643       *  {@link $request_minutes}[{@link $attribute_name}], then that minute
 644       *  is initially selected regardless of the value of this argument.
 645       *  Otherwise, if the first argument is present and is a character
 646       *  string of two decimal digits with a value in the range
 647       *  '00'..'59' then that minute is initially selected.  If this
 648       *  argument is absent or invalid, the current minute is
 649       *  initially selected.
 650       *  @param mixed[] Output format options:
 651       *  <ul>
 652       *    <li><samp>'include_blank' => true</samp> Show a blank
 653       *      as the first option.</li>
 654       *    <li><samp>'field_name' => '</samp><i>somestring</i><samp>'</samp>
 655       *      Generate output<br />
 656       *      <samp><select name="</samp><i>somestring</i><samp>">...</select></samp> .
 657       *      <br />If absent, generate output<br />
 658       *      <samp><select name="minute">...</select></samp>.</li>
 659       *    <li><samp>'discard_type' => ???</samp> FIXME</li>
 660       *    <li><samp>'prefix' => ???</samp> FIXME</li>
 661       *  </ul>
 662       *
 663       *  @return string  Generated HTML
 664       *  @uses attribute_name
 665       *  @uses leading_zero_on_single_digits()
 666       *  @uses request_minutes
 667       *  @uses select_html()
 668       */
 669      function select_minute($datetime=null, $options = array()) {
 670          $minute_options = "";
 671          
 672          if($this->request_minutes[$this->attribute_name]) {
 673              $datetime_min = $this->request_minutes[$this->attribute_name];    
 674          } elseif(strlen($datetime) == 2 && is_numeric($datetime)) {
 675              $datetime_min = $datetime;
 676          } else {                  
 677              #$datetime = $datetime ? $datetime : date("Y-m-d H:i:s"); 
 678              $datetime = $options['value'] ? $options['value'] :
 679                  ($datetime ? $datetime : date("Y-m-d H:i:s"));            
 680              $datetime_min = date("i",strtotime($datetime));
 681          }
 682          
 683          for($minute = 0; $minute <= 59; $minute++) {        
 684              $minute_options .= ($datetime && ($datetime_min == $minute)) ?
 685              "<option value=\"".$this->leading_zero_on_single_digits($minute)."\"  selected=\"selected\">".$this->leading_zero_on_single_digits($minute)."</option>\n" :
 686              "<option value=\"".$this->leading_zero_on_single_digits($minute)."\">".$this->leading_zero_on_single_digits($minute)."</option>\n";
 687          }
 688          $field_name = array_key_exists('field_name', $options)
 689              ? $options['field_name'] : 'minute';
 690          return $this->select_html($field_name, $minute_options,
 691                                    array_key_exists('prefix', $options)
 692                                    ? $options['prefix'] : null,
 693                                    array_key_exists('include_blank', $options)
 694                                    ? $options['include_blank'] : false,
 695                                    array_key_exists('discard_type', $options)
 696                                    ? $options['discard_type'] : false);
 697      }
 698  
 699      /**
 700       *  Generate HTML/XML for hour selector pull-down menu
 701       *
 702       *  Returns <samp><select>...</select></samp> HTML with an option
 703       *  for each of the twenty-four hours.  The first argument, if
 704       *  present, specifies the initially selected hour.  The second
 705       *  argument controls the format of the generated HTML.
 706       *
 707       *  Examples:
 708       *  <ul>
 709       *   <li><samp>select_hour();</samp><br />
 710       *     Generates menu '00', '01', ..., '23'.  Initially selected
 711       *     hour is the hour in
 712       *     {@link $request_hours}[{@link $attribute_name}], or if that
 713       *     is not defined, the current hour.</li>
 714       *   <li><samp>select_hour(null,array('include_blank' => true));</samp>
 715       *    <br />Generates menu ' ', '00', '01',..., '23'.  Initially
 716       *    selected hour same as above.</li>
 717       *  </ul>
 718       *
 719       *  @param string  Initially selected hour as two-digit number.
 720       *  If a value for this field is specified in
 721       *  {@link $request_hours}[{@link $attribute_name}], then that hour
 722       *  is initially selected regardless of the value of this argument.
 723       *  Otherwise, if the first argument is present and is a character
 724       *  string of two decimal digits with a value in the range
 725       *  '00'..'23' then that hour is initially selected.  If this
 726       *  argument is absent or invalid, the current hour is
 727       *  initially selected.
 728       *  @param mixed[] Output format options:
 729       *  <ul>
 730       *    <li><samp>'include_blank' => true</samp> Show a blank
 731       *      as the first option.</li>
 732       *    <li><samp>'field_name' => '</samp><i>somestring</i><samp>'</samp>
 733       *      Generate output<br />
 734       *      <samp><select name="</samp><i>somestring</i><samp>">...</select></samp> .
 735       *      <br />If absent, generate output<br />
 736       *      <samp><select name="hour">...</select></samp>.</li>
 737       *    <li><samp>'discard_type' => ???</samp> FIXME</li>
 738       *    <li><samp>'prefix' => ???</samp> FIXME</li>
 739       *  </ul>
 740       *
 741       *  @return string  Generated HTML
 742       *  @uses attribute_name
 743       *  @uses leading_zero_on_single_digits()
 744       *  @uses request_hours
 745       *  @uses select_html()
 746       */
 747      function select_hour($datetime=null, $options = array()) {
 748          //error_log("DateTime::select_hour() \$datetime=$datetime \$options="
 749          //          .var_export($options,true));
 750          $hour_options = "";
 751          
 752          //  If a value for this attribute was parsed from $_REQUEST,
 753          //  use it as initially selected and ignore first argument
 754          if($this->request_hours[$this->attribute_name]) {
 755              $datetime_hour = $this->request_hours[$this->attribute_name];    
 756          }
 757  
 758          //  No value in $_REQUEST so look at the first argument.
 759          //  If it is valid use it as initially selected
 760          elseif(strlen($datetime) == 2 && is_numeric($datetime)) {
 761              $datetime_hour = $datetime;
 762          }
 763  
 764          //  First argument is missing or invalid,
 765          //  initially select current hour
 766          else {                  
 767              #$datetime = $datetime ? $datetime : date("Y-m-d H:i:s"); 
 768              $datetime = $options['value'] ? $options['value'] :
 769                  ($datetime ? $datetime : date("Y-m-d H:i:s"));
 770              $datetime_hour = date("H",strtotime($datetime)); 
 771          }
 772  
 773          //  Generate <option>...</option> HTML for each hour
 774          for($hour = 0; $hour <= 23; $hour++) {
 775              $hour_options .= ($datetime && ($datetime_hour == $hour)) ?
 776              "<option value=\"".$this->leading_zero_on_single_digits($hour)."\"  selected=\"selected\">".$this->leading_zero_on_single_digits($hour)."</option>\n" :
 777              "<option value=\"".$this->leading_zero_on_single_digits($hour)."\">".$this->leading_zero_on_single_digits($hour)."</option>\n";
 778          }
 779  
 780          //  Return finished HTML
 781          $field_name = array_key_exists('field_name', $options)
 782              ? $options['field_name'] : 'hour';
 783          return $this->select_html($field_name, $hour_options,
 784                                    array_key_exists('prefix', $options)
 785                                    ? $options['prefix'] : null,
 786                                    array_key_exists('include_blank', $options)
 787                                    ? $options['include_blank'] : false,
 788                                    array_key_exists('discard_type', $options)
 789                                    ? $options['discard_type'] : false);
 790      }
 791  
 792      /**
 793       *  Generate HTML/XML for day selector pull-down menu
 794       *
 795       *  Returns <samp><select>...</select></samp> HTML with an option
 796       *  for each of the thirty-one days.  The first argument, if
 797       *  present, specifies the initially selected day.  The second
 798       *  argument controls the format of the generated HTML.
 799       *
 800       *
 801       *  Examples:
 802       *  <ul>
 803       *   <li><samp>select_day();</samp><br />
 804       *     Generates menu '01', '02', ..., '31'.  Initially selected
 805       *     day is the day in
 806       *     {@link $request_days}[{@link $attribute_name}], or if that
 807       *     is not defined, the current calendar day.</li>
 808       *   <li><samp>select_day(null,array('include_blank' => true));</samp>
 809       *    <br />Generates menu ' ', '01', '02',..., '31'.  Initially
 810       *    selected day same as above.</li>
 811       *  </ul>
 812       *
 813       *  @param string  Initially selected day as two-digit number.
 814       *  If a value for this field is specified in
 815       *  {@link $request_days}[{@link $attribute_name}], then that day
 816       *  is initially selected regardless of the value of this argument.
 817       *  Otherwise, if the first argument is present and is a character
 818       *  string of two decimal digits with a value in the range
 819       *  '01'..'31' then that day is initially selected.  Otherwise, if
 820       *  the first argument is a date in some US English date format,
 821       *  the day of the month from that date is initially selected.  If
 822       *  this argument is absent or invalid, the current calendar day
 823       *  is initially selected.
 824       *  @param mixed[] Output format options:
 825       *  <ul>
 826       *    <li><samp>'include_blank' => true</samp> Show a blank
 827       *      as the first option.</li>
 828       *    <li><samp>'field_name' => '</samp><i>somestring</i><samp>'</samp>
 829       *      Generate output<br />
 830       *      <samp><select name="</samp><i>somestring</i><samp>">...</select></samp> .
 831       *      <br />If absent, generate output<br />
 832       *      <samp><select name="day">...</select></samp>.</li>
 833       *    <li><samp>'discard_type' => ???</samp> FIXME</li>
 834       *    <li><samp>'prefix' => ???</samp> FIXME</li>
 835       *  </ul>
 836       *
 837       *  @return string  Generated HTML
 838       *  @uses attribute_name
 839       *  @uses leading_zero_on_single_digits()
 840       *  @uses request_days
 841       *  @uses select_html()
 842       */
 843      function select_day($datetime=null, $options = array()) {
 844          $day_options = "";
 845          
 846          //  If a value for this attribute was parsed from $_REQUEST,
 847          //  use it as initially selected and ignore first argument
 848          if($this->request_days[$this->attribute_name]) {
 849              $datetime_day = $this->request_days[$this->attribute_name];    
 850          }
 851  
 852          //  No value in $_REQUEST so look at the first argument.
 853          //  If it is valid use it as initially selected
 854          elseif(strlen($datetime) == 2 && is_numeric($datetime)) {
 855              $datetime_day = $datetime;
 856          }
 857  
 858          //  First argument is missing or invalid,
 859          //  initially select current day
 860          else {                  
 861              #$datetime = $datetime ? $datetime : date("Y-m-d H:i:s");
 862              $datetime = $options['value'] ? $options['value'] :
 863                  ($datetime ? $datetime : date("Y-m-d H:i:s"));
 864              $datetime_day = date("d",strtotime($datetime));  
 865          }
 866          
 867          //  Generate <option>...</option> HTML for each day
 868          for($day = 1; $day <= 31; $day++) {        
 869              $day_options .= ($datetime && ($datetime_day == $day)) ?
 870              "<option value=\"".$this->leading_zero_on_single_digits($day)."\"  selected=\"selected\">".$this->leading_zero_on_single_digits($day)."</option>\n" :
 871              "<option value=\"".$this->leading_zero_on_single_digits($day)."\">".$this->leading_zero_on_single_digits($day)."</option>\n";
 872          }
 873  
 874          //  Return finished HTML
 875          $field_name = array_key_exists('field_name', $options)
 876              ? $options['field_name'] : 'day';
 877          return $this->select_html($field_name, $day_options,
 878                                    array_key_exists('prefix',$options)
 879                                    ? $options['prefix'] : null,
 880                                    array_key_exists('include_blank', $options)
 881                                    ? $options['include_blank'] : false,
 882                                    array_key_exists('discard_type', $options)
 883                                    ? $options['discard_type'] : false);
 884      }
 885  
 886      /**
 887       *  Generate HTML/XML for month selector pull-down menu
 888       *
 889       *  Returns <samp><select>...</select></samp> HTML with an option
 890       *  for each of the twelve months.  The first argument, if
 891       *  present, specifies the initially selected month.  The second
 892       *  argument controls the format of the generated HTML.
 893       *
 894       *
 895       *  Examples:
 896       *  <ul>
 897       *   <li><samp>select_month();</samp> Generates menu January,
 898       *    February etc.</li>
 899       *   <li><samp>select_month(null,array('use_month_number' => true));</samp>
 900       *    Generates menu 1, 2 etc.</li>
 901       *   <li><samp>select_month(null,array('add_month_number' => true));</samp>
 902       *    Generates menu 1 - January, 2 - February etc.</li>
 903       *  </ul>
 904       *
 905       *  @param string  Initially selected month as two-digit number.
 906       *  If a value for this field is specified in
 907       *  {@link $request_months}[{@link $attribute_name}], then that month
 908       *  is initially selected regardless of the value of this argument.
 909       *  Otherwise, if the first argument is present and is a character
 910       *  string of two decimal digits with a value in the range
 911       *  '01'..'12' then that month is initially selected.  Otherwise,
 912       *  if the first argument is a date in some US English date
 913       *  format, the month from that date is initially selected. If
 914       *  this argument is absent or invalid, the current calendar month
 915       *  is initially selected.
 916       *  @param mixed[] Output format options:
 917       *  <ul>
 918       *    <li><samp>'include_blank' => true</samp> Show a blank
 919       *      as the first option.</li>
 920       *    <li><samp>'use_month_number' => true</samp> Show months in
 921       *      the menu by their month number (1, 2 ...).  Default is to
 922       *      show English month name (January, February ...).</li>
 923       *    <li><samp>'add_month_number' => true</samp> Show both month
 924       *      number and month name in the menu.</li>
 925       *    <li><samp>'field_name' => '</samp><i>somestring</i><samp>'</samp>
 926       *      Generate output<br />
 927       *      <samp><select name="</samp><i>somestring</i><samp>">...</select></samp> .
 928       *      <br />If absent, generate output<br />
 929       *      <samp><select name="month">...</select></samp>.</li>
 930       *    <li><samp>'discard_type' => ???</samp> FIXME</li>
 931       *    <li><samp>'prefix' => ???</samp> FIXME</li>
 932       *  </ul>
 933       *  In all cases the value sent to the server is the two digit
 934       *  month number in the range '01'..'12'.
 935       *
 936       *  @return string  Generated HTML
 937       *  @uses attribute_name
 938       *  @uses leading_zero_on_single_digits()
 939       *  @uses request_months
 940       *  @uses select_html
 941       */
 942      function select_month($date = null, $options = array()) {
 943          $month_options = "";    // will accumulate <option>s
 944          
 945          //  If a value for this attribute was parsed from $_REQUEST,
 946          //  use it as initially selected and ignore first argument
 947          if(array_key_exists($this->attribute_name,$this->request_months)) {
 948              $date_month = $this->request_months[$this->attribute_name];    
 949          }
 950  
 951          //  No value in $_REQUEST so look at the first argument.
 952          //  If it is valid use it as initially selected
 953          elseif(strlen($date) == 2 && is_numeric($date)
 954                 && $date >=1 && $date <= 12 ) {
 955              $date_month = $date;
 956          }
 957  
 958          //  Parse initially selected month from US English description
 959          //  in first argument if present, otherwise select current month
 960          else {
 961              $date = $options['value'] ? $options['value'] :
 962                  ($date ? $date : date("Y-m-d H:i:s"));
 963              $date_month = date("m",strtotime($date));  
 964          }
 965     
 966          //  Generate <option>...</option> HTML for each month
 967          for($month_number = 1; $month_number <= 12; $month_number++) {
 968              if(array_key_exists('use_month_numbers',$options)) {
 969                  $month_name = $month_number;
 970              } elseif(array_key_exists('add_month_numbers',$options)) {
 971                  $month_name = $month_number. ' - '
 972                      . date("F",strtotime("2005-" . $month_number
 973                                         . "-01"));
 974              } else {
 975                  $month_name = date("F",strtotime("2005-" . $month_number
 976                                                   ."-01"));
 977              }
 978  
 979              $month_options .= ($date_month == $month_number ?
 980                                 "<option value=\""
 981                            .$this->leading_zero_on_single_digits($month_number)
 982                         ."\" selected=\"selected\">$month_name</option>\n" :
 983                                 "<option value=\""
 984                            .$this->leading_zero_on_single_digits($month_number)
 985                                 ."\">$month_name</option>\n");
 986          }
 987  
 988          //  Return finished HTML
 989          $field_name = array_key_exists('field_name', $options)
 990                         ? $options['field_name'] : 'month';
 991          return $this->select_html($field_name, $month_options,
 992                                    array_key_exists('prefix', $options)
 993                                    ? $options['prefix'] : null,
 994                                    array_key_exists('include_blank', $options)
 995                                    ? $options['include_blank'] : false,
 996                                    array_key_exists('discard_type', $options)
 997                                    ? $options['discard_type'] : false);
 998      }
 999  
1000      /**
1001       *  Generate HTML/XML for year selector pull-down menu
1002       *
1003       *  Returns <samp><select>...</select></samp> HTML with options
1004       *  for a number of years.  The first argument, if present,
1005       *  specifies the initially selected year.  The second 
1006       *  argument controls the format of the generated HTML.
1007       *
1008       *  Examples:
1009       *  <ul>
1010       *   <li><samp>select_year();</samp><br /> Generates a pulldown menu with
1011       *     with a range of +/- five years.  If a year is specified in
1012       *     {@link $request_years}[{@link $attribute_name}] then it is
1013       *     selected initially, otherwise the current calendar year is
1014       *     selected.</li> 
1015       *   <li>
1016       *  <samp>select_year(null,array('start_year' => '1900));</samp><br />
1017       *    Generates year options from 1900 to five years after the
1018       *    initially selected year, which is chosen as in the previous
1019       *    example.</li> 
1020       *   <li><samp>select_year(null,array('start_year'=>date('Y')+5, 'end_year'=>date('Y')-5);</samp><br />
1021       *    Generates year options starting five years after the current year,
1022       *    ending five years before the current year.
1023       *  </ul>
1024       *
1025       *  @param string   Year to display as initially selected if none
1026       *    was found in {@link $request_years}[{@link $attribute_name}].
1027       *    Character string is either exactly four decimal
1028       *    digits or some English date representation.  If omitted, the
1029       *    current year is initially selected.
1030       *
1031       *  @param mixed[] Output format options:
1032       *  <ul>
1033       *    <li><samp>'start_year'=>'</samp><i>startyear</i><samp>'</samp>
1034       *      If specified, <i>startyear</i> will be the first year in
1035       *      the output menu, otherwise the first year in the menu will
1036       *      be five years before the initially selected year.</li>
1037       *    <li><samp>'end_year'=>'</samp><i>endyear</i><samp>'</samp>
1038       *      If specified, <i>endyear</i> will be the last year in
1039       *      the output menu, otherwise the last year in the menu will
1040       *      be five years after the initially selected year.</li>
1041       *    <li><samp>'field_name' => '</samp><i>somestring</i><samp>'</samp>
1042       *      Generate output<br />
1043       *      <samp><select name="</samp><i>somestring</i><samp>">...</select></samp> .
1044       *      <br />If absent, generate output<br />
1045       *      <samp><select name="year">...</select></samp>.</li>
1046       *    <li><samp>'discard_type' => ???</samp> FIXME</li>
1047       *    <li><samp>'prefix' => ???</samp> FIXME</li>
1048       *  </ul>
1049       *  To generate a list with most recent year first, define that
1050       *  year as the start year and the oldest year as the end year.
1051       *  @return string  Generated HTML
1052       *  @uses attribute_name
1053       *  @uses request_years
1054       *  @uses select_html
1055       *  @uses year_option()
1056       */
1057      function select_year($date=null, $options = array()) {
1058          //error_log("select_year('" . (is_null($date) ? 'null' : $date)
1059          //          ."', " . var_export($options,true));
1060          //error_log('request_years='
1061          //     .var_export($this->request_years[$this->attribute_name],true));
1062          $year_options = "";
1063  
1064          //  Find the year to display.
1065          if($this->request_years[$this->attribute_name]) {
1066  
1067              //  There was a value for this attribute in $_REQUEST
1068              //  so display it as the initial choice
1069              $date_year = $this->request_years[$this->attribute_name];    
1070          } elseif(strlen($date) == 4 && is_numeric($date)) {
1071  
1072              //  The first argument is exactly four decimal digits
1073              //  so interpret that as a year
1074              $date_year = $date;     
1075          } else {
1076  
1077              //  If a first argument was specified, assume that it is
1078              //  some English date representation and convert it for
1079              //  use as the initial value.
1080              //  If first argument was null, use the current year for
1081              //  the initial value.
1082              $date = $options['value'] ? $options['value'] :
1083                  ($date ? $date : date("Y-m-d H:i:s"));
1084              $date_year = date("Y",strtotime($date));
1085          } 
1086  
1087          //  Set first year to appear in the option list
1088          $start_year = array_key_exists('start_year',$options)
1089                         ? $options['start_year'] : $date_year - 5;
1090  
1091          //  Set last year to appear in the option list
1092          $end_year = array_key_exists('end_year',$options)
1093                       ? $options['end_year'] : $date_year + 5;
1094  
1095          if ($start_year < $end_year) {
1096              for($year = $start_year; $year <= $end_year; $year++) {
1097                  $year_options .= $this->year_option($year, $date_year);
1098              }
1099          } else {
1100              for($year = $start_year; $year >= $end_year; $year--) {
1101                  $year_options .= $this->year_option($year, $date_year);
1102              }
1103          }
1104  
1105          $field_name = array_key_exists('field_name',$options)
1106                        ? $options['field_name'] : 'year';
1107          return $this->select_html($field_name, $year_options,
1108                                    array_key_exists('prefix',$options)
1109                                    ? $options['prefix'] : null,
1110                                    array_key_exists('include_blank',$options)
1111                                    ? $options['include_blank'] : false,
1112                                    array_key_exists('discard_type',$options)
1113                                    ? $options['discard_type'] : false);
1114  
1115      }
1116  
1117      /**
1118       *  Return one HTML/XML year option, selected if so specified
1119       *  @param integer Year to put in the option
1120       *  @param integer Year that should be selected
1121       *  @return string HTML for one year option
1122       */
1123      function year_option($year, $date_year) {
1124          return "<option value=\"$year\""
1125              . (($date_year == $year) ? "  selected=\"selected\">" : ">")
1126              . "$year</option>\n";
1127      }
1128  
1129      /**
1130       *  Generate HTML/XML for day/month/year selector pull-down menus
1131       *
1132       *  When called, {@link $object_name} describes the
1133       *  {@link ActiveRecord} subclass and {@link $attribute_name}
1134       *  describes the attribute whose value will be set by the
1135       *  generated pull-down menus.  The value to be displayed
1136       *  initially in each menu is from $_REQUEST if present, otherwise
1137       *  from the database.
1138       *
1139       *  @param mixed[] Output format options
1140       *  <ul>
1141       *    <li><samp>'discard_day' => true</samp> Don't show a day of
1142       *      month menu. If absent or false, day menu will be output.</li>
1143       *    <li><samp>'discard_month' => true</samp> Don't show a month
1144       *      or day of the month menu.  If absent or false, month menu
1145       *      will be output.</li>
1146       *    <li><samp>'discard_type' => true</samp> (true is the 
1147       *      default) Don't show name of individual field, for example
1148       *      <samp>[year]</samp>, as part of the <samp>name</samp> value
1149       *      of the generated <samp><select ...></samp>.  The
1150       *      information to identify the field is available as a suffix 
1151       *      <samp>(</samp><i>n</i><samp>i)</samp> of the attribute
1152       *      name.</li> 
1153       *    <li><samp>'discard_year' => true</samp> Don't show a year
1154       *      menu.  If absent or false, year menu will be output.</li>
1155       *    <li><samp>'field_separator' => '</samp><i>string</i><samp>'</samp>
1156       *      String to insert between the submenus in the output.  If
1157       *      absent, one blank will be inserted.</li> 
1158       *    <li><samp>'include_blank' => true</samp> Initially show a blank
1159       *      selection in the menu.  If absent or false, the current  
1160       *      date will be shown as the initial selection.  If a value
1161       *      was parsed from $_REQUEST, it will be used for the initial
1162       *      selection regardless of this option.</li>
1163       *    <li><samp>'month_before_year' => true</samp>  Equivalent to
1164       *      <samp>'order' => array('month', 'day', 'year')</samp></li>
1165       *    <li><samp>'order' => array(</samp><i>elements</i><samp>)</samp>
1166       *      A list of the elements <samp>'month', 'day'</samp> and
1167       *      <samp>'year'</samp> in the order in which the menus should
1168       *      appear in the output. Default is
1169       *      <samp>'year', 'month', 'day'</samp></li>
1170       *    <li><b>Also:</b> options provided by {@link select_month()},
1171       *      {@link select_day()} and {@link select_year()}
1172       *  </ul>
1173       *  @return string Generated HTML
1174       *  @uses select_day()
1175       *  @uses select_month()
1176       *  @uses select_year()
1177       *  @uses value()
1178       */
1179      function to_date_select_tag($options = array()) {
1180  //        error_log("to_date_select_tag() object='$this->object_name'"
1181  //                  . " attribute='$this->attribute_name'");
1182  //        error_log("options=".var_export($options,true));
1183  
1184          //  Handle historically misspelled options
1185          if (array_key_exists('field_seperator', $options)) {
1186              $options['field_separator'] = $options['field_seperator'];
1187              unset($options['field_seperator']);
1188          }
1189          $defaults = array('discard_type' => true);
1190          $options  = array_merge($defaults, $options);
1191          $options_with_prefix = array();
1192  
1193          //  Set the name of each submenu in the form
1194          for($i=1 ; $i <= 3 ; $i++) {
1195              $options_with_prefix[$i] = array_merge($options, array('prefix' =>
1196                    "{$this->object_name}[{$this->attribute_name}({$i}i)]"));
1197          }        
1198          
1199          //  Test for output option 'include_blank' == true
1200          if(array_key_exists('include_blank', $options)
1201             && $options['include_blank']) {
1202  
1203              //  'include_blank' is present so if no value for this
1204              //  attribute was parsed from $_REQUEST, show blank initially
1205              //  FIXME: this doesn't actually work
1206              $value = $this->value();
1207              $date = $value ? $value : null;
1208          } else {
1209  
1210              //  'include_blank' is not present so if no value for this
1211              //  attribute was parsed from $_REQUEST, show today's date
1212              //  initially
1213              $value = $this->value();
1214              $date = $value ? $value : date("Y-m-d");
1215          }
1216  
1217          //  Test for output option 'month_before_year' == true
1218          $date_select = array();
1219          if(array_key_exists('month_before_year', $options)
1220             && $options['month_before_year']) {
1221  
1222              //  'month_before_year' is present so set the default
1223              //  ordering of output menus accordingly
1224              $options['order'] = array('month', 'year', 'day');
1225          } elseif(!array_key_exists('order',$options)
1226                   ||!$options['order']) {
1227  
1228              //  If 'order' option not present set order from default
1229              $options['order'] = array('year', 'month', 'day');
1230          }
1231  
1232          $position = array('year' => 1, 'month' => 2, 'day' => 3);
1233  
1234          //  Evaluate 'discard_field' options to see which fields
1235          //  should not be represented by menus in the output
1236          $discard = array();
1237          if(array_key_exists('discard_year',$options)
1238             && $options['discard_year']) $discard['year']  = true;
1239          if(array_key_exists('discard_month',$options)
1240             && $options['discard_month']) $discard['month'] = true;
1241          if( (array_key_exists('discard_day',$options)
1242               &&$options['discard_day'])
1243              || (array_key_exists('discard_month',$options)
1244                  && $options['discard_month'])) $discard['day'] = true;
1245  
1246          //  Build HTML for menus in the order determined above,
1247          //  except for fields to be discarded.
1248          foreach($options['order'] as $param) {
1249              if(!array_key_exists($param,$discard) || !$discard[$param]) {
1250                  $date_select[] = call_user_func(array($this, "select_$param"),
1251                                $date, $options_with_prefix[$position[$param]]);
1252              }
1253          }
1254          
1255          //  HTML for each menu is in an element of $date_select[].
1256          //  Join the pieces of HTML with an optional field separator
1257          //  (default blank)
1258          if(count($date_select)) {
1259              $separator = array_key_exists('field_separator',$options)
1260                  ? $options['field_separator'] : " ";
1261              $date_select = implode($separator, $date_select);            
1262          }
1263  
1264          return $date_select;
1265      }
1266  
1267      /**
1268       *  Generate HTML/XML for date/time pulldown menus
1269       *
1270       *  Returns <samp><select>...</select></samp> HTML with options
1271       *  for a number of years, months, days, hours and minutes.  The
1272       *  first argument, if present, specifies the initially selected
1273       *  date.  The second argument controls the format of the
1274       *  generated HTML.
1275       *
1276       *  Examples:
1277       *  <ul>
1278       *   <li><samp>to_datetime_select_tag();</samp><br /> Generates a
1279       *     group of five pulldown menus in the order year, month, day,
1280       *     hour and minute with the current date and time initially
1281       *     selected.</li> 
1282       *   <li>
1283       *   <li><samp>to_datetime_select_tag(array('discard_second' => false);</samp><br />
1284       *     Generates a group of six pulldown menus in the order year,
1285       *     month, day, hour, minute and second with the current date
1286       *     and time initially selected.</li> 
1287       *   <li>
1288       *  <samp>to_datetime_select_tag('1998-04-08 13:21:17');</samp><br />
1289       *    Generates a group of five pulldown menus in the order year,
1290       *    month, day, hour and minute with the date/time
1291       *    1998 August 4 13:21 initially selected.</li> 
1292       *  </ul>
1293       *
1294       *  @param string   Date/time to display as initially selected.
1295       *    Character string is any US English date representation
1296       *    supported by {@link strtotime()}.  If omitted, the
1297       *    current date/time is initially selected.
1298       *
1299       *  @param mixed[] Output format options:
1300       *  <ul>
1301       *    <li><samp>'discard_month' => true</samp><br />
1302       *      Output selector for only the year.</li>
1303       *    <li><samp>'discard_day' => true</samp><br />
1304       *      Output selector for only the year and month.</li>
1305       *    <li><samp>'discard_hour' => true</samp><br />
1306       *      Output selector for only the year, month and day.</li>
1307       *    <li><samp>'discard_minute' => true</samp><br />
1308       *      Output selector for only the year, month, day and
1309       *      hour.</li> 
1310       *    <li><samp>'discard_second' => false</samp><br />
1311       *      Output selector for year, month, day, hour, minute and
1312       *      second.</li> 
1313       *  </ul>
1314       *  @return string Generated HTML
1315       *  @uses request_days
1316       *  @uses request_hours
1317       *  @uses request_minutes
1318       *  @uses request_months
1319       *  @uses request_seconds
1320       *  @uses request_years
1321       *  @uses select_day()
1322       *  @uses select_hour()
1323       *  @uses select_minute()
1324       *  @uses select_month()
1325       *  @uses select_second()
1326       *  @uses select_year()
1327       *  @uses value()
1328       */
1329      function to_datetime_select_tag($options = array()) {
1330          $defaults = array('discard_type'   => true,
1331                            'discard_second' => true);
1332          $options = array_merge($defaults, $options);
1333          $options_with_prefix = array();
1334          for($i=1 ; $i <= 6 ; $i++) {
1335              $options_with_prefix[$i] =
1336                  array_merge($options, array('prefix' =>
1337                     "{$this->object_name}[{$this->attribute_name}({$i}i)]"));
1338          }
1339  
1340          //  FIXME: this doesn't work
1341          if(array_key_exists('include_blank', $options)
1342             && $options['include_blank']) {
1343              $value = $this->value();
1344              $datetime = $value ? $value : null;
1345          } else {
1346              $value = $this->value();
1347              $datetime = $value ? $value : date("Y-m-d H:i:s");
1348          }
1349      
1350          //  Generate year pulldown
1351          $datetime_select = $this->select_year($datetime,
1352                                                $options_with_prefix[1]);
1353  
1354          //  Generate month pulldown if not discarded
1355          if(!array_key_exists('discard_month', $options)
1356             || !$options['discard_month']) {
1357              $datetime_select .= $this->select_month($datetime,
1358                                                      $options_with_prefix[2]);
1359  
1360              //  Generate day pulldown if not discarded
1361              if(!array_key_exists('discard_day', $options)
1362                 || !($options['discard_day'] || $options['discard_month'])) {
1363                  $datetime_select .= $this->select_day($datetime,
1364                                                        $options_with_prefix[3]);
1365  
1366                  //  Generate hour pulldown if not discarded
1367                  if(!array_key_exists('discard_hour', $options)
1368                     || !$options['discard_hour']) {
1369                      $datetime_select .= ' &mdash; '
1370                          . $this->select_hour($datetime,
1371                                           $options_with_prefix[4]);
1372  
1373                      //  Generate minute pulldown if not discarded
1374                      if(!array_key_exists('discard_minute', $options)
1375                         || !$options['discard_minute']) {
1376                          $datetime_select .= ' : '
1377                              . $this->select_minute($datetime,
1378                                                     $options_with_prefix[5]);
1379  
1380                          //  Generate second pulldown if not discarded
1381                          if(!array_key_exists('discard_second', $options)
1382                             || !$options['discard_second']) {
1383                              $datetime_select .= ' : '
1384                                  . $this->select_second($datetime,
1385                                                      $options_with_prefix[6]);
1386                          }  // second
1387                      }      // minute
1388                  }          // hour
1389              }              // day
1390          }                  // month
1391          return $datetime_select;
1392      }
1393      
1394      /**
1395       *  Generate HTML/XML for expiration month and year pulldown.
1396       *
1397       *  Calls {@link to_date_select_tag()} with options for month with
1398       *  number, followed by year starting this year and going seven
1399       *  years in the future.
1400       *  @param mixed[] Output format options
1401       *  @return string Generated HTML
1402       *  @uses to_date_select_tag()
1403       */
1404      function to_expiration_date_select_tag($options = array()) {
1405          $options['discard_day'] = true; 
1406          $options['month_before_year'] = true;      
1407          $options['use_month_numbers'] = true;   
1408          $options['start_year'] = date("Y");
1409          $options['end_year'] = date("Y") + 7;
1410          $options['field_separator'] = " / ";
1411          return $this->to_date_select_tag($options);               
1412      }  
1413  
1414      /**
1415       *  Generate HTML/XML for time pulldown
1416       *
1417       *  When called, {@link $object_name} describes the
1418       *  {@link ActiveRecord} subclass and {@link $attribute_name}
1419       *  describes the attribute whose value will be set by the
1420       *  generated pull-down menu.  The value to be displayed initially
1421       *  is from $_REQUEST if present, otherwise from the database.
1422       *
1423       *  @param mixed[] Output format options
1424       *  @return string Generated HTML
1425       *  @uses request_hours
1426       *  @uses request_minutes
1427       *  @uses request_seconds
1428       *  @uses select_time()
1429       *  @uses value()
1430       */
1431      function time_select($options=array()) {
1432          $defaults = array('discard_type' => true,
1433                            'discard_second' => true);
1434          $options = array_merge($defaults,$options);
1435          $options_with_prefix = array();
1436          for($i=4 ; $i <= 6 ; $i++) {
1437              $options_with_prefix[$i] =
1438                  array_merge($options, array('prefix' =>
1439                   "{$this->object_name}[{$this->attribute_name}({$i}i)]"));
1440          }
1441  
1442          //  If no value for this attribute found in $_REQUEST
1443          //  or the model, show current time initially 
1444          $time = $this->value();
1445          $time = $time ? $time : date('H:i:s');
1446  
1447          //  Generate HTML for hour
1448          $time_select = $this->select_hour($time, $options_with_prefix[4]);
1449  
1450          //  Generate HTML for minute if not discarded
1451          if (!(array_key_exists('discard_minute', $options)
1452                && $options['discard_minute'])) {
1453              $time_select .= ' : '
1454                  . $this->select_minute($time, $options_with_prefix[5]);
1455  
1456              //  Generate HTML for second if not discarded
1457              if (!(array_key_exists('discard_second', $options)
1458                    && $options['discard_second'])) {
1459                  $time_select .= ' : '
1460                      . $this->select_second($time, $options_with_prefix[6]);
1461              }
1462          }
1463          return $time_select;
1464      }
1465  
1466      /**
1467       *  Generate HTML/XML for year pulldown
1468       *
1469       *  When called, {@link $object_name} describes the
1470       *  {@link ActiveRecord} subclass and {@link $attribute_name}
1471       *  describes the attribute whose value will be set by the
1472       *  generated pull-down menu.  The value to be displayed initially
1473       *  is from $_REQUEST if present, otherwise from the database.
1474       *
1475       *  @param mixed[] Output format options
1476       *  @return string Generated HTML
1477       *  @uses select_year()
1478       *  @uses value()
1479       */
1480      function year_select($options=array()) {
1481          $defaults = array('discard_type' => true,
1482               'prefix' =>
1483                     "{$this->object_name}[{$this->attribute_name}(1i)]");
1484          $options = array_merge($defaults,$options);
1485  
1486          //  If no value for this attribute found in $_REQUEST
1487          //  or the model, show today's date initially 
1488          $year = $this->value();
1489          if (!$year) {
1490              $year =
1491              (is_array($this->request_years)
1492               && array_key_exists($this->attribute_name,$this->request_years))
1493              ? $this->request_years[$this->attribute_name]
1494              : date("Y");
1495          }
1496          return $this->select_year($year.'-01-01',$options);
1497      }
1498  }
1499  
1500  /**
1501   *  Make a new DateHelper object and call its select_date() method
1502   *  @uses DateHelper::select_date()
1503    */
1504  function select_date() {
1505      $date_helper = new DateHelper();
1506      $args = func_get_args();
1507      return call_user_func_array(array($date_helper, 'select_date'), $args);
1508  }
1509  
1510  /**
1511   *  Make a new DateHelper object and call its select_datetime() method
1512   *  @uses DateHelper::select_datetime()
1513   */
1514  function select_datetime() {
1515      $date_helper = new DateHelper();
1516      $args = func_get_args();
1517      return call_user_func_array(array($date_helper, 'select_datetime'), $args);
1518  }
1519  
1520  /**
1521   *  Make a new DateHelper object and call its select_expiration_date() method
1522   *  @uses DateHelper::select_expiration_date()
1523   */
1524  function select_expiration_date() {
1525      $date_helper = new DateHelper();
1526      $args = func_get_args();
1527      return call_user_func_array(array($date_helper, 'select_expiration_date'), $args);        
1528  }
1529  
1530  /**
1531   *  Make a new DateHelper object and call its datetime_select() method
1532   *  @param string Name of an ActiveRecord subclass
1533   *  @param string Name of an attribute of $object
1534   *  @param mixed[] Format options
1535   *  @uses DateHelper::datetime_select()
1536   *  @see ActiveRecordHelper::to_scaffold_tag()
1537   */
1538  function datetime_select($object, $attribute, $options = array()) {
1539      $date_helper = new DateHelper($object, $attribute);
1540      return $date_helper->datetime_select($options);    
1541  }
1542  
1543  /**
1544   *  Make a new DateHelper object and call its date_select() method
1545   *  @param string Name of an ActiveRecord subclass
1546   *  @param string Name of an attribute of $object
1547   *  @param mixed[]  Output format options
1548   *  @return string Generated HTML
1549   *  @uses DateHelper::date_select()
1550   *  @see ActiveRecordHelper::to_scaffold_tag()
1551   */
1552  function date_select($object, $attribute, $options = array()) {
1553      $date_helper = new DateHelper($object, $attribute);
1554      return $date_helper->date_select($options);    
1555  }
1556  
1557  /**
1558   *  Make a new DateHelper object and call its year_select() method
1559   *  @param string Name of an ActiveRecord subclass
1560   *  @param string Name of an attribute of $object
1561   *  @param mixed[] Format options
1562   *  @uses DateHelper::year_select()
1563   *  @see ActiveRecordHelper::to_scaffold_tag()
1564   */
1565  function year_select($object, $attribute, $options = array()) {
1566      $date_helper = new DateHelper($object, $attribute);
1567      return $date_helper->year_select($options);    
1568  }
1569  
1570  /**
1571   *  Make a new DateHelper object and call its select_time() method
1572   *  @param string Name of an ActiveRecord subclass
1573   *  @param string Name of an attribute of $object
1574   *  @param mixed[] Format options
1575   *  @uses DateHelper::select_time()
1576   *  @see ActiveRecordHelper::to_scaffold_tag()
1577   */
1578  function time_select($object, $attribute, $options = array()) {
1579      $date_helper = new DateHelper($object, $attribute);
1580      return $date_helper->time_select($options);    
1581  }
1582  
1583  /**
1584   *  Make a new DateHelper object and call its expiration_date_select() method
1585   *  @param string Name of an ActiveRecord subclass
1586   *  @param string Name of an attribute of $object
1587   *  @param mixed[] Format options
1588   *  @uses DateHelper::expiration_date_select()
1589   */
1590  function expiration_date_select($object, $attribute, $options = array()) {
1591      $date_helper = new DateHelper($object, $attribute);
1592      return $date_helper->expiration_date_select($options);        
1593  }
1594  
1595  /**
1596   *  Make a new DateHelper object and call its select_month() method
1597   *
1598   *  Generate HTML/XML for month selector pull-down menu using only
1599   *  explicit month specification.<br />
1600   *  <b>NB:</b>  An attempt to get value of an attribute will always
1601   *  fail because there is no way to set
1602   *  {@link DateHelper::object_name} and
1603   *  {@link DateHelper::attribute_name}.
1604   *  @uses DateHelper::select_month()
1605   */
1606  function select_month() {
1607      $date_helper = new DateHelper();
1608      $args = func_get_args();
1609      return call_user_func_array(array($date_helper, 'select_month'), $args);    
1610  }
1611  
1612  /**
1613   *  Make a new DateHelper object and call its select_day() method
1614   *  @uses DateHelper::select_day()
1615   */
1616  function select_day() {
1617      $date_helper = new DateHelper();
1618      $args = func_get_args();
1619      return call_user_func_array(array($date_helper, 'select_day'), $args);    
1620  }
1621  
1622  // -- set Emacs parameters --
1623  // Local variables:
1624  // tab-width: 4
1625  // c-basic-offset: 4
1626  // c-hanging-comment-ender-p: nil
1627  // indent-tabs-mode: nil
1628  // End:
1629  ?>


Généré le : Sun Feb 25 20:04:38 2007 par Balluche grâce à PHPXref 0.7