Skip to content

Commit

Permalink
fix date/time attributes input processing (#719)
Browse files Browse the repository at this point in the history
Date/time attributes processing was inconsistent in that output of such
attributes was done using date() function and a configurable format
string, but input was done using strtotime() and no format string. For
some format strings this lead to parts (year/month/day) of the date
swapped around on each form submit or the update declined.

This change addresses the problem through switching to strftime() for
output and strptime() for input. This implies a different format string
syntax, but both functions are available in early releases of PHP5, as
opposed to DateTime::createFromFormat(), which uses the same format as
date() but requires PHP 5.3.

* datetimestrFromTimestamp(): new helper function
* renderEditObjectForm(): update to use above
* formatAttributeValue(): idem
* renderExpirations(): idem

* timestampFromDatetimestr(): new helper function
* assertDateArg(): rewrite using above
* updateObjectAttributes(): update to use above

* upgrade.php: overwrite DATETIME_FORMAT value
* install.php: update DATETIME_FORMAT default value
* resetUIConfig(): idem
  • Loading branch information
infrastation committed Mar 2, 2013
1 parent 3be783f commit 17c1470
Show file tree
Hide file tree
Showing 7 changed files with 58 additions and 19 deletions.
1 change: 1 addition & 0 deletions ChangeLog
Expand Up @@ -13,6 +13,7 @@
bugfix: sometimes racks could not be deleted (#757)
bugfix: references to tags and files remained when a location was deleted
(#747)
bugfix: date/time attributes handling code had a bug (#719)
update: vlan search results now include binded IP networks
update: make scaled rack thumb images sharp again
update: Cisco IOS 15.0 support
Expand Down
5 changes: 5 additions & 0 deletions README
Expand Up @@ -116,6 +116,11 @@ were renamed to meet official Cisco classification:
C2960-24 => C2960-24-S
C2960G-24PC => C2960-24PC-L

The DATETIME_FORMAT configuration option used in setting date and time output
format now uses a different [1] syntax. During upgrade the option is reset to
the default value, which is now %Y-%m-%d (YYYY-MM-DD) per ISO 8601.

[1] http://php.net/manual/en/function.strftime.php

*** Upgrading to 0.20.1 ***

Expand Down
42 changes: 35 additions & 7 deletions wwwroot/inc/functions.php
Expand Up @@ -169,17 +169,22 @@ function isInteger ($arg, $allow_zero = FALSE)
return TRUE;
}

// make sure the arg is a parsable date
# Make sure the arg is a parsable date, return its UNIX timestamp equivalent
# (or empty string for empty input, when allowed).
function assertDateArg ($argname, $ok_if_empty = FALSE)
{
$arg = assertStringArg ($argname, $ok_if_empty);
// different versions of PHP return false/-1
if ($arg != '' and strtotime ($arg) <= 0)
throw new InvalidRequestArgException($argname, $arg, 'parameter is not a parsable date');
return $arg;
if ('' == $arg = assertStringArg ($argname, $ok_if_empty))
return '';
try
{
return timestampFromDatetimestr ($arg);
}
catch (InvalidArgException $e)
{
throw convertToIRAE ($e, $argname);
}
}


// This function assures that specified argument was passed
// and is a non-empty string.
function assertStringArg ($argname, $ok_if_empty = FALSE)
Expand Down Expand Up @@ -5889,4 +5894,27 @@ function convertToIRAE ($iae, $override_argname = NULL)
return new InvalidRequestArgException ($reported_argname, $reported_argvalue, $iae->getReason());
}

# produce a textual date/time from a given UNIX timestamp
function datetimestrFromTimestamp ($ts)
{
return strftime (getConfigVar ('DATETIME_FORMAT'), $ts);
}

# vice versa
function timestampFromDatetimestr ($s)
{
$format = getConfigVar ('DATETIME_FORMAT');
if (FALSE === $tmp = strptime ($s, $format))
throw new InvalidArgException ('s', $s, "not a date in format '${format}'");
return mktime
(
$tmp['tm_hour'], # 0~23
$tmp['tm_min'], # 0~59
$tmp['tm_sec'], # 0~59
$tmp['tm_mon'] + 1, # 0~11 -> 1~12
$tmp['tm_mday'], # 1~31
$tmp['tm_year'] + 1900 # 0~n -> 1900~n
);
}

?>
2 changes: 1 addition & 1 deletion wwwroot/inc/install.php
Expand Up @@ -1625,7 +1625,7 @@ function get_pseudo_file ($name)
('MUNIN_LISTSRC','false','string','yes','no','no','List of object with Munin graphs'),
('VIRTUAL_OBJ_LISTSRC','1504,1505,1506,1507','string','no','no','no','List source: virtual objects'),
('DATETIME_ZONE','UTC','string','yes','no','yes','Timezone to use for displaying/calculating dates'),
('DATETIME_FORMAT','m/d/Y','string','no','no','yes','PHP date() format to use for date output'),
('DATETIME_FORMAT','%Y-%m-%d','string','no','no','yes','PHP date() format to use for date output'),
('SEARCH_DOMAINS','','string','yes','no','yes','DNS domain list (comma-separated) to search in FQDN attributes'),
('8021Q_EXTSYNC_LISTSRC','false','string','yes','no','no','List source: objects with extended 802.1Q sync'),
('8021Q_MULTILINK_LISTSRC','false','string','yes','no','no','List source: IPv4/IPv6 networks allowing multiple VLANs from same domain'),
Expand Down
6 changes: 3 additions & 3 deletions wwwroot/inc/interface.php
Expand Up @@ -872,7 +872,7 @@ function renderEditObjectForm()
printNiftySelect ($chapter, array ('name' => "${i}_value"), $record['key']);
break;
case 'date':
$date_value = $record['value'] ? date(getConfigVar('DATETIME_FORMAT'), $record['value']) : '';
$date_value = $record['value'] ? datetimestrFromTimestamp ($record['value']) : '';
echo "<input type=text name=${i}_value value='${date_value}'>";
break;
}
Expand Down Expand Up @@ -8114,7 +8114,7 @@ function formatIfTypeVariants ($variants, $select_name)
function formatAttributeValue ($record)
{
if ('date' == $record['type'])
return date(getConfigVar('DATETIME_FORMAT'), $record['value']);
return datetimestrFromTimestamp ($record['value']);

if (! isset ($record['key'])) // if record is a dictionary value, generate href with autotag in cfe
{
Expand Down Expand Up @@ -8602,7 +8602,7 @@ function renderExpirations ()
echo "<th align=center>Asset Tag</th><th align=center>Date Warranty <br> Expires</th></tr>\n";
foreach ($result as $row)
{
$date_value = date(getConfigVar('DATETIME_FORMAT'), $row['uint_value']);
$date_value = datetimestrFromTimestamp ($row['uint_value']);

$object = spotEntity ('object', $row['object_id']);
echo '<tr class=' . $section['class'] . $order . ' valign=top>';
Expand Down
14 changes: 6 additions & 8 deletions wwwroot/inc/ophandlers.php
Expand Up @@ -1196,12 +1196,6 @@ function updateObjectAttributes ($object_id)
if ($type_id == 1560 and ($attr_id == 27 or $attr_id == 29))
continue;

if ('date' == $oldvalues[$attr_id]['type']) {
assertDateArg ("${i}_value", TRUE);
if ($value != '')
$value = strtotime ($value);
}

// Delete attribute and move on, when the field is empty or if the field
// type is a dictionary and it is the "--NOT SET--" value of 0.
if ($value == '' || ($oldvalues[$attr_id]['type'] == 'dict' && $value == 0))
Expand All @@ -1215,7 +1209,11 @@ function updateObjectAttributes ($object_id)

// The value could be uint/float, but we don't know ATM. Let SQL
// server check this and complain.
assertStringArg ("${i}_value");
if ('date' == $oldvalues[$attr_id]['type'])
$value = assertDateArg ("${i}_value");
else
assertStringArg ("${i}_value");

switch ($oldvalues[$attr_id]['type'])
{
case 'uint':
Expand Down Expand Up @@ -1474,7 +1472,7 @@ function resetUIConfig()
setConfigVar ('MUNIN_LISTSRC', 'false');
setConfigVar ('VIRTUAL_OBJ_LISTSRC', '1504,1505,1506,1507');
setConfigVar ('DATETIME_ZONE', 'UTC');
setConfigVar ('DATETIME_FORMAT', 'm/d/Y');
setConfigVar ('DATETIME_FORMAT', '%Y-%m-%d');
setConfigVar ('SEARCH_DOMAINS', '');
setConfigVar ('8021Q_EXTSYNC_LISTSRC', 'false');
setConfigVar ('8021Q_MULTILINK_LISTSRC', 'false');
Expand Down
7 changes: 7 additions & 0 deletions wwwroot/inc/upgrade.php
Expand Up @@ -177,6 +177,12 @@
2960G-8TC => 2960G-8TC-L
C2960-24 => C2960-24-S
C2960G-24PC => C2960-24PC-L
The DATETIME_FORMAT configuration option used in setting date and time output
format now uses a different [1] syntax. During upgrade the option is reset to
the default value, which is now %Y-%m-%d (YYYY-MM-DD) per ISO 8601.
[1] http://php.net/manual/en/function.strftime.php
ENDOFTEXT
,
);
Expand Down Expand Up @@ -1636,6 +1642,7 @@ function getUpgradeBatch ($batchid)
$query[] = "UPDATE `Config` SET varvalue = CONCAT(varvalue, ' or {\$typeid_965}') WHERE varname = 'IPV4OBJ_LISTSRC'";
$query[] = "UPDATE AttributeValue INNER JOIN AttributeMap USING (attr_id) SET AttributeValue.uint_value = 1572 WHERE chapter_id = 12 AND uint_value = 162";
$query[] = "UPDATE AttributeValue INNER JOIN AttributeMap USING (attr_id) SET AttributeValue.uint_value = 1710 WHERE chapter_id = 12 AND uint_value = 163";
$query[] = "UPDATE Config SET varvalue = '%Y-%m-%d' WHERE varname = 'DATETIME_FORMAT'";
$query[] = "UPDATE Config SET varvalue = '0.20.4' WHERE varname = 'DB_VERSION'";
break;
case 'dictionary':
Expand Down

0 comments on commit 17c1470

Please sign in to comment.