[ Index ]

PHP Cross Reference of Akelos Framework

title

Body

[close]

/AkActionView/helpers/ -> date_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  if(!defined('AK_DATE_HELPER_DEFAULT_PREFIX')){
  21      define('AK_DATE_HELPER_DEFAULT_PREFIX', 'date');
  22  }
  23  
  24  /**
  25  * The Date Helper primarily creates select/option tags for different kinds of dates and date elements. All of the select-type methods
  26  * share a number of common options that are as follows:
  27  *
  28  * * <tt>:prefix</tt> - overwrites the default prefix of "date" used for the select names. So specifying "birthday" would give
  29  *   birthday[month] instead of date[month] if passed to the select_month method.
  30  * * <tt>:include_blank</tt> - set to true if it should be possible to set an empty date.
  31  * * <tt>:discard_type</tt> - set to true if you want to discard the type part of the select name. If set to true, the select_month
  32  *   method would use simply "date" (which can be overwritten using <tt>:prefix</tt>) instead of "date[month]".
  33  */
  34  class DateHelper extends AkActionViewHelper
  35  {
  36  
  37      /**
  38      * Reports the approximate distance in time between two times given in seconds
  39      * or in a valid ISO string like.
  40      * For example, if the distance is 47 minutes, it'll return
  41      * "about 1 hour". See the source for the complete wording list.
  42      *
  43      * Integers are interpreted as seconds. So,
  44      * <tt>$date_helper->distance_of_time_in_words(50)</tt> returns "less than a minute".
  45      *
  46      * Set <tt>include_seconds</tt> to true if you want more detailed approximations if distance < 1 minute
  47      */
  48      function distance_of_time_in_words($from_time, $to_time = 0, $include_seconds = false)
  49      {
  50          $from_time = is_numeric($from_time) ? $from_time : Ak::getTimestamp($from_time);
  51          $to_time = is_numeric($to_time) ? $to_time : Ak::getTimestamp($to_time);
  52          $distance_in_minutes = round((abs($to_time - $from_time))/60);
  53          $distance_in_seconds = round(abs($to_time - $from_time));
  54  
  55          if($distance_in_minutes <= 1){
  56              if($include_seconds){
  57                  if($distance_in_seconds < 5){
  58                      return Ak::t('less than %seconds seconds',array('%seconds'=>5),'localize/date');
  59                  }elseif($distance_in_seconds < 10){
  60                      return Ak::t('less than %seconds seconds',array('%seconds'=>10),'localize/date');
  61                  }elseif($distance_in_seconds < 20){
  62                      return Ak::t('less than %seconds seconds',array('%seconds'=>20),'localize/date');
  63                  }elseif($distance_in_seconds < 40){
  64                      return Ak::t('half a minute',array(),'localize/date');
  65                  }elseif($distance_in_seconds < 60){
  66                      return Ak::t('less than a minute',array(),'localize/date');
  67                  }else {
  68                      return Ak::t('1 minute',array(),'localize/date');
  69                  }
  70              }
  71              return ($distance_in_minutes===0) ? Ak::t('less than a minute', array(),'localize/date') : Ak::t('1 minute', array(),'localize/date');
  72          }elseif ($distance_in_minutes <= 45){
  73              return Ak::t('%minutes minutes',array('%minutes'=>$distance_in_minutes),'localize/date');
  74          }elseif ($distance_in_minutes <= 90){
  75              return Ak::t('about 1 hour',array(),'localize/date');
  76          }elseif ($distance_in_minutes <= 1440){
  77              return Ak::t('about %hours hours',array('%hours'=>round($distance_in_minutes/60)),'localize/date');
  78          }elseif ($distance_in_minutes <= 2880){
  79              return Ak::t('1 day',array(),'localize/date');
  80          }else{
  81              return Ak::t('%days days',array('%days'=>round($distance_in_minutes/1440)),'localize/date');
  82          }
  83      }
  84  
  85      /**
  86        * Like distance_of_time_in_words, but where <tt>to_time</tt> is fixed to <tt>timestamp()</tt>.
  87        */
  88      function time_ago_in_words($from_time, $include_seconds = false)
  89      {
  90          return DateHelper::distance_of_time_in_words($from_time, Ak::time(), $include_seconds);
  91      }
  92      function distance_of_time_in_words_to_now($from_time, $include_seconds = false)
  93      {
  94          return DateHelper::time_ago_in_words($from_time, $include_seconds);
  95      }
  96  
  97      /**
  98        * Returns a set of select tags (one for year, month, and day) pre-selected for accessing a specified date-based attribute (identified by
  99        * +column_name+) on an object assigned to the template (identified by +object+). It's possible to tailor the selects through the +options+ array,
 100        * which accepts all the keys that each of the individual select builders do (like 'use_month_numbers' for select_month) as well as a range of
 101        * discard options. The discard options are <tt>'discard_year'</tt>, <tt>'discard_month'</tt> and <tt>'discard_day'</tt>. Set to true, they'll
 102        * drop the respective select. Discarding the month select will also automatically discard the day select. It's also possible to explicitly
 103        * set the order of the tags using the <tt>'order'</tt> option with an array(<tt>'year'</tt>, <tt>'month'</tt> and <tt>'day')</tt> in
 104        * the desired order.
 105        *
 106        * Passing 'disabled' => true as part of the +options+ will make elements inaccessible for change.
 107        *
 108        * NOTE: Discarded selects will default to 1. So if no month select is available, January will be assumed.
 109        *
 110        * Examples:
 111        *
 112        *   $date_helper->date_select("post", "written_on");
 113        *   $date_helper->date_select("post", "written_on", array('start_year' => 1995));
 114        *   $date_helper->date_select("post", "written_on", array('start_year' => 1995, 'use_month_numbers' => true,
 115        *                                     'discard_day' => true, 'include_blank' => true)));
 116        *   $date_helper->date_select("post", "written_on", array('order' => array('day', 'month', 'year')));
 117        *   $date_helper->date_select("user", "birthday",   array('order' => array('month', 'day')));
 118        *
 119        * The selects are prepared for multi-parameter assignment to an Active Record object.
 120        */
 121      function date_select($object_name, $column_name, $options = array())
 122      {
 123          $defaults = array('discard_type' => true);
 124          $options  = array_merge($defaults, $options);
 125  
 126          if(!empty($this->_controller->$object_name) && $column_name[0] != '_' && method_exists($this->_controller->$object_name,$column_name)){
 127              $date = $this->_controller->$object_name->$column_name();
 128          }elseif(!empty($this->_controller->$object_name)) {
 129              $date = $this->_controller->$object_name->get($column_name);
 130          }elseif(!empty($this->_object[$object_name])){
 131              $date = $this->_object[$object_name]->get($column_name);
 132          }
 133  
 134          $date = !empty($options['include_blank']) ? (!empty($date) ? $date : 0) : (!empty($date) ? $date : Ak::getDate());
 135  
 136          $options['order'] = empty($options['order']) ? explode(',',Ak::t('year,month,day',array(),'localize/date')) : $options['order'];
 137  
 138          $discard = array(
 139          'year'=>!empty($options['discard_year']),
 140          'month'=>!empty($options['discard_month']),
 141          'day'=>!empty($options['discard_day']) || !empty($options['discard_month'])
 142          );
 143  
 144          $date_select = '';
 145          $codes = array('year'=>'1i','month'=>'2i','day'=>'3i');
 146          foreach ($options['order'] as $param){
 147              if(empty($discard[$param])){
 148                  $helper_method = 'select_'.$param;
 149                  $date_select .= DateHelper::$helper_method($date, array_merge($options,array('prefix' => $object_name.'['.$column_name.'('.$codes[$param].')]')))."\n";
 150              }
 151          }
 152          return $date_select;
 153      }
 154  
 155      /**
 156        * Returns a set of select tags (one for year, month, day, hour, and minute) pre-selected for accessing a specified datetime-based
 157        * attribute (identified by +column_name+) on an object assigned to the template (identified by +object+). Examples:
 158        *
 159        *   datetime_select("post", "written_on");
 160        *   datetime_select("post", "written_on", array('start_year' => 1995));
 161        *
 162        * The selects are prepared for multi-parameter assignment to an Active Record object.
 163        */
 164      function datetime_select($object_name, $column_name, $options = array())
 165      {
 166          $defaults = array('discard_type' => true, 'order'=>explode(',',Ak::t('year,month,day,hour,minute',array(),'localize/date')));
 167          $options  = array_merge($defaults, $options);
 168  
 169          if(!empty($this->_controller->$object_name) && $column_name[0] != '_' && method_exists($this->_controller->$object_name,$column_name)){
 170              $date = $this->_controller->$object_name->$column_name();
 171          }elseif(!empty($this->_controller->$object_name)) {
 172              $date = $this->_controller->$object_name->get($column_name);
 173          }elseif(!empty($this->_object[$object_name])) {
 174              $date = $this->_object[$object_name]->get($column_name);
 175          }
 176  
 177          $date = !empty($options['include_blank']) ? (!empty($date) ? $date : 0) : (!empty($date) ? $date : Ak::getDate());
 178  
 179          $discard = array(
 180          'year'=>!empty($options['discard_year']),
 181          'month'=>!empty($options['discard_month']),
 182          'day'=>!empty($options['discard_day']) || !empty($options['discard_month']),
 183          'hour'=>!empty($options['discard_hour']),
 184          'minute'=>!empty($options['discard_hour']) || !empty($options['discard_minute'])
 185          );
 186  
 187          $datetime_select = '';
 188          $codes = array('year'=>'1i','month'=>'2i','day'=>'3i','hour'=>'4i','minute'=>'5i');
 189          foreach ($options['order'] as $param){
 190              if(empty($discard[$param])){
 191                  $helper_method = 'select_'.$param;
 192                  $datetime_select .= ($param == 'hour' ? ' &mdash; ' : ($param == 'minute' ? ' : ' : '')).
 193                  DateHelper::$helper_method($date, array_merge($options,array('prefix' => $object_name.'['.$column_name.'('.$codes[$param].')]')))."\n";
 194              }
 195          }
 196          return $datetime_select;
 197      }
 198  
 199      /**
 200        * Returns a set of html select-tags (one for year, month, and day) pre-selected with the +date+.
 201        */
 202      function select_date($date = null, $options = array())
 203      {
 204          $date = empty($date) ? Ak::getDate() : $date;
 205          return DateHelper::select_year($date, $options) . DateHelper::select_month($date, $options) . DateHelper::select_day($date, $options);
 206      }
 207  
 208      /**
 209        * Returns a set of html select-tags (one for year, month, day, hour, and minute) pre-selected with the +datetime+.
 210        */
 211      function select_datetime($datetime = null, $options = array())
 212      {
 213          $datetime = empty($datetime) ? Ak::getDate() : $datetime;
 214          return DateHelper::select_date($datetime, $options) . DateHelper::select_time($datetime, $options);
 215      }
 216  
 217      /**
 218        * Returns a set of html select-tags (one for hour and minute)
 219        */
 220      function select_time($datetime = null, $options = array())
 221      {
 222          $datetime = empty($datetime) ? Ak::getDate() : $datetime;
 223          return DateHelper::select_hour($datetime, $options) . DateHelper::select_minute($datetime, $options) .
 224          (!empty($options['include_seconds']) ? DateHelper::select_second($datetime, $options) : '');
 225      }
 226  
 227      /**
 228        * Returns a select tag with options for each of the seconds 0 through 59 with the current second selected.
 229        * The <tt>second</tt> can also be substituted for a second number.
 230        * Override the field name using the <tt>field_name</tt> option, 'second' by default.
 231        */
 232      function select_second($datetime, $options = array())
 233      {
 234          return DateHelper::_select_for('second',range(0,59),'s',$datetime, $options);
 235      }
 236  
 237      /**
 238        * Returns a select tag with options for each of the minutes 0 through 59 with the current minute selected.
 239        * Also can return a select tag with options by <tt>minute_step</tt> from 0 through 59 with the 00 minute selected
 240        * The <tt>minute</tt> can also be substituted for a minute number.
 241        * Override the field name using the <tt>field_name</tt> option, 'minute' by default.
 242        */
 243      function select_minute($datetime, $options = array())
 244      {
 245          return DateHelper::_select_for('minute',range(0,59),'i',$datetime, $options);
 246      }
 247  
 248      /**
 249        * Returns a select tag with options for each of the hours 0 through 23 with the current hour selected.
 250        * The <tt>hour</tt> can also be substituted for a hour number.
 251        * Override the field name using the <tt>:field_name</tt> option, 'hour' by default
 252        */
 253      function select_hour($datetime, $options = array())
 254      {
 255          return DateHelper::_select_for('hour',range(0,23),'H',$datetime, $options);
 256      }
 257  
 258      /**
 259        * Returns a select tag with options for each of the days 1 through 31 with the current day selected.
 260        * The <tt>date</tt> can also be substituted for a hour number.
 261        * Override the field name using the <tt>field_name</tt> option, 'day' by default.
 262        */
 263      function select_day($date, $options = array())
 264      {
 265          return DateHelper::_select_for('day',range(1,31),'j',$date, $options,false);
 266      }
 267  
 268      /**
 269        * Returns a select tag with options for each of the months January through December with the current month selected.
 270        * The month names are presented as keys (what's shown to the user) and the month numbers (1-12) are used as values
 271        * (what's submitted to the server). It's also possible to use month numbers for the presentation instead of names --
 272        * set the <tt>use_month_numbers</tt> key in +options+ to true for this to happen. If you want both numbers and names,
 273        * set the <tt>add_month_numbers</tt> key in +options+ to true. Examples:
 274        *
 275        *   $date_helper->select_month(Ak::getDate()); // Will use keys like "January", "March"
 276        *   $date_helper->select_month(Ak::getDate(), array('use_month_numbers' => true)); // Will use keys like "1", "3"
 277        *   $date_helper->select_month(Ak::getDate(), array('add_month_numbers' => true)); // Will use keys like "1 - January", "3 - March"
 278        *
 279        * Override the field name using the <tt>field_name</tt> option, 'month' by default.
 280        *
 281        * If you would prefer to show month names as abbreviations, set the
 282        * <tt>use_short_month</tt> key in +options+ to true.
 283        */
 284      function select_month($date=null, $options = array())
 285      {
 286          if(!empty($options['use_month_numbers'])){
 287              $month_details = '1,2,3,4,5,6,7,8,9,10,11,12';
 288          }elseif(!empty($options['add_month_numbers']) && empty($options['use_short_month'])){
 289              $month_details = Ak::t('1 - January,2 - February,3 - March,4 - April,5 - May,6 - June,7 - July,8 - August,'.
 290              '9 - September,10 - October,11 - November,12 - December',array(),'localize/date');
 291          }elseif(!empty($options['add_month_numbers']) && !empty($options['use_short_month'])){
 292              $month_details = Ak::t('1 - Jan,2 - Feb,3 - Mar,4 - Apr,5 - May,6 - Jun,7 - Jul,8 - Aug,9 - Sep,10 - Oct,11 - Nov,12 - Dec',array(),'localize/date');
 293          }elseif(empty($options['add_month_numbers']) && !empty($options['use_short_month'])){
 294              $month_details = Ak::t('Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec',array(),'localize/date');
 295          }else{
 296              $month_details = Ak::t('January,February,March,April,May,June,July,August,September,October,November,December',array(),'localize/date');
 297          }
 298  
 299          $date = !empty($options['include_blank']) ? (!empty($date) ? $date : 0) : (!empty($date) ? $date : Ak::getDate());
 300  
 301          return DateHelper::_select_for('month', explode(',',$month_details),'n', $date, $options,'_add_one');
 302      }
 303  
 304      /**
 305        * Returns a select tag with options for each of the five years on each side of the current, which is selected. The five year radius
 306        * can be changed using the <tt>:start_year</tt> and <tt>:end_year</tt> keys in the +options+. Both ascending and descending year
 307        * lists are supported by making <tt>start_year</tt> less than or greater than <tt>end_year</tt>. The <tt>date</tt> can also be
 308        * substituted for a year given as a number. Example:
 309        *
 310        *   $date_helper->select_year(Ak::getDate(), array('start_year' => 1992, 'end_year' => 2007)); // ascending year values
 311        *   $date_helper->select_year(Ak::getDate(), array('start_year' => 2005, 'end_year' => 1900)); //  descending year values
 312        *
 313        * Override the field name using the <tt>field_name</tt> option, 'year' by default.
 314        */
 315      function select_year($date = null, $options = array())
 316      {
 317          $year = Ak::getDate(Ak::getTimestamp(isset($date) ? $date.'-01-01' : null),'Y');
 318  
 319          $start_year = !empty($options['start_year']) ? $options['start_year'] : $year-5;
 320          $end_year = !empty($options['end_year']) ? $options['end_year'] : $year+5;
 321  
 322          $range = range($start_year,$end_year);
 323          $start_year < $end_year ? array_reverse($range): null;
 324  
 325          return DateHelper::_select_for('year',$range,'Y',$date, $options,false);
 326      }
 327  
 328      function _select_for($select_type, $range, $date_format, $datetime, $options = array(), $unit_format_callback = '_leading_zero_on_single_digits')
 329      {
 330          $options_array = array();
 331          
 332          if (!empty($options['include_blank']) && $datetime == 0) {
 333              $datetime_unit = "";
 334              $date_blank = true;
 335          } else {
 336              $datetime = empty($datetime) ? Ak::getDate() : $datetime;
 337              $datetime_unit = Ak::getDate(Ak::getTimestamp($datetime),$date_format);
 338              $date_blank = false;
 339          } 
 340  
 341          foreach ($range as $k=>$time_unit){
 342              if(is_string($time_unit)){
 343                  $k = !empty($unit_format_callback) ? DateHelper::$unit_format_callback($k) : $k;
 344                  $options_array[] = '<option value="'.$k.'"'.($k == $datetime_unit ? ' selected="selected"' : '').">$time_unit</option>";
 345              }else{
 346                  $time_unit = !empty($unit_format_callback) ? DateHelper::$unit_format_callback($time_unit) : $time_unit;
 347                  $options_array[] = '<option value="'.$time_unit.'"'.($time_unit == $datetime_unit ? ' selected="selected"' : '').">$time_unit</option>";
 348              }
 349          }
 350          return DateHelper::_select_html(empty($options['field_name']) ? $select_type : $options['field_name'],
 351          $options_array, @$options['prefix'], @$options['include_blank'], @$options['discard_type'], @$options['disabled'], $date_blank);
 352      }
 353  
 354      function _select_html($type, $options, $prefix = null, $include_blank = false, $discard_type = false, $disabled = false, $date_blank = false)
 355      {
 356          return '<select name="'.(empty($prefix) ? AK_DATE_HELPER_DEFAULT_PREFIX : $prefix).
 357          ($discard_type ? '' : $type).'"'.
 358          ($disabled ? ' disabled="disabled"' : '').">\n".
 359          ($include_blank && $date_blank ? "<option value=\"\" selected=\"selected\"></option>\n" : '').
 360          ($include_blank && !$date_blank ? "<option value=\"\"></option>\n" : '').
 361          (!empty($options) ? join("\n",$options) : '')."\n</select>\n";
 362      }
 363  
 364      function _leading_zero_on_single_digits($number)
 365      {
 366          return $number > 9 ? $number : "0$number";
 367      }
 368  
 369      function _add_one($number)
 370      {
 371          return $number+1;
 372      }
 373  
 374  
 375      /**
 376       * Converts an ISO date to current locale format
 377       *
 378       */
 379      function locale_date_time($iso_date_time = null)
 380      {
 381          $timestamp = Ak::getTimestamp($iso_date_time);
 382          $format = Ak::locale('date_time_format');
 383          return Ak::getDate($timestamp, $format);
 384      }
 385  
 386      /**
 387       * Converts an ISO date to current locale format
 388       *
 389       */
 390      function locale_date($iso_date = null)
 391      {
 392          $timestamp = Ak::getTimestamp($iso_date);
 393          $format = Ak::locale('date_format');
 394          return Ak::getDate($timestamp, $format);
 395      }
 396  }
 397  
 398  
 399  
 400  ?>


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