function.html_select_date.php (14130B)
1 <?php 2 /** 3 * Smarty plugin 4 * 5 * @package Smarty 6 * @subpackage PluginsFunction 7 */ 8 9 /** 10 * @ignore 11 */ 12 require_once(SMARTY_PLUGINS_DIR . 'shared.escape_special_chars.php'); 13 /** 14 * @ignore 15 */ 16 require_once(SMARTY_PLUGINS_DIR . 'shared.make_timestamp.php'); 17 18 /** 19 * Smarty {html_select_date} plugin 20 * Type: function<br> 21 * Name: html_select_date<br> 22 * Purpose: Prints the dropdowns for date selection. 23 * ChangeLog: 24 * <pre> 25 * - 1.0 initial release 26 * - 1.1 added support for +/- N syntax for begin 27 * and end year values. (Monte) 28 * - 1.2 added support for yyyy-mm-dd syntax for 29 * time value. (Jan Rosier) 30 * - 1.3 added support for choosing format for 31 * month values (Gary Loescher) 32 * - 1.3.1 added support for choosing format for 33 * day values (Marcus Bointon) 34 * - 1.3.2 support negative timestamps, force year 35 * dropdown to include given date unless explicitly set (Monte) 36 * - 1.3.4 fix behaviour of 0000-00-00 00:00:00 dates to match that 37 * of 0000-00-00 dates (cybot, boots) 38 * - 2.0 complete rewrite for performance, 39 * added attributes month_names, *_id 40 * </pre> 41 * 42 * @link http://www.smarty.net/manual/en/language.function.html.select.date.php {html_select_date} 43 * (Smarty online manual) 44 * @version 2.0 45 * @author Andrei Zmievski 46 * @author Monte Ohrt <monte at ohrt dot com> 47 * @author Rodney Rehm 48 * 49 * @param array $params parameters 50 * 51 * @return string 52 */ 53 function smarty_function_html_select_date($params) 54 { 55 // generate timestamps used for month names only 56 static $_month_timestamps = null; 57 static $_current_year = null; 58 if ($_month_timestamps === null) { 59 $_current_year = date('Y'); 60 $_month_timestamps = array(); 61 for ($i = 1; $i <= 12; $i ++) { 62 $_month_timestamps[$i] = mktime(0, 0, 0, $i, 1, 2000); 63 } 64 } 65 66 /* Default values. */ 67 $prefix = "Date_"; 68 $start_year = null; 69 $end_year = null; 70 $display_days = true; 71 $display_months = true; 72 $display_years = true; 73 $month_format = "%B"; 74 /* Write months as numbers by default GL */ 75 $month_value_format = "%m"; 76 $day_format = "%02d"; 77 /* Write day values using this format MB */ 78 $day_value_format = "%d"; 79 $year_as_text = false; 80 /* Display years in reverse order? Ie. 2000,1999,.... */ 81 $reverse_years = false; 82 /* Should the select boxes be part of an array when returned from PHP? 83 e.g. setting it to "birthday", would create "birthday[Day]", 84 "birthday[Month]" & "birthday[Year]". Can be combined with prefix */ 85 $field_array = null; 86 /* <select size>'s of the different <select> tags. 87 If not set, uses default dropdown. */ 88 $day_size = null; 89 $month_size = null; 90 $year_size = null; 91 /* Unparsed attributes common to *ALL* the <select>/<input> tags. 92 An example might be in the template: all_extra ='class ="foo"'. */ 93 $all_extra = null; 94 /* Separate attributes for the tags. */ 95 $day_extra = null; 96 $month_extra = null; 97 $year_extra = null; 98 /* Order in which to display the fields. 99 "D" -> day, "M" -> month, "Y" -> year. */ 100 $field_order = 'MDY'; 101 /* String printed between the different fields. */ 102 $field_separator = "\n"; 103 $option_separator = "\n"; 104 $time = null; 105 // $all_empty = null; 106 // $day_empty = null; 107 // $month_empty = null; 108 // $year_empty = null; 109 $extra_attrs = ''; 110 $all_id = null; 111 $day_id = null; 112 $month_id = null; 113 $year_id = null; 114 115 foreach ($params as $_key => $_value) { 116 switch ($_key) { 117 case 'time': 118 if (!is_array($_value) && $_value !== null) { 119 $time = smarty_make_timestamp($_value); 120 } 121 break; 122 123 case 'month_names': 124 if (is_array($_value) && count($_value) == 12) { 125 $$_key = $_value; 126 } else { 127 trigger_error("html_select_date: month_names must be an array of 12 strings", E_USER_NOTICE); 128 } 129 break; 130 131 case 'prefix': 132 case 'field_array': 133 case 'start_year': 134 case 'end_year': 135 case 'day_format': 136 case 'day_value_format': 137 case 'month_format': 138 case 'month_value_format': 139 case 'day_size': 140 case 'month_size': 141 case 'year_size': 142 case 'all_extra': 143 case 'day_extra': 144 case 'month_extra': 145 case 'year_extra': 146 case 'field_order': 147 case 'field_separator': 148 case 'option_separator': 149 case 'all_empty': 150 case 'month_empty': 151 case 'day_empty': 152 case 'year_empty': 153 case 'all_id': 154 case 'month_id': 155 case 'day_id': 156 case 'year_id': 157 $$_key = (string) $_value; 158 break; 159 160 case 'display_days': 161 case 'display_months': 162 case 'display_years': 163 case 'year_as_text': 164 case 'reverse_years': 165 $$_key = (bool) $_value; 166 break; 167 168 default: 169 if (!is_array($_value)) { 170 $extra_attrs .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_value) . '"'; 171 } else { 172 trigger_error("html_select_date: extra attribute '$_key' cannot be an array", E_USER_NOTICE); 173 } 174 break; 175 } 176 } 177 178 // Note: date() is faster than strftime() 179 // Note: explode(date()) is faster than date() date() date() 180 if (isset($params['time']) && is_array($params['time'])) { 181 if (isset($params['time'][$prefix . 'Year'])) { 182 // $_REQUEST[$field_array] given 183 foreach (array('Y' => 'Year', 'm' => 'Month', 'd' => 'Day') as $_elementKey => $_elementName) { 184 $_variableName = '_' . strtolower($_elementName); 185 $$_variableName = isset($params['time'][$prefix . $_elementName]) 186 ? $params['time'][$prefix . $_elementName] 187 : date($_elementKey); 188 } 189 } elseif (isset($params['time'][$field_array][$prefix . 'Year'])) { 190 // $_REQUEST given 191 foreach (array('Y' => 'Year', 'm' => 'Month', 'd' => 'Day') as $_elementKey => $_elementName) { 192 $_variableName = '_' . strtolower($_elementName); 193 $$_variableName = isset($params['time'][$field_array][$prefix . $_elementName]) 194 ? $params['time'][$field_array][$prefix . $_elementName] 195 : date($_elementKey); 196 } 197 } else { 198 // no date found, use NOW 199 list($_year, $_month, $_day) = $time = explode('-', date('Y-m-d')); 200 } 201 } elseif ($time === null) { 202 if (array_key_exists('time', $params)) { 203 $_year = $_month = $_day = $time = null; 204 } else { 205 list($_year, $_month, $_day) = $time = explode('-', date('Y-m-d')); 206 } 207 } else { 208 list($_year, $_month, $_day) = $time = explode('-', date('Y-m-d', $time)); 209 } 210 211 // make syntax "+N" or "-N" work with $start_year and $end_year 212 // Note preg_match('!^(\+|\-)\s*(\d+)$!', $end_year, $match) is slower than trim+substr 213 foreach (array('start', 'end') as $key) { 214 $key .= '_year'; 215 $t = $$key; 216 if ($t === null) { 217 $$key = (int) $_current_year; 218 } elseif ($t[0] == '+') { 219 $$key = (int) ($_current_year + (int)trim(substr($t, 1))); 220 } elseif ($t[0] == '-') { 221 $$key = (int) ($_current_year - (int)trim(substr($t, 1))); 222 } else { 223 $$key = (int) $$key; 224 } 225 } 226 227 // flip for ascending or descending 228 if (($start_year > $end_year && !$reverse_years) || ($start_year < $end_year && $reverse_years)) { 229 $t = $end_year; 230 $end_year = $start_year; 231 $start_year = $t; 232 } 233 234 // generate year <select> or <input> 235 if ($display_years) { 236 $_extra = ''; 237 $_name = $field_array ? ($field_array . '[' . $prefix . 'Year]') : ($prefix . 'Year'); 238 if ($all_extra) { 239 $_extra .= ' ' . $all_extra; 240 } 241 if ($year_extra) { 242 $_extra .= ' ' . $year_extra; 243 } 244 245 if ($year_as_text) { 246 $_html_years = '<input type="text" name="' . $_name . '" value="' . $_year . '" size="4" maxlength="4"' . $_extra . $extra_attrs . ' />'; 247 } else { 248 $_html_years = '<select name="' . $_name . '"'; 249 if ($year_id !== null || $all_id !== null) { 250 $_html_years .= ' id="' . smarty_function_escape_special_chars( 251 $year_id !== null ? ($year_id ? $year_id : $_name) : ($all_id ? ($all_id . $_name) : $_name) 252 ) . '"'; 253 } 254 if ($year_size) { 255 $_html_years .= ' size="' . $year_size . '"'; 256 } 257 $_html_years .= $_extra . $extra_attrs . '>' . $option_separator; 258 259 if (isset($year_empty) || isset($all_empty)) { 260 $_html_years .= '<option value="">' . (isset($year_empty) ? $year_empty : $all_empty) . '</option>' . $option_separator; 261 } 262 263 $op = $start_year > $end_year ? - 1 : 1; 264 for ($i = $start_year; $op > 0 ? $i <= $end_year : $i >= $end_year; $i += $op) { 265 $_html_years .= '<option value="' . $i . '"' 266 . ($_year == $i ? ' selected="selected"' : '') 267 . '>' . $i . '</option>' . $option_separator; 268 } 269 270 $_html_years .= '</select>'; 271 } 272 } 273 274 // generate month <select> or <input> 275 if ($display_months) { 276 $_extra = ''; 277 $_name = $field_array ? ($field_array . '[' . $prefix . 'Month]') : ($prefix . 'Month'); 278 if ($all_extra) { 279 $_extra .= ' ' . $all_extra; 280 } 281 if ($month_extra) { 282 $_extra .= ' ' . $month_extra; 283 } 284 285 $_html_months = '<select name="' . $_name . '"'; 286 if ($month_id !== null || $all_id !== null) { 287 $_html_months .= ' id="' . smarty_function_escape_special_chars( 288 $month_id !== null ? ($month_id ? $month_id : $_name) : ($all_id ? ($all_id . $_name) : $_name) 289 ) . '"'; 290 } 291 if ($month_size) { 292 $_html_months .= ' size="' . $month_size . '"'; 293 } 294 $_html_months .= $_extra . $extra_attrs . '>' . $option_separator; 295 296 if (isset($month_empty) || isset($all_empty)) { 297 $_html_months .= '<option value="">' . (isset($month_empty) ? $month_empty : $all_empty) . '</option>' . $option_separator; 298 } 299 300 for ($i = 1; $i <= 12; $i ++) { 301 $_val = sprintf('%02d', $i); 302 $_text = isset($month_names) ? smarty_function_escape_special_chars($month_names[$i]) : ($month_format == "%m" ? $_val : strftime($month_format, $_month_timestamps[$i])); 303 $_value = $month_value_format == "%m" ? $_val : strftime($month_value_format, $_month_timestamps[$i]); 304 $_html_months .= '<option value="' . $_value . '"' 305 . ($_val == $_month ? ' selected="selected"' : '') 306 . '>' . $_text . '</option>' . $option_separator; 307 } 308 309 $_html_months .= '</select>'; 310 } 311 312 // generate day <select> or <input> 313 if ($display_days) { 314 $_extra = ''; 315 $_name = $field_array ? ($field_array . '[' . $prefix . 'Day]') : ($prefix . 'Day'); 316 if ($all_extra) { 317 $_extra .= ' ' . $all_extra; 318 } 319 if ($day_extra) { 320 $_extra .= ' ' . $day_extra; 321 } 322 323 $_html_days = '<select name="' . $_name . '"'; 324 if ($day_id !== null || $all_id !== null) { 325 $_html_days .= ' id="' . smarty_function_escape_special_chars( 326 $day_id !== null ? ($day_id ? $day_id : $_name) : ($all_id ? ($all_id . $_name) : $_name) 327 ) . '"'; 328 } 329 if ($day_size) { 330 $_html_days .= ' size="' . $day_size . '"'; 331 } 332 $_html_days .= $_extra . $extra_attrs . '>' . $option_separator; 333 334 if (isset($day_empty) || isset($all_empty)) { 335 $_html_days .= '<option value="">' . (isset($day_empty) ? $day_empty : $all_empty) . '</option>' . $option_separator; 336 } 337 338 for ($i = 1; $i <= 31; $i ++) { 339 $_val = sprintf('%02d', $i); 340 $_text = $day_format == '%02d' ? $_val : sprintf($day_format, $i); 341 $_value = $day_value_format == '%02d' ? $_val : sprintf($day_value_format, $i); 342 $_html_days .= '<option value="' . $_value . '"' 343 . ($_val == $_day ? ' selected="selected"' : '') 344 . '>' . $_text . '</option>' . $option_separator; 345 } 346 347 $_html_days .= '</select>'; 348 } 349 350 // order the fields for output 351 $_html = ''; 352 for ($i = 0; $i <= 2; $i ++) { 353 switch ($field_order[$i]) { 354 case 'Y': 355 case 'y': 356 if (isset($_html_years)) { 357 if ($_html) { 358 $_html .= $field_separator; 359 } 360 $_html .= $_html_years; 361 } 362 break; 363 364 case 'm': 365 case 'M': 366 if (isset($_html_months)) { 367 if ($_html) { 368 $_html .= $field_separator; 369 } 370 $_html .= $_html_months; 371 } 372 break; 373 374 case 'd': 375 case 'D': 376 if (isset($_html_days)) { 377 if ($_html) { 378 $_html .= $field_separator; 379 } 380 $_html .= $_html_days; 381 } 382 break; 383 } 384 } 385 386 return $_html; 387 }