Changeset 1482

Show
Ignore:
Timestamp:
01/10/07 22:11:24 (2 years ago)
Author:
dominik
Message:

BREAKING CHANGE!
rewrite date validator to contain the stuff in the ticket
to see what the new parameters are check the phpdoc
refs #359

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • branches/0.11/src/validator/AgaviDateValidator.class.php

    r1245 r1482  
    1717 * AgaviDateValidator verifies that a parameter is of a date format. 
    1818 *  
    19  * This validator checks of the date is in a valid format. Following formats 
    20  * are allowed: 
    21  *   * YYYY-MM-DD, YY-MM-DD, MM-DD 
    22  *   * DD.MM.YYYY, DD.MM.YY, DD.MM., DD., DD (seperators '.' or ' '; day and 
    23  *                                            month also single digit possible) 
    24  *   * MM/DD/YYYY, MM/DD (day and month also single digit possible) 
    25  * Omitted values are set to current infos (e.g. ommitting year sets date('Y')). 
    26  *  
    27  * If parameter 'check' is true, the date is checked by checkdate() if its a 
    28  * real existing day. Optional the date can be exported in format YYYY-MM-DD. 
     19 * Arguments:  
     20 *   This can be: 
     21 *    * a single argument which will then be parsed with the formats in the  
     22 *      'formats' parameter. 
     23 *    * multiple arguments with the calendar constants  
     24 *      (AgaviDateDefinitions::MONTH, etc) as key and the argument field as  
     25 *      value. 
     26 *    * multiple arguments and the 'arguments_format' parameter defined. This 
     27 *      will use the string in 'arguments_format' as input string to sprintf and 
     28 *      will use the arguments in the given order as argument to sprintf. 
    2929 *  
    3030 * Parameters: 
    31  *   'check'   check date if the specified day really exists 
     31 *   'check'       check date if the specified day really exists 
     32 *   'formats'     an array of arrays with these keys: 
     33 *     'type'       The type of the string in 'format'. 
     34 *     'format'     The input string dependent on the type. These types are  
     35 *                  allowed: 
     36 *                    format:   The value is a date format string. 
     37 *                    time:     The value is a time specifier (full,...) or null 
     38 *                    date:     The value is a date specifier or null 
     39 *                    datetime: The value is a date specifier or null 
     40 *                    translation_domain: The value will be translated in the  
     41 *                              domain given in the 'translation_domain' key. 
     42 *                    
     43 *     'locale'     The optional locale which will be used for this format. 
     44 *     'translation_domain' Only applicable when the type is translation_domain 
     45 *   'cast_to'     Only useful in combination with the export parameter. 
     46 *                 This can either be a string or an array. If its an string it  
     47 *                 can be one of 'unix' (converts the date to a unix timestamp), 
     48 *                 'string' (converts it to a string using the default format),  
     49 *                 'calendar' (will return the AgaviCalendar object). 
     50 *                 If it's an array it can have these keys: 
     51 *     'type'        The type of the format (format, time, date, datetime) 
     52 *     'format'      see in 'formats' above. 
     53 *   'arguments_format' A string which will be used as the format string for  
     54 *                 sprintf. 
    3255 * 
    3356 * @package    agavi 
    3457 * @subpackage validator 
    3558 * 
    36  * @author     Uwe Mesecke <uwe@mesecke.net> 
     59 * @author     Dominik del Bondio <ddb@bitxtender.com> 
    3760 * @copyright  (c) Authors 
    3861 * @since      0.11.0 
     
    4770   * @return     bool True if the input was a valid date. 
    4871   *  
    49    * @author     Uwe Mesecke <uwe@mesecke.net> 
     72   * @author     Dominik del Bondio <ddb@bitxtender.com> 
    5073   * @since      0.11.0 
    5174   */ 
    5275  protected function validate() 
    5376  { 
    54     $param = $this->getData($this->getArgument()); 
    55     // check YY(YY)-MM-DD 
    56     if(preg_match('/^(?:((?:\d{2})?\d{2})-)?(\d{2})-(\d{2})$/', $param, $matches)) { 
    57       if(count($matches) == 4) { 
    58         $year = $matches[1]; 
    59         $month = $matches[2]; 
    60         $day = $matches[3]; 
    61       } else { 
    62         $year = date('Y'); 
    63         $month = $matches[1]; 
    64         $day = $matches[2]; 
     77    $tm = $this->getContext()->getTranslationManager(); 
     78    $cal = null; 
     79 
     80    $check = $this->getParameter('check', true); 
     81    $locale = $this->hasParameter('locale') ? $tm->getLocaleFromIdentifier($this->getParameter('locale')) : $tm->getCurrentLocale(); 
     82 
     83    if($this->hasMultipleArguments() && !$this->getParameter('arguments_format')) { 
     84      $cal = $tm->createCalendar(); 
     85      $cal->clear(); 
     86      $cal->setLenient(!$check); 
     87      foreach($this->getArguments() as $calField => $field) { 
     88        $param = $this->getData($field); 
     89        if(defined($calField)) { 
     90          $calField = constant($calField); 
     91 
     92          if($calField == AgaviDateDefinitions::MONTH) { 
     93            $param -= 1; 
     94          } 
     95 
     96          $cal->set($calField, (float) $param); 
     97        } 
    6598      } 
    66     // check DD.MM.YY(YY) 
    67     } elseif(preg_match('/^(\d{1,2})(?:[. ](\d{1,2})(?:[. ]((?:\d{2})?\d{2}))?)?[. ]?$/', $param, $matches)) { 
    68       $day = $matches[1]; 
    69       if(isset($matches[2])) { 
    70         $month = $matches[2]; 
    71       } else { 
    72         $month = date('m'); 
    73       } 
    74       if(isset($matches[3])) { 
    75         $year = $matches[3]; 
    76       } else { 
    77         $year = date('Y'); 
    78       } 
    79     // check MM/DD/YY(YY) 
    80     } elseif(preg_match('/^(\d{1,2})\/(\d{1,2})(?:\/((?:\d{2})?\d{2}))?$/', $param, $matches)) { 
    81       $month = $matches[1]; 
    82       $day = $matches[2]; 
    83       if(sizeof($matches) > 3) { 
    84         $year = $matches[3]; 
    85       } else { 
    86         $year = date('Y'); 
     99 
     100      try { 
     101        $cal->getTime(); 
     102      } catch(Exception $e) { 
     103        $this->throwError(); 
     104        return false; 
    87105      } 
    88106    } else { 
    89       $this->throwError(); 
    90       return false; 
     107      if($argFormat = $this->getParameter('arguments_format')) { 
     108        $values = array(); 
     109        foreach($this->getArguments() as $field) { 
     110          $values[] = $this->getData($field); 
     111        } 
     112        $param = vsprintf($argFormat, $values); 
     113      } else { 
     114        $param = $this->getData($this->getArgument()); 
     115      } 
     116 
     117      $matchedFormat = false; 
     118      foreach($this->getParameter('formats', array()) as $item) { 
     119        $itemLocale = empty($item['locale']) ? $locale : $tm->getLocaleFromIdentifier($item['locale']); 
     120        $type = empty($item['type']) ? 'format' : $item['type']; 
     121 
     122        try { 
     123          if($type == 'format') { 
     124            $formatString = $item['format']; 
     125          } elseif($type == 'time' || $type == 'date' || $type == 'datetime') { 
     126            $format = isset($item['format']) ? $item['format'] : null; 
     127            $formatString = AgaviDateFormatter::resolveFormat($format, $itemLocale, $type); 
     128          } elseif($type == 'translation_domain') { 
     129            $td = $item['translation_domain']; 
     130            $formatString = $tm->_($item['format'], $td, $itemLocale); 
     131          } 
     132 
     133          $format = new AgaviDateFormat($formatString); 
     134          $cal = $format->parse($param, $itemLocale, $check); 
     135 
     136          // no exception got thrown so the parsing was successful 
     137          $matchedFormat = true; 
     138          break; 
     139        } catch(Exception $e) { 
     140          // nop 
     141        } 
     142      } 
     143 
     144      if(!$matchedFormat) { 
     145        $this->throwError(); 
     146        return false; 
     147      } 
    91148    } 
    92      
    93     if($year < 70) { 
    94       $year += 2000; 
    95     } elseif($year < 100) { 
    96       $year += 1900; 
     149 
     150    $cal->setLenient(true); 
     151    $value = $cal; 
     152 
     153    if($cast = $this->getParameter('cast_to')) { 
     154      // an array means the user wants it custom formatted 
     155      if(is_array($cast)) { 
     156        $type = empty($cast['type']) ? 'format' : $cast['type']; 
     157        if($type == 'format') { 
     158          $formatString = $cast['format']; 
     159        } elseif($type == 'time' || $type == 'date' || $type == 'datetime') { 
     160          $format = isset($cast['format']) ? $cast['format'] : null; 
     161          $formatString = AgaviDateFormatter::resolveFormat($format, $locale, $type); 
     162        } 
     163 
     164        $format = new AgaviDateFormat($formatString); 
     165        $value = $format->format($cal, $cal->getType(), $locale); 
     166      } else { 
     167        if($cast == 'unix') { 
     168          $value = $cal->getUnixTimestamp(); 
     169        } elseif($cast == 'string') { 
     170          $value = $tm->_d($cal); 
     171        } else { 
     172          $value = $cal; 
     173        } 
     174      } 
    97175    } 
    98      
    99     if($this->getParameter('check') and !checkdate($month, $day, $year)) { 
    100       $this->throwError(); 
    101       return false; 
     176 
     177    if($this->hasParameter('export')) { 
     178      $export = $this->getParameter('export'); 
     179      if(is_string($export)) { 
     180        $this->export($value); 
     181      } elseif(is_array($export)) { 
     182        foreach($export as $calField => $field) { 
     183          if(defined($calField)) { 
     184            $this->export($cal->get(constant($calField)), $field); 
     185          } 
     186        } 
     187      } 
    102188    } 
    103      
    104     $this->export(sprintf('%04d-%02d-%02d', $year, $month, $day)); 
    105      
     189 
    106190    return true; 
    107191  }