library/smarty/libs/plugins/function.html_select_date.php
changeset 46 f11c31f7fa3e
parent 45 a56e7f9a0463
child 47 03388ec805b4
equal deleted inserted replaced
45:a56e7f9a0463 46:f11c31f7fa3e
     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     // generate timestamps used for month names only
       
    55     static $_month_timestamps = null;
       
    56     static $_current_year = null;
       
    57     if ($_month_timestamps === null) {
       
    58         $_current_year = date('Y');
       
    59         $_month_timestamps = array();
       
    60         for ($i = 1; $i <= 12; $i++) {
       
    61             $_month_timestamps[$i] = mktime(0, 0, 0, $i, 1, 2000);
       
    62         }
       
    63     }
       
    64 
       
    65     /* Default values. */
       
    66     $prefix = "Date_";
       
    67     $start_year = null;
       
    68     $end_year = null;
       
    69     $display_days = true;
       
    70     $display_months = true;
       
    71     $display_years = true;
       
    72     $month_format = "%B";
       
    73     /* Write months as numbers by default  GL */
       
    74     $month_value_format = "%m";
       
    75     $day_format = "%02d";
       
    76     /* Write day values using this format MB */
       
    77     $day_value_format = "%d";
       
    78     $year_as_text = false;
       
    79     /* Display years in reverse order? Ie. 2000,1999,.... */
       
    80     $reverse_years = false;
       
    81     /* Should the select boxes be part of an array when returned from PHP?
       
    82        e.g. setting it to "birthday", would create "birthday[Day]",
       
    83        "birthday[Month]" & "birthday[Year]". Can be combined with prefix */
       
    84     $field_array = null;
       
    85     /* <select size>'s of the different <select> tags.
       
    86        If not set, uses default dropdown. */
       
    87     $day_size = null;
       
    88     $month_size = null;
       
    89     $year_size = null;
       
    90     /* Unparsed attributes core to *ALL* the <select>/<input> tags.
       
    91        An example might be in the template: all_extra ='class ="foo"'. */
       
    92     $all_extra = null;
       
    93     /* Separate attributes for the tags. */
       
    94     $day_extra = null;
       
    95     $month_extra = null;
       
    96     $year_extra = null;
       
    97     /* Order in which to display the fields.
       
    98        "D" -> day, "M" -> month, "Y" -> year. */
       
    99     $field_order = 'MDY';
       
   100     /* String printed between the different fields. */
       
   101     $field_separator = "\n";
       
   102     $option_separator = "\n";
       
   103     $time = null;
       
   104     // $all_empty = null;
       
   105     // $day_empty = null;
       
   106     // $month_empty = null;
       
   107     // $year_empty = null;
       
   108     $extra_attrs = '';
       
   109     $all_id = null;
       
   110     $day_id = null;
       
   111     $month_id = null;
       
   112     $year_id = null;
       
   113 
       
   114     foreach ($params as $_key => $_value) {
       
   115         switch ($_key) {
       
   116             case 'time':
       
   117                 if (!is_array($_value) && $_value !== null) {
       
   118                     $time = smarty_make_timestamp($_value);
       
   119                 }
       
   120                 break;
       
   121 
       
   122             case 'month_names':
       
   123                 if (is_array($_value) && count($_value) == 12) {
       
   124                     $$_key = $_value;
       
   125                 } else {
       
   126                     trigger_error("html_select_date: month_names must be an array of 12 strings", E_USER_NOTICE);
       
   127                 }
       
   128                 break;
       
   129 
       
   130             case 'prefix':
       
   131             case 'field_array':
       
   132             case 'start_year':
       
   133             case 'end_year':
       
   134             case 'day_format':
       
   135             case 'day_value_format':
       
   136             case 'month_format':
       
   137             case 'month_value_format':
       
   138             case 'day_size':
       
   139             case 'month_size':
       
   140             case 'year_size':
       
   141             case 'all_extra':
       
   142             case 'day_extra':
       
   143             case 'month_extra':
       
   144             case 'year_extra':
       
   145             case 'field_order':
       
   146             case 'field_separator':
       
   147             case 'option_separator':
       
   148             case 'all_empty':
       
   149             case 'month_empty':
       
   150             case 'day_empty':
       
   151             case 'year_empty':
       
   152             case 'all_id':
       
   153             case 'month_id':
       
   154             case 'day_id':
       
   155             case 'year_id':
       
   156                 $$_key = (string)$_value;
       
   157                 break;
       
   158 
       
   159             case 'display_days':
       
   160             case 'display_months':
       
   161             case 'display_years':
       
   162             case 'year_as_text':
       
   163             case 'reverse_years':
       
   164                 $$_key = (bool)$_value;
       
   165                 break;
       
   166 
       
   167             default:
       
   168                 if (!is_array($_value)) {
       
   169                     $extra_attrs .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_value) . '"';
       
   170                 } else {
       
   171                     trigger_error("html_select_date: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
       
   172                 }
       
   173                 break;
       
   174         }
       
   175     }
       
   176 
       
   177     // Note: date() is faster than strftime()
       
   178     // Note: explode(date()) is faster than date() date() date()
       
   179     if (isset($params['time']) && is_array($params['time'])) {
       
   180         if (isset($params['time'][$prefix . 'Year'])) {
       
   181             // $_REQUEST[$field_array] given
       
   182             foreach (array('Y' => 'Year', 'm' => 'Month', 'd' => 'Day') as $_elementKey => $_elementName) {
       
   183                 $_variableName = '_' . strtolower($_elementName);
       
   184                 $$_variableName = isset($params['time'][$prefix . $_elementName])
       
   185                     ? $params['time'][$prefix . $_elementName]
       
   186                     : date($_elementKey);
       
   187             }
       
   188         } elseif (isset($params['time'][$field_array][$prefix . 'Year'])) {
       
   189             // $_REQUEST given
       
   190             foreach (array('Y' => 'Year', 'm' => 'Month', 'd' => 'Day') as $_elementKey => $_elementName) {
       
   191                 $_variableName = '_' . strtolower($_elementName);
       
   192                 $$_variableName = isset($params['time'][$field_array][$prefix . $_elementName])
       
   193                     ? $params['time'][$field_array][$prefix . $_elementName]
       
   194                     : date($_elementKey);
       
   195             }
       
   196         } else {
       
   197             // no date found, use NOW
       
   198             list($_year, $_month, $_day) = $time = explode('-', date('Y-m-d'));
       
   199         }
       
   200     } elseif ($time === null) {
       
   201         if (array_key_exists('time', $params)) {
       
   202             $_year = $_month = $_day = $time = null;
       
   203         } else {
       
   204             list($_year, $_month, $_day) = $time = explode('-', date('Y-m-d'));
       
   205         }
       
   206     } else {
       
   207         list($_year, $_month, $_day) = $time = explode('-', date('Y-m-d', $time));
       
   208     }
       
   209 
       
   210     // make syntax "+N" or "-N" work with $start_year and $end_year
       
   211     // Note preg_match('!^(\+|\-)\s*(\d+)$!', $end_year, $match) is slower than trim+substr
       
   212     foreach (array('start', 'end') as $key) {
       
   213         $key .= '_year';
       
   214         $t = $$key;
       
   215         if ($t === null) {
       
   216             $$key = (int)$_current_year;
       
   217         } elseif ($t[0] == '+') {
       
   218             $$key = (int)($_current_year + (int)trim(substr($t, 1)));
       
   219         } elseif ($t[0] == '-') {
       
   220             $$key = (int)($_current_year - (int)trim(substr($t, 1)));
       
   221         } else {
       
   222             $$key = (int)$$key;
       
   223         }
       
   224     }
       
   225 
       
   226     // flip for ascending or descending
       
   227     if (($start_year > $end_year && !$reverse_years) || ($start_year < $end_year && $reverse_years)) {
       
   228         $t = $end_year;
       
   229         $end_year = $start_year;
       
   230         $start_year = $t;
       
   231     }
       
   232 
       
   233     // generate year <select> or <input>
       
   234     if ($display_years) {
       
   235         $_extra = '';
       
   236         $_name = $field_array ? ($field_array . '[' . $prefix . 'Year]') : ($prefix . 'Year');
       
   237         if ($all_extra) {
       
   238             $_extra .= ' ' . $all_extra;
       
   239         }
       
   240         if ($year_extra) {
       
   241             $_extra .= ' ' . $year_extra;
       
   242         }
       
   243 
       
   244         if ($year_as_text) {
       
   245             $_html_years = '<input type="text" name="' . $_name . '" value="' . $_year . '" size="4" maxlength="4"' . $_extra . $extra_attrs . ' />';
       
   246         } else {
       
   247             $_html_years = '<select name="' . $_name . '"';
       
   248             if ($year_id !== null || $all_id !== null) {
       
   249                 $_html_years .= ' id="' . smarty_function_escape_special_chars(
       
   250                         $year_id !== null ? ($year_id ? $year_id : $_name) : ($all_id ? ($all_id . $_name) : $_name)
       
   251                     ) . '"';
       
   252             }
       
   253             if ($year_size) {
       
   254                 $_html_years .= ' size="' . $year_size . '"';
       
   255             }
       
   256             $_html_years .= $_extra . $extra_attrs . '>' . $option_separator;
       
   257 
       
   258             if (isset($year_empty) || isset($all_empty)) {
       
   259                 $_html_years .= '<option value="">' . (isset($year_empty) ? $year_empty : $all_empty) . '</option>' . $option_separator;
       
   260             }
       
   261 
       
   262             $op = $start_year > $end_year ? -1 : 1;
       
   263             for ($i = $start_year; $op > 0 ? $i <= $end_year : $i >= $end_year; $i += $op) {
       
   264                 $_html_years .= '<option value="' . $i . '"'
       
   265                     . ($_year == $i ? ' selected="selected"' : '')
       
   266                     . '>' . $i . '</option>' . $option_separator;
       
   267             }
       
   268 
       
   269             $_html_years .= '</select>';
       
   270         }
       
   271     }
       
   272 
       
   273     // generate month <select> or <input>
       
   274     if ($display_months) {
       
   275         $_extra = '';
       
   276         $_name = $field_array ? ($field_array . '[' . $prefix . 'Month]') : ($prefix . 'Month');
       
   277         if ($all_extra) {
       
   278             $_extra .= ' ' . $all_extra;
       
   279         }
       
   280         if ($month_extra) {
       
   281             $_extra .= ' ' . $month_extra;
       
   282         }
       
   283 
       
   284         $_html_months = '<select name="' . $_name . '"';
       
   285         if ($month_id !== null || $all_id !== null) {
       
   286             $_html_months .= ' id="' . smarty_function_escape_special_chars(
       
   287                     $month_id !== null ? ($month_id ? $month_id : $_name) : ($all_id ? ($all_id . $_name) : $_name)
       
   288                 ) . '"';
       
   289         }
       
   290         if ($month_size) {
       
   291             $_html_months .= ' size="' . $month_size . '"';
       
   292         }
       
   293         $_html_months .= $_extra . $extra_attrs . '>' . $option_separator;
       
   294 
       
   295         if (isset($month_empty) || isset($all_empty)) {
       
   296             $_html_months .= '<option value="">' . (isset($month_empty) ? $month_empty : $all_empty) . '</option>' . $option_separator;
       
   297         }
       
   298 
       
   299         for ($i = 1; $i <= 12; $i++) {
       
   300             $_val = sprintf('%02d', $i);
       
   301             $_text = isset($month_names) ? smarty_function_escape_special_chars($month_names[$i]) : ($month_format == "%m" ? $_val : strftime($month_format, $_month_timestamps[$i]));
       
   302             $_value = $month_value_format == "%m" ? $_val : strftime($month_value_format, $_month_timestamps[$i]);
       
   303             $_html_months .= '<option value="' . $_value . '"'
       
   304                 . ($_val == $_month ? ' selected="selected"' : '')
       
   305                 . '>' . $_text . '</option>' . $option_separator;
       
   306         }
       
   307 
       
   308         $_html_months .= '</select>';
       
   309     }
       
   310 
       
   311     // generate day <select> or <input>
       
   312     if ($display_days) {
       
   313         $_extra = '';
       
   314         $_name = $field_array ? ($field_array . '[' . $prefix . 'Day]') : ($prefix . 'Day');
       
   315         if ($all_extra) {
       
   316             $_extra .= ' ' . $all_extra;
       
   317         }
       
   318         if ($day_extra) {
       
   319             $_extra .= ' ' . $day_extra;
       
   320         }
       
   321 
       
   322         $_html_days = '<select name="' . $_name . '"';
       
   323         if ($day_id !== null || $all_id !== null) {
       
   324             $_html_days .= ' id="' . smarty_function_escape_special_chars(
       
   325                     $day_id !== null ? ($day_id ? $day_id : $_name) : ($all_id ? ($all_id . $_name) : $_name)
       
   326                 ) . '"';
       
   327         }
       
   328         if ($day_size) {
       
   329             $_html_days .= ' size="' . $day_size . '"';
       
   330         }
       
   331         $_html_days .= $_extra . $extra_attrs . '>' . $option_separator;
       
   332 
       
   333         if (isset($day_empty) || isset($all_empty)) {
       
   334             $_html_days .= '<option value="">' . (isset($day_empty) ? $day_empty : $all_empty) . '</option>' . $option_separator;
       
   335         }
       
   336 
       
   337         for ($i = 1; $i <= 31; $i++) {
       
   338             $_val = sprintf('%02d', $i);
       
   339             $_text = $day_format == '%02d' ? $_val : sprintf($day_format, $i);
       
   340             $_value = $day_value_format == '%02d' ? $_val : sprintf($day_value_format, $i);
       
   341             $_html_days .= '<option value="' . $_value . '"'
       
   342                 . ($_val == $_day ? ' selected="selected"' : '')
       
   343                 . '>' . $_text . '</option>' . $option_separator;
       
   344         }
       
   345 
       
   346         $_html_days .= '</select>';
       
   347     }
       
   348 
       
   349     // order the fields for output
       
   350     $_html = '';
       
   351     for ($i = 0; $i <= 2; $i++) {
       
   352         switch ($field_order[$i]) {
       
   353             case 'Y':
       
   354             case 'y':
       
   355                 if (isset($_html_years)) {
       
   356                     if ($_html) {
       
   357                         $_html .= $field_separator;
       
   358                     }
       
   359                     $_html .= $_html_years;
       
   360                 }
       
   361                 break;
       
   362 
       
   363             case 'm':
       
   364             case 'M':
       
   365                 if (isset($_html_months)) {
       
   366                     if ($_html) {
       
   367                         $_html .= $field_separator;
       
   368                     }
       
   369                     $_html .= $_html_months;
       
   370                 }
       
   371                 break;
       
   372 
       
   373             case 'd':
       
   374             case 'D':
       
   375                 if (isset($_html_days)) {
       
   376                     if ($_html) {
       
   377                         $_html .= $field_separator;
       
   378                     }
       
   379                     $_html .= $_html_days;
       
   380                 }
       
   381                 break;
       
   382         }
       
   383     }
       
   384 
       
   385     return $_html;
       
   386 }