diff --git a/doc/82-Changelog.md b/doc/82-Changelog.md index 4d4eb25b..4946c283 100644 --- a/doc/82-Changelog.md +++ b/doc/82-Changelog.md @@ -63,6 +63,8 @@ before switching to a new version. * FEATURE: Preserve _override_servicevars on sync, even when replacing vars (#1307) ### Internals +* FIX: problems related to users working from different time zones have been + fixed (#1270, #1332) * FEATURE: Html/Attribute now allows boolean properties * FEATURE: Html/Attribute allows colons in attribute names (required for SVGs) * FEATURE: Html/Attributes can be prefixed (helps with data-*) diff --git a/library/Director/Db.php b/library/Director/Db.php index d7c18176..bc28e39d 100644 --- a/library/Director/Db.php +++ b/library/Director/Db.php @@ -2,11 +2,14 @@ namespace Icinga\Module\Director; +use DateTime; +use DateTimeZone; use Exception; +use Icinga\Data\ResourceFactory; +use Icinga\Exception\ConfigurationError; use Icinga\Module\Director\Data\Db\DbConnection; use Icinga\Module\Director\Objects\IcingaEndpoint; use Icinga\Module\Director\Objects\IcingaObject; -use Icinga\Exception\ConfigurationError; use RuntimeException; use Zend_Db_Expr; use Zend_Db_Select; @@ -47,6 +50,44 @@ class Db extends DbConnection return $this; } + public static function fromResourceName($name) + { + $connection = new static(ResourceFactory::getResourceConfig($name)); + + if ($connection->isMysql()) { + $connection->setClientTimezoneForMysql(); + } elseif ($connection->isPgsql()) { + $connection->setClientTimezoneForPgsql(); + } + + return $connection; + } + + protected function getTimezoneOffset() + { + $tz = new DateTimeZone(date_default_timezone_get()); + $offset = $tz->getOffset(new DateTime()); + $prefix = $offset >= 0 ? '+' : '-'; + $offset = abs($offset); + + $hours = (int) floor($offset / 3600); + $minutes = (int) floor(($offset % 3600) / 60); + + return sprintf('%s%d:%02d', $prefix, $hours, $minutes); + } + + protected function setClientTimezoneForMysql() + { + $db = $this->getDbAdapter(); + $db->query($db->quoteInto('SET time_zone = ?', $this->getTimezoneOffset())); + } + + protected function setClientTimezoneForPgsql() + { + $db = $this->getDbAdapter(); + $db->query($db->quoteInto('SET TIME ZONE INTERVAL ? HOUR TO MINUTE', $this->getTimezoneOffset())); + } + public function countActivitiesSinceLastDeployedConfig(IcingaObject $object = null) { $db = $this->db(); @@ -226,6 +267,7 @@ class Db extends DbConnection { $sql = 'SELECT id, object_type, object_name, action_name,' . ' old_properties, new_properties, author, change_time,' + . ' UNIX_TIMESTAMP(change_time) AS change_time_ts,' . ' %s AS checksum, %s AS parent_checksum' . ' FROM director_activity_log WHERE id = %d'; @@ -270,6 +312,7 @@ class Db extends DbConnection $sql = 'SELECT id, object_type, object_name, action_name,' . ' old_properties, new_properties, author, change_time,' + . ' UNIX_TIMESTAMP(change_time) AS change_time_ts,' . ' %s AS checksum, %s AS parent_checksum' . ' FROM director_activity_log WHERE checksum = ?'; diff --git a/library/Director/Objects/DirectorActivityLog.php b/library/Director/Objects/DirectorActivityLog.php index 57b3b625..74f45b62 100644 --- a/library/Director/Objects/DirectorActivityLog.php +++ b/library/Director/Objects/DirectorActivityLog.php @@ -100,7 +100,7 @@ class DirectorActivityLog extends DbObject 'author' => static::username(), 'object_type' => $type, 'new_properties' => $newProps, - 'change_time' => date('Y-m-d H:i:s'), // TODO -> postgres! + 'change_time' => date('Y-m-d H:i:s'), 'parent_checksum' => $db->getLastActivityChecksum() ); @@ -131,7 +131,7 @@ class DirectorActivityLog extends DbObject 'object_type' => $type, 'old_properties' => $oldProps, 'new_properties' => $newProps, - 'change_time' => date('Y-m-d H:i:s'), // TODO -> postgres! + 'change_time' => date('Y-m-d H:i:s'), 'parent_checksum' => $db->getLastActivityChecksum() ); @@ -161,7 +161,7 @@ class DirectorActivityLog extends DbObject 'author' => static::username(), 'object_type' => $type, 'old_properties' => $oldProps, - 'change_time' => date('Y-m-d H:i:s'), // TODO -> postgres! + 'change_time' => date('Y-m-d H:i:s'), 'parent_checksum' => $db->getLastActivityChecksum() ); diff --git a/library/Director/Web/Table/DeploymentLogTable.php b/library/Director/Web/Table/DeploymentLogTable.php index ed3508f6..74bd7d0b 100644 --- a/library/Director/Web/Table/DeploymentLogTable.php +++ b/library/Director/Web/Table/DeploymentLogTable.php @@ -4,6 +4,7 @@ namespace Icinga\Module\Director\Web\Table; use dipl\Html\Link; use dipl\Web\Table\ZfQueryBasedTable; +use Icinga\Date\DateFormatter; class DeploymentLogTable extends ZfQueryBasedTable { @@ -33,7 +34,7 @@ class DeploymentLogTable extends ZfQueryBasedTable 'director/deployment', ['id' => $row->id] )), - $this::td(strftime('%H:%M:%S', $row->start_time)) + $this::td(DateFormatter::formatTime($row->start_time)) ])->addAttributes(['class' => $this->getMyRowClasses($row)]); return $tr; diff --git a/library/Director/Web/Widget/ActivityLogInfo.php b/library/Director/Web/Widget/ActivityLogInfo.php index 01ddc057..7471af2d 100644 --- a/library/Director/Web/Widget/ActivityLogInfo.php +++ b/library/Director/Web/Widget/ActivityLogInfo.php @@ -4,6 +4,7 @@ namespace Icinga\Module\Director\Web\Widget; use dipl\Html\HtmlDocument; use dipl\Html\HtmlElement; +use Icinga\Date\DateFormatter; use Icinga\Exception\ProgrammingError; use Icinga\Module\Director\ConfigDiff; use Icinga\Module\Director\Db; @@ -380,7 +381,9 @@ class ActivityLogInfo extends HtmlDocument $table = new NameValueTable(); $table->addNameValuePairs([ $this->translate('Author') => $entry->author, - $this->translate('Date') => $entry->change_time, + $this->translate('Date') => DateFormatter::formatDateTime( + $entry->change_time_ts + ), ]); if (null === $this->name) {