Index: branches/RC/core/kernel/utility/formatters/date_formatter.php =================================================================== diff -u -N --- branches/RC/core/kernel/utility/formatters/date_formatter.php (revision 11892) +++ branches/RC/core/kernel/utility/formatters/date_formatter.php (revision 0) @@ -1,446 +0,0 @@ -language =& $this->Application->recallObject('lang.current'); - } - - /** - * Sets mixed format (date + time) for field if not set directly - * - * @param Array $field_options options of field - * @param Array $format separate formats for date & time - * @param string $type destination key in field_options to store mixed format - */ - function SetMixedFormat(&$field_options, &$format, $type) - { - if (!isset($field_options[$type])) { - // default value is date+sepatator+time - $field_options[$type] = '_regional_DateTimeFormat'; - } - - if ($field_options[$type] == '_regional_DateTimeFormat') { - $field_options[$type] = $format['date'].$field_options['date_time_separator'].$format['time']; - } - else if(preg_match('/_regional_(.*)/', $field_options[$type], $regs)) { - $field_options[$type] = $this->language->GetDBField($regs[1]); - } - $format['mixed'] = $field_options[$type]; - } - - /** - * Returns separate formats for date,time,combined for input & display formats - * - * @param Array $field_options options of field - * @param string $type type of requested information = {mixed,date,time} - * @return Array display & input formats - */ - function GetSeparateFormats(&$field_options, $type) - { - if ($type == 'mixed') { - if (!isset($field_options['date_time_separator'])) $field_options['date_time_separator'] = ' '; - - $display_format = Array (); - $input_format = Array (); - - list ($display_format['date'], $input_format['date']) = $this->GetSeparateFormats($field_options, 'date'); - list ($display_format['time'], $input_format['time']) = $this->GetSeparateFormats($field_options, 'time'); - - $this->SetMixedFormat($field_options, $display_format, 'format'); - $this->SetMixedFormat($field_options, $input_format, 'input_format'); - - return Array ($display_format, $input_format); - } - else { - // 1. set display format - if (isset($field_options[$type.'_format'])) { - $format = $field_options[$type.'_format']; - } - else { - $format = $this->language->GetDBField(ucfirst($type).'Format'); - } - - // 2. set input format - if (isset($field_options['input_'.$type.'_format'])) { - $input_format = $field_options['input_'.$type.'_format']; - } - else { - $input_format = $this->language->GetDBField('Input'.ucfirst($type).'Format'); - } - - return Array ($format, $input_format); - } - } - - function PrepareOptions($field_name, &$field_options, &$object) - { - list ($display_format, $input_format) = $this->GetSeparateFormats($field_options, 'mixed'); - - $field_options['sub_fields'] = Array('date' => $field_name.'_date', 'time' => $field_name.'_time'); - if (!isset($field_options['use_timezone'])) { - // apply timezone from server - $field_options['use_timezone'] = true; - } - - $add_fields = Array(); - - // 1. add DATE virtual field - $opts = Array('master_field' => $field_name, 'formatter' => 'kDateFormatter', 'format' => $display_format['date'], 'input_format' => $input_format['date']); - - $copy_options = Array ('default', 'required', 'use_timezone', 'error_msgs'); - foreach ($copy_options as $copy_option) { - if (array_key_exists($copy_option, $field_options) ) { - $opts[$copy_option] = $field_options[$copy_option]; - } - } - - $add_fields[$field_name.'_date'] = $opts; - - // 2. add TIME virtual field - $opts['format'] = $display_format['time']; - $opts['input_format'] = $input_format['time']; - $add_fields[$field_name.'_time'] = $opts; - - $filter_type = getArrayValue($field_options, 'filter_type'); - if($filter_type == 'range') - { - $opts['format'] = $field_options['format']; - $add_fields[$field_name.'_rangefrom'] = $opts; - $add_fields[$field_name.'_rangeto'] = $opts; - } - - if ( !isset($object->VirtualFields[$field_name]) ) { - // adding caluclated field to format date directly in the query - if ( !isset($object->CalculatedFields) || !is_array($object->CalculatedFields) ) { - $object->CalculatedFields = Array(); - } -// $object->CalculatedFields[$field_name.'_formatted'] = 'FROM_UNIXTIME('.'`%1$s`.'.$field_name.' + '.$this->Application->TimeZoneAdjustment().', \''.$this->SQLFormat($field_options['format']).'\')'; - $object->CalculatedFields[$field_name.'_date'] = '%1$s.'.$field_name; - $object->CalculatedFields[$field_name.'_time'] = '%1$s.'.$field_name; -// $opts['format'] = $field_options['format']; -// $opts['required'] = 0; -// unset($opts['master_field']); -// $add_fields[$field_name.'_formatted'] = $opts; - } - - $add_fields = array_merge_recursive2($add_fields, $object->VirtualFields); - $object->setVirtualFields($add_fields); - } - - function UpdateSubFields($field, $value, &$options, &$object) - { - if ( $sub_fields = getArrayValue($options, 'sub_fields') ) { - if( isset($value) && $value ) - { - $object->SetDBField( $sub_fields['date'], $value ); - $object->SetDBField( $sub_fields['time'], $value ); - } - } - } - - function UpdateMasterFields($field, $value, &$options, &$object) - { - // when in master field - set own value from sub_fields - if ( $sub_fields = getArrayValue($options, 'sub_fields') ) { - // if date is not empty, but time is empty - set time to 0, otherwise master field fomratter will complain - // when we have only date field on form, we need time hidden field always empty, don't ask me why! - if ( $object->GetDBField($sub_fields['date']) != '' && $object->GetDBField($sub_fields['time']) == '' ) { - $empty_time = getArrayValue($options,'empty_time'); - if($empty_time === false) $empty_time = adodb_mktime(0,0,0); - $object->SetDBField($sub_fields['time'], $empty_time); - } - - $input_format['date'] = $object->Fields[ $sub_fields['date'] ]['input_format']; - $input_format['time'] = $object->Fields[ $sub_fields['time'] ]['input_format']; - - $object->SetField($field, $object->GetField($sub_fields['date'], $input_format['date']).$options['date_time_separator'].$object->GetField($sub_fields['time'], $input_format['time'])); - } - // when in one of sub_fields - call update for master_field to update its value from sub_fields [are you following ? :) ] - elseif ($master_field = getArrayValue($options, 'master_field') ) { - $opt = $object->GetFieldOptions($master_field); - $this->UpdateMasterFields($master_field, null, $opt, $object); - } - } - -//function Format($value, $options, &$errors) - function Format($value, $field_name, &$object, $format=null) - { - if ( is_null($value) ) return ''; - if ( !is_numeric($value) ) { - return $value; // for leaving badly formatted date on the form - } - settype($value, 'int'); - if ( !is_int($value) ) { - return $value; - } - - $options = $object->GetFieldOptions($field_name); - if ( isset($format) ) { - $options['format'] = $format; - } - - if (preg_match('/_regional_(.*)/', $options['format'], $regs)) { - // when such type of format is given directly to kDBBase::GetField - $options['format'] = $this->language->GetDBField($regs[1]); - } - - if (!$options['use_timezone']) { - return adodb_gmdate($options['format'], $value); - } - - return adodb_date($options['format'], $value + $this->Application->TimeZoneAdjustment()); - } - - function HumanFormat($format) - { - $patterns = Array('/m/', - '/n/', - '/d/', - '/j/', - '/y/', - '/Y/', - '/h|H/', - '/g|G/', - '/i/', - '/s/', - '/a|A/'); - $replace = Array( 'mm', - 'm', - 'dd', - 'd', - 'yy', - 'yyyy', - 'hh', - 'h', - 'mm', - 'ss', - 'AM'); - $res = preg_replace($patterns, $replace, $format); - return $res; - } - - function SQLFormat($format) - { - $mapping = Array( - '/%/' => '%%', - '/(? '%p', // Lowercase Ante meridiem and Post meridiem => MySQL provides only uppercase - '/(? '%p', // Uppercase Ante meridiem and Post meridiem - '/(? '%d', // Day of the month, 2 digits with leading zeros - '/(? '%a', // A textual representation of a day, three letters - '/(? '%M', // A full textual representation of a month, such as January or March - '/(? '%l', // 12-hour format of an hour without leading zeros - '/(? '%k', // 24-hour format of an hour without leading zeros - '/(? '%h', // 12-hour format of an hour with leading zeros - '/(? '%H', // 24-hour format of an hour with leading zeros - '/(? '%i', // Minutes with leading zeros - '/(? 'N/A', // Whether or not the date is in daylights savings time - - '/(? 'N/A', // English ordinal suffix for the day of the month, 2 characters, see below - '/jS/' => '%D', // MySQL can't return separate suffix, but could return date with suffix - '/(? '%e', // Day of the month without leading zeros - '/(? '%W', // A full textual representation of the day of the week - '/(? 'N/A', // Whether it's a leap year - '/(? '%m', // Numeric representation of a month, with leading zeros - '/(? '%b', // A short textual representation of a month, three letters - '/(? '%c', // Numeric representation of a month, without leading zeros - '/(? 'N/A', // Difference to Greenwich time (GMT) in hours - '/(? 'N/A', // RFC 2822 formatted date - '/(? '%s', // Seconds, with leading zeros - // S and jS moved before j - see above - '/(? 'N/A', // Number of days in the given month - '/(? 'N/A', // Timezone setting of this machine - '/(? 'N/A', // Seconds since the Unix Epoch (January 1 1970 00:00:00 GMT) - '/(? '%w', // Numeric representation of the day of the week - '/(? '%v', // ISO-8601 week number of year, weeks starting on Monday (added in PHP 4.1.0) - '/(? '%Y', // A full numeric representation of a year, 4 digits - '/(? '%y', // A two digit representation of a year - '/(? 'N/A', // The day of the year (starting from 0) => MySQL starts from 1 - '/(? 'N/A', // Timezone offset in seconds. The offset for timezones west of UTC is always negative, and for those east of UTC is always positive. - ); - - $patterns = array_keys($mapping); - $replacements = array_values($mapping); - - $res = preg_replace($patterns, $replacements, $format); - return $res; - } - - /** - * Converts formatted date+time to timestamp and validates format - * - * @param mixed $value - * @param string $field_name - * @param kDBItem $object - * @return string - */ - function Parse($value, $field_name, &$object) - { - $options = $object->GetFieldOptions($field_name); - - $dt_separator = getArrayValue($options,'date_time_separator'); - if($dt_separator) $value = trim($value, $dt_separator); - if($value == '') return NULL; - //return strtotime($value); - - $format = $options['input_format']; - if ($dt_separator) $format = trim($format, $dt_separator); - - $error_field = isset($this->Fields[$field_name]['error_field']) ? $this->Fields[$field_name]['error_field'] : $field_name; - $object->FieldErrors[$error_field]['params'] = Array( $this->HumanFormat($format), adodb_date($format) ); - $object->FieldErrors[$error_field]['value'] = $value; - - $hour = 0; - $minute = 0; - $second = 0; - $month = 1; - $day = 1; - $year = 1970; - - $patterns['n'] = '([0-9]{1,2})'; - $patterns['m'] = '([0-9]{1,2})'; - $patterns['d'] = '([0-9]{1,2})'; - $patterns['j'] = '([0-9]{1,2})'; - $patterns['Y'] = '([0-9]{4})'; - $patterns['y'] = '([0-9]{2})'; - $patterns['G'] = '([0-9]{1,2})'; - $patterns['g'] = '([0-9]{1,2})'; - $patterns['H'] = '([0-9]{2})'; - $patterns['h'] = '([0-9]{2})'; - $patterns['i'] = '([0-9]{2})'; - $patterns['s'] = '([0-9]{2})'; - $patterns['a'] = '(am|pm)'; - $patterns['A'] = '(AM|PM)'; - - $holders_mask = eregi_replace('[a-zA-Z]{1}', '([a-zA-Z]{1})', $format); - if (!ereg($holders_mask, $format, $holders)) { - $object->SetError($field_name, 'bad_date_format'); - return $value; - } - - $values_mask = '/^'.str_replace('/','\/',$format).'$/'; - foreach ($patterns as $key => $val) { - $values_mask = ereg_replace($key, $val, $values_mask); - } - // echo " values_mask : $values_mask
"; - - if (!preg_match($values_mask, $value, $values)) { - $object->SetError($field_name, 'bad_date_format'); - return $value; - } - - for ($i = 1; $i < count($holders); $i++) { - switch ($holders[$i]) { - case 'n': - case 'm': - $month = $values[$i]; - $month = ereg_replace("^0{1}", '', $month); - break; - case 'd': - $day = $values[$i]; - $day = ereg_replace("^0{1}", '', $day); - break; - case 'Y': - $year = $values[$i]; - break; - case 'y': - $year = $values[$i] >= 70 ? 1900 + $values[$i] : 2000 + $values[$i]; - break; - case 'H': - case 'h': - case 'G': - case 'g': - $hour = $values[$i]; - $hour = ereg_replace("^0{1}", '', $hour); - break; - case 'i': - $minute = $values[$i]; - $minute = ereg_replace("^0{1}", '', $minute); - break; - case 's': - $second = $values[$i]; - $second = ereg_replace("^0{1}", '', $second); - break; - case 'a': - case 'A': - if ($hour <= 12) { // if AM/PM used with 24-hour - could happen :) - if ($values[$i] == 'pm' || $values[$i] == 'PM') { - $hour += 12; - if ($hour == 24) $hour = 12; - } - elseif ($values[$i] == 'am' || $values[$i] == 'AM') { - if ($hour == 12) $hour = 0; - } - } - break; - } - } - - //echo "day: $day, month: $month, year: $year, hour: $hour, minute: $minute
"; - - /*if (!($year >= 1970 && $year <= 2037)) { - $object->SetError($field_name, 'bad_date_format'); - return $value; - }*/ - - if (!($month >= 1 && $month <= 12)) { - $object->SetError($field_name, 'bad_date_format'); - return $value; - } - - $months_days = Array ( 1 => 31,2 => 28, 3 => 31, 4 => 30,5 => 31,6 => 30, 7 => 31, 8 => 31,9 => 30,10 => 31,11 => 30,12 => 31); - if ($year % 4 == 0) $months_days[2] = 29; - - if (!($day >=1 && $day <= $months_days[$month])) { - $object->SetError($field_name, 'bad_date_format'); - return $value; - } - - if (!($hour >=0 && $hour <= 23)) { - $object->SetError($field_name, 'bad_date_format'); - return $value; - } - - if (!($minute >=0 && $minute <= 59)) { - $object->SetError($field_name, 'bad_date_format'); - return $value; - } - - if (!($second >=0 && $second <= 59)) { - $object->SetError($field_name, 'bad_date_format'); - return $value; - } - - if (!$options['use_timezone']) { - return adodb_gmmktime($hour, $minute, $second, $month, $day, $year); - } - - return adodb_mktime($hour, $minute, $second, $month, $day, $year) - $this->Application->TimeZoneAdjustment(); - } - - function GetSample($field, &$options, &$object) - { - return $this->Format( adodb_mktime(), $field, $object, $options['input_format']); - } -} \ No newline at end of file