| [ Index ] |
PHP Cross Reference of Akelos Framework |
[Summary view] [Print] [Text view]
1 <?php 2 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ 3 4 // +----------------------------------------------------------------------+ 5 // | Akelos Framework - http://www.akelos.org | 6 // +----------------------------------------------------------------------+ 7 // | Copyright (c) 2002-2006, Akelos Media, S.L. & Bermi Ferrer Martinez | 8 // | Released under the GNU Lesser General Public License, see LICENSE.txt| 9 // +----------------------------------------------------------------------+ 10 11 /** 12 * @package ActionView 13 * @subpackage Helpers 14 * @author Bermi Ferrer <bermi a.t akelos c.om> 15 * @copyright Copyright (c) 2002-2006, Akelos Media, S.L. http://www.akelos.org 16 * @license GNU Lesser General Public License <http://www.gnu.org/copyleft/lesser.html> 17 */ 18 19 20 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' ? ' — ' : ($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 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Mon Oct 27 12:43:49 2008 | Cross-referenced by PHPXref 0.6 |