Merge branch 'master' into feature/user-and-group-management-8826

This commit is contained in:
Johannes Meyer 2015-05-26 09:28:35 +02:00
commit ec556edc65
44 changed files with 619 additions and 1043 deletions

View File

@ -113,16 +113,17 @@ class LdapResourceForm extends Form
'text',
'bind_dn',
array(
'required' => true,
'label' => $this->translate('Bind DN'),
'description' => $this->translate('The user dn to use for querying the ldap server')
'description' => $this->translate(
'The user dn to use for querying the ldap server. Leave the dn and password empty for attempting'
. ' an anonymous bind'
)
)
);
$this->addElement(
'password',
'bind_pw',
array(
'required' => true,
'renderPassword' => true,
'label' => $this->translate('Bind Password'),
'description' => $this->translate('The password to use for querying the ldap server')

View File

@ -1,133 +0,0 @@
<?php
/* Icinga Web 2 | (c) 2013-2015 Icinga Development Team | GPLv2+ */
use Icinga\Application\Icinga;
use Icinga\Util\DateTimeFactory;
/**
* Helper to format date and time. Utilizes DateTimeFactory to ensure time zone awareness
*
* @see DateTimeFactory::create()
*/
class Zend_View_Helper_DateFormat extends Zend_View_Helper_Abstract
{
/**
* Current request
*
* @var Zend_Controller_Request_Abstract
*/
protected $request;
/**
* Constructor
*
* Retrieves the request from the application's front controller if not given.
*
* @param Zend_Controller_Request_Abstract $request The request to use
*/
public function __construct(Zend_Controller_Request_Abstract $request = null)
{
if ($request === null) {
$this->request = Icinga::app()->getFrontController()->getRequest();
} else {
$this->request = $request;
}
}
/**
* Helper entry point
*
* @return $this
*/
public function dateFormat()
{
return $this;
}
/**
* Return date formatted according to given format respecting the user's timezone
*
* @param int $timestamp
* @param string $format
*
* @return string
*/
public function format($timestamp, $format)
{
$dt = DateTimeFactory::create();
if (DateTimeFactory::isUnixTimestamp($timestamp)) {
$dt->setTimestamp($timestamp);
} else {
return $timestamp;
}
return $dt->format($format);
}
/**
* Format date according to user's format
*
* @param int $timestamp A unix timestamp
*
* @return string The formatted date string
*/
public function formatDate($timestamp)
{
return $this->format($timestamp, $this->getDateFormat());
}
/**
* Format time according to user's format
*
* @param int $timestamp A unix timestamp
*
* @return string The formatted time string
*/
public function formatTime($timestamp)
{
return $this->format($timestamp, $this->getTimeFormat());
}
/**
* Format datetime according to user's format
*
* @param int $timestamp A unix timestamp
* @return string The formatted datetime string
*/
public function formatDateTime($timestamp)
{
return $this->format($timestamp, $this->getDateTimeFormat());
}
/**
* Retrieve the user's date format string
*
* @return string
*/
public function getDateFormat()
{
// TODO(mh): Missing localized format (#6077)
return 'd/m/Y';
}
/**
* Retrieve the user's time format string
*
* @return string
*/
public function getTimeFormat()
{
// TODO(mh): Missing localized format (#6077)
return 'g:i A';
}
/**
* Retrieve the user's datetime format string
*
* @return string
*/
public function getDateTimeFormat()
{
return $this->getDateFormat() . ' ' . $this->getTimeFormat();
}
}

View File

@ -32,7 +32,7 @@ If your web server is not configured for authentication though the `autologin` s
### <a id="authentication-configuration-ad-or-ldap-authentication"></a> Active Directory or LDAP Authentication
If you want to authenticate against Active Directory or LDAP, you have to define a
[LDAP resource](#resources-configuration-ldap) which will be referenced as data source for the Active Directory
[LDAP resource](resources.md#resources-configuration-ldap) which will be referenced as data source for the Active Directory
or LDAP configuration method.
#### <a id="authentication-configuration-ldap-authentication"></a> LDAP
@ -40,7 +40,7 @@ or LDAP configuration method.
Directive | Description
------------------------|------------
**backend** | `ldap`
**resource** | The name of the LDAP resource defined in [resources.ini](#resources).
**resource** | The name of the LDAP resource defined in [resources.ini](resources.md#resources).
**user_class** | LDAP user class.
**user_name_attribute** | LDAP attribute which contains the username.
@ -63,7 +63,7 @@ with Icinga Web 2 (e.g. an alias) no matter what the primary user id might actua
Directive | Description
------------------------|------------
**backend** | `ad`
**resource** | The name of the LDAP resource defined in [resources.ini](#resources).
**resource** | The name of the LDAP resource defined in [resources.ini](resources.md#resources).
**Example:**
@ -76,19 +76,19 @@ resource = my_ad
### <a id="authentication-configuration-db-authentication"></a> Database Authentication
If you want to authenticate against a MySQL or a PostgreSQL database, you have to define a
[database resource](#resources-configuration-database) which will be referenced as data source for the database
[database resource](resources.md#resources-configuration-database) which will be referenced as data source for the database
authentication method.
Directive | Description
------------------------|------------
**backend** | `db`
**resource** | The name of the database resource defined in [resources.ini](#resources).
**resource** | The name of the database resource defined in [resources.ini](resources.md#resources).
**Example:**
```
[auth_ad]
backend = ad
[auth_db]
backend = db
resource = icingaweb-mysql
```
@ -99,7 +99,7 @@ For authenticating against a database, you have to import one of the following d
* **etc/schema/preferences.mysql.sql** (for **MySQL** database)
* **etc/schema/preferences.pgsql.sql** (for **PostgreSQL** databases)
After that you have to define the [database resource](#resources-configuration-database).
After that you have to define the [database resource](resources.md#resources-configuration-database).
**Manually Creating Users**

View File

@ -27,13 +27,13 @@ type = ini
### <a id="preferences-configuration-db"></a> Store Preferences in a Database
In order to be more flexible in distributed setups you can store preferences in a MySQL or in a PostgreSQL database.
For storing preferences in a database, you have to define a [database resource](#resources-configuration-database)
For storing preferences in a database, you have to define a [database resource](resources.md#resources-configuration-database)
which will be referenced as resource for the preferences storage.
Directive | Description
------------------------|------------
**type** | `db`
**resource** | The name of the database resource defined in [resources.ini](resources).
**resource** | The name of the database resource defined in [resources.ini](resources.md#resources).
**Example:**
@ -50,4 +50,4 @@ For storing preferences in a database, you have to import one of the following d
* **etc/schema/preferences.mysql.sql** (for **MySQL** database)
* **etc/schema/preferences.pgsql.sql** (for **PostgreSQL** databases)
After that you have to define the [database resource](#resources-configuration-database).
After that you have to define the [database resource](resources.md#resources-configuration-database).

View File

@ -12,7 +12,6 @@ use Icinga\Data\ResourceFactory;
use Icinga\Exception\ConfigurationError;
use Icinga\Exception\NotReadableError;
use Icinga\Application\Logger;
use Icinga\Util\DateTimeFactory;
use Icinga\Util\Translator;
use Icinga\Exception\IcingaException;
@ -568,7 +567,6 @@ abstract class ApplicationBootstrap
date_default_timezone_set($timezone);
}
}
DateTimeFactory::setConfig(array('timezone' => $timezone));
return $this;
}

View File

@ -4,7 +4,7 @@
namespace Icinga\Chart\Unit;
use Icinga\Util\DateTimeFactory;
use DateTime;
/**
* Calendar Axis Unit that transforms timestamps into user-readable values
@ -81,7 +81,7 @@ class CalendarUnit extends LinearUnit
*/
private function calculateLabels($unit)
{
$fac = DateTimeFactory::create();
$fac = new DateTime();
$duration = $this->getMax() - $this->getMin();

View File

@ -164,10 +164,12 @@ class DbQuery extends SimpleQuery
$parts[] = $filterPart;
}
}
if ($level > 0) {
$str .= ' (' . implode($op, $parts) . ') ';
} else {
$str .= implode($op, $parts);
if (! empty($parts)) {
if ($level > 0) {
$str .= ' (' . implode($op, $parts) . ') ';
} else {
$str .= implode($op, $parts);
}
}
}
} else {

View File

@ -0,0 +1,255 @@
<?php
/* Icinga Web 2 | (c) 2013-2015 Icinga Development Team | GPLv2+ */
namespace Icinga\Date;
/**
* Date formatting
*/
class DateFormatter
{
/**
* Format relative
*
* @var int
*/
const RELATIVE = 0;
/**
* Format time
*
* @var int
*/
const TIME = 1;
/**
* Format date
*
* @var int
*/
const DATE = 2;
/**
* Format date and time
*
* @var int
*/
const DATETIME = 4;
/**
* Get the diff between the given time and the current time
*
* @param int|float $time
*
* @return array
*/
protected static function diff($time)
{
$invert = false;
$now = time();
$time = (float) $time;
$diff = $time - $now;
if ($diff < 0) {
$diff = abs($diff);
$invert = true;
}
if ($diff > 3600 * 24 * 3) {
$type = static::DATE;
if (date('Y') === date('Y', $time)) {
$formatted = date('M j', $time);
} else {
$formatted = date('Y-m', $time);
}
} else {
$minutes = floor($diff / 60);
if ($minutes < 60) {
$type = static::RELATIVE;
$formatted = sprintf('%dm %ds', $minutes, $diff % 60);
} else {
$hours = floor($minutes / 60);
if ($hours < 24) {
if (date('d') === date('d', $time)) {
$type = static::TIME;
$formatted = date('H:i', $time);
} else {
$type = static::DATE;
$formatted = date('M j H:i', $time);
}
} else {
$type = static::RELATIVE;
$formatted = sprintf('%dd %dh', floor($hours / 24), $hours % 24);
}
}
}
return array($type, $formatted, $invert);
}
/**
* Format date
*
* @param int|float $date
*
* @return string
*/
public static function formatDate($date)
{
return date('Y-m-d', (float) $date);
}
/**
* Format date and time
*
* @param int|float $dateTime
*
* @return string
*/
public static function formatDateTime($dateTime)
{
return date('Y-m-d H:i:s', (float) $dateTime);
}
/**
* Format a duration
*
* @param int|float $seconds Duration in seconds
*
* @return string
*/
public static function formatDuration($seconds)
{
$minutes = floor((float) $seconds / 60);
if ($minutes < 60) {
$formatted = sprintf('%dm %ds', $minutes, $seconds % 60);
} else {
$hours = floor($minutes / 60);
if ($hours < 24) {
$formatted = sprintf('%dh %dm', $hours, $minutes % 60);
} else {
$formatted = sprintf('%dd %dh', floor($hours / 24), $hours % 24);
}
}
return $formatted;
}
/**
* Format time
*
* @param int|float $time
*
* @return string
*/
public static function formatTime($time)
{
return date('H:i:s', (float) $time);
}
/**
* Format time as time ago
*
* @param int|float $time
* @param bool $timeOnly
*
* @return string
*/
public static function timeAgo($time, $timeOnly = false)
{
list($type, $ago, $invert) = static::diff($time);
if ($timeOnly) {
return $ago;
}
switch ($type) {
case static::DATE:
// Move to next case
case static::DATETIME:
$formatted = sprintf(
t('on %s', 'An event happened on the given date or date and time'),
$ago
);
break;
case static::RELATIVE:
$formatted = sprintf(
t('%s ago', 'An event that happened the given time interval ago'),
$ago
);
break;
case static::TIME:
$formatted = sprintf(t('at %s', 'An event happened at the given time'), $ago);
break;
}
return $formatted;
}
/**
* Format time as time since
*
* @param int|float $time
* @param bool $timeOnly
*
* @return string
*/
public static function timeSince($time, $timeOnly = false)
{
list($type, $since, $invert) = static::diff($time);
if ($timeOnly) {
return $since;
}
switch ($type) {
case static::RELATIVE:
$formatted = sprintf(
t('for %s', 'A status is lasting for the given time interval'),
$since
);
break;
case static::DATE:
// Move to next case
case static::DATETIME:
// Move to next case
case static::TIME:
$formatted = sprintf(
t('since %s', 'A status is lasting since the given time, date or date and time'),
$since
);
break;
}
return $formatted;
}
/**
* Format time as time until
*
* @param int|float $time
* @param bool $timeOnly
*
* @return string
*/
public static function timeUntil($time, $timeOnly = false)
{
list($type, $until, $invert) = static::diff($time);
if ($invert && $type === static::RELATIVE) {
$until = '-' . $until;
}
if ($timeOnly) {
return $until;
}
switch ($type) {
case static::DATE:
// Move to next case
case static::DATETIME:
$formatted = sprintf(
t('on %s', 'An event will happen on the given date or date and time'),
$until
);
break;
case static::RELATIVE:
$formatted = sprintf(
t('in %s', 'An event will happen after the given time interval has elapsed'),
$until
);
break;
case static::TIME:
$formatted = sprintf(t('at %s', 'An event will happen at the given time'), $until);
break;
}
return $formatted;
}
}

View File

@ -25,7 +25,6 @@ namespace Icinga\Test {
use Mockery;
use PHPUnit_Framework_TestCase;
use Icinga\Application\Icinga;
use Icinga\Util\DateTimeFactory;
use Icinga\Data\ConfigObject;
use Icinga\Data\ResourceFactory;
use Icinga\Data\Db\DbConnection;
@ -104,12 +103,11 @@ namespace Icinga\Test {
);
/**
* Setup the default timezone and pass it to DateTimeFactory::setConfig
* Setup the default timezone
*/
public static function setupTimezone()
{
date_default_timezone_set('UTC');
DateTimeFactory::setConfig(array('timezone' => 'UTC'));
}
/**

View File

@ -1,92 +0,0 @@
<?php
/* Icinga Web 2 | (c) 2013-2015 Icinga Development Team | GPLv2+ */
namespace Icinga\Util;
use Exception;
use DateTime;
use DateTimeZone;
use Icinga\Util\ConfigAwareFactory;
use Icinga\Exception\ConfigurationError;
/**
* Factory for time zone aware DateTime objects
*/
class DateTimeFactory implements ConfigAwareFactory
{
/**
* Time zone used throughout DateTime object creation
*
* @var DateTimeZone
*/
protected static $timeZone;
/**
* Set the factory's config
*
* Set the factory's time zone via key timezone in the given config array
*
* @param array $config An array with key 'timezone'
*
* @throws ConfigurationError if the given array misses the key 'timezone'
*/
public static function setConfig($config)
{
try {
$tz = new DateTimeZone(isset($config['timezone']) ? $config['timezone'] : '');
} catch (Exception $e) {
throw new ConfigurationError('"DateTimeFactory" expects a valid time zone be set via "setConfig"');
}
self::$timeZone = $tz;
}
/**
* Return new DateTime object using the given format, time and set timezone
*
* Wraps DateTime::createFromFormat()
*
* @param string $format
* @param string $time
* @param DateTimeZone $timeZone
*
* @return DateTime
*
* @see DateTime::createFromFormat()
*/
public static function parse($time, $format, DateTimeZone $timeZone = null)
{
return DateTime::createFromFormat($format, $time, $timeZone !== null ? $timeZone : self::$timeZone);
}
/**
* Return new DateTime object using the given date/time string and set time zone
*
* Wraps DateTime::__construct()
*
* @param string $time
* @param DateTimeZone $timeZone
*
* @return DateTime
*
* @see DateTime::__construct()
*/
public static function create($time = 'now', DateTimeZone $timeZone = null)
{
return new DateTime($time, $timeZone !== null ? $timeZone : self::$timeZone);
}
/**
* Check whether a variable is a Unix timestamp
*
* @param mixed $timestamp
*
* @return bool
*/
public static function isUnixTimestamp($timestamp)
{
return (is_int($timestamp) || ctype_digit($timestamp))
&& ($timestamp <= PHP_INT_MAX)
&& ($timestamp >= ~PHP_INT_MAX);
}
}

View File

@ -4,6 +4,7 @@
namespace Icinga\Util;
use DateTime;
use Icinga\Date\DateFormatter;
use Icinga\Exception\ProgrammingError;
class Format
@ -58,86 +59,13 @@ class Format
if ($value < 60) {
return self::formatForUnits($value, self::$secondPrefix, self::$secondBase);
} elseif ($value < 3600) {
return sprintf('0.2f m', $value / 60);
return sprintf('%0.2f m', $value / 60);
} elseif ($value < 86400) {
return sprintf('0.2f h', $value / 3600);
return sprintf('%0.2f h', $value / 3600);
}
// TODO: Do we need weeks, months and years?
return sprintf('0.2f d', $value / 86400);
}
public static function duration($duration)
{
if ($duration === null || $duration === false) {
return '-';
}
return self::showHourMin($duration);
}
protected static function showHourMin($sec, $includePrefix = false)
{
$min = floor($sec / 60);
if ($min < 60) {
return ($includePrefix ? t('for') . ' ' : '') . $min . 'm ' . ($sec % 60) . 's';
}
$hour = floor($min / 60);
if ($hour < 24) {
return ($includePrefix ? t('since') . ' ' : '') . date('H:i', time() - $sec);
}
return ($includePrefix ? t('for') . ' ' : '') . floor($hour / 24) . 'd ' . ($hour % 24) . 'h';
}
protected static function smartTimeDiff($diff, $timestamp, $includePrefix = false)
{
if ($timestamp === null || $timestamp === false) {
return '-';
}
if (! preg_match('~^\d+$~', $timestamp)) {
throw new ProgrammingError(
'"%s" is not a number',
$timestamp
);
}
$prefix = '';
if ($diff < 0) {
$prefix = '-';
}
if (abs($diff) > 3600 * 24 * 3) {
if (date('Y') === date('Y', $timestamp)) {
return ($includePrefix ? t('since') . ' ' : '') . date('d.m.', $timestamp);
}
return ($includePrefix ? t('since') . ' ' : '') . date('m.Y', $timestamp);
}
return $prefix . self::showHourMin(abs($diff), $includePrefix);
}
public static function timeSince($timestamp)
{
return self::smartTimeDiff(time() - $timestamp, $timestamp);
}
public static function prefixedTimeSince($timestamp, $ucfirst = false)
{
$result = self::smartTimeDiff(time() - $timestamp, $timestamp, true);
if ($ucfirst) {
$result = ucfirst($result);
}
return $result;
}
public static function timeUntil($timestamp)
{
return self::smartTimeDiff($timestamp - time(), $timestamp);
}
public static function prefixedTimeUntil($timestamp, $ucfirst)
{
$result = self::smartTimeDiff($timestamp - time(), $timestamp, true);
if ($ucfirst) {
$result = ucfirst($result);
}
return $result;
return sprintf('%0.2f d', $value / 86400);
}
protected static function formatForUnits($value, & $units, $base)

View File

@ -5,7 +5,6 @@ namespace Icinga\Web\Form\Validator;
use DateTime;
use Zend_Validate_Abstract;
use Icinga\Util\DateTimeFactory;
/**
* Validator for date-and-time input controls
@ -68,7 +67,7 @@ class DateTimeValidator extends Zend_Validate_Abstract
}
if ($dateTime === false || $dateTime->format($format) !== $value) {
$this->_error(self::INVALID_DATETIME_FORMAT, DateTimeFactory::create()->format($baseFormat));
$this->_error(self::INVALID_DATETIME_FORMAT, $baseFormat);
return false;
}
}

View File

@ -1,204 +0,0 @@
<?php
/* Icinga Web 2 | (c) 2013-2015 Icinga Development Team | GPLv2+ */
namespace Icinga\Web\View;
use DateTime;
class DateTimeRenderer
{
const TYPE_DATETIME = 0;
const TYPE_TIME = 1;
const TYPE_TIMESPAN = 2;
const HOUR = 3600;
/**
* The present DateTime
*
* @var DateTime
*/
protected $now;
/**
* The DateTime tense
*
* @var bool
*/
protected $future;
/**
* The given DateTime type
*
* @var integer
*/
protected $type;
/**
* The given DateTime
*
* @var DateTime
*/
protected $dateTime;
public function __construct($dateTime, $future = false)
{
$this->future = $future;
$this->now = new DateTime();
$this->dateTime = $this->normalize($dateTime);
$this->detectType();
}
/**
* Creates a new DateTimeRenderer
*
* @param DateTime|int $dateTime
* @param bool $future
*
* @return DateTimeRenderer
*/
public static function create($dateTime, $future = false)
{
return new static($dateTime, $future);
}
/**
* Detects the DateTime context
*/
protected function detectType()
{
if ($this->now->format('Y-m-d') !== $this->dateTime->format('Y-m-d')) {
$this->type = self::TYPE_DATETIME;
return;
}
if (
$this->now->format('Y-m-d') === $this->dateTime->format('Y-m-d') &&
(abs($this->now->getTimestamp() - $this->dateTime->getTimestamp()) >= self::HOUR)
) {
$this->type = self::TYPE_TIME;
return;
}
if (
$this->now->format('Y-m-d') === $this->dateTime->format('Y-m-d') &&
(abs($this->now->getTimestamp() - $this->dateTime->getTimestamp()) < self::HOUR)
) {
$this->type = self::TYPE_TIMESPAN;
return;
}
}
/**
* Normalizes the given DateTime
*
* @param DateTime|int $dateTime
*
* @return DateTime
*/
public static function normalize($dateTime)
{
if (! ($dt = $dateTime) instanceof DateTime) {
$dt = new DateTime();
$dt->setTimestamp($dateTime);
}
return $dt;
}
/**
* Checks whether DateTime is a date with time
*
* @return bool
*/
public function isDateTime()
{
return $this->type === self::TYPE_DATETIME;
}
/**
* Checks whether DateTime is a time of the current day
*
* @return bool
*/
public function isTime()
{
return $this->type === self::TYPE_TIME;
}
/**
* Checks whether DateTime is in a defined interval
*
* @return bool
*/
public function isTimespan()
{
return $this->type === self::TYPE_TIMESPAN;
}
/**
* Returns the type of the DateTime
*
* @return mixed
*/
public function getType()
{
return $this->type;
}
/**
* Renders the DateTime on the basis of the type and returns suited text
*
* @param string $dateTimeText
* @param string $timeText
* @param string $timespanText
*
* @return string
*/
public function render($dateTimeText, $timeText, $timespanText)
{
if ($this->isDateTime()) {
return sprintf($dateTimeText, $this);
} elseif ($this->isTime()) {
return sprintf($timeText, $this);
} elseif ($this->isTimespan()) {
return sprintf($timespanText, $this);
}
return $dateTimeText;
}
/**
* Returns a rendered html wrapped text
*
* @return string
*/
public function __toString()
{
switch ($this->type) {
case self::TYPE_DATETIME:
$format = $this->dateTime->format('d.m.Y - H:i:s');
break;
case self::TYPE_TIME:
$format = $this->dateTime->format('H:i:s');
break;
case self::TYPE_TIMESPAN:
$format = $this->dateTime->diff($this->now)->format(t('%im %ss', 'timespan'));
break;
default:
$format = $this->dateTime->format('d.m.Y - H:i:s');
break;
}
$css = '';
if ($this->type === self::TYPE_TIMESPAN) {
$css = $this->future === true ? 'timeuntil' : 'timesince';
}
return sprintf(
'<span class="%s" title="%s">%s</span>',
$css,
$this->dateTime->format('d.m.Y - H:i:s'),
$format
);
}
}

View File

@ -3,47 +3,70 @@
namespace Icinga\Web\View;
use Icinga\Web\Url;
use Icinga\Date\DateFormatter;
use Icinga\Util\Format;
$this->addHelperFunction('format', function () {
return Format::getInstance();
});
$this->addHelperFunction('timeSince', function ($timestamp) {
$this->addHelperFunction('formatDate', function ($date) {
if (! $date) {
return '';
}
return DateFormatter::formatDate($date);
});
$this->addHelperFunction('formatDateTime', function ($dateTime) {
if (! $dateTime) {
return '';
}
return DateFormatter::formatDateTime($dateTime);
});
$this->addHelperFunction('formatDuration', function ($seconds) {
if (! $seconds) {
return '';
}
return DateFormatter::formatDuration($seconds);
});
$this->addHelperFunction('formatTime', function ($time) {
if (! $time) {
return '';
}
return DateFormatter::formatTime($time);
});
$this->addHelperFunction('timeAgo', function ($time, $timeOnly = false) {
if (! $time) {
return '';
}
return sprintf(
'<span class="timesince" title="%s">%s</span>',
date('Y-m-d H:i:s', $timestamp), // TODO: internationalized format
Format::timeSince($timestamp)
'<span class="time-ago" title="%s">%s</span>',
DateFormatter::formatDateTime($time),
DateFormatter::timeAgo($time, $timeOnly)
);
});
$this->addHelperFunction('prefixedTimeSince', function ($timestamp, $ucfirst = false) {
$this->addHelperFunction('timeSince', function ($time, $timeOnly = false) {
if (! $time) {
return '';
}
return sprintf(
'<span class="timesince" title="%s">%s</span>',
date('Y-m-d H:i:s', $timestamp), // TODO: internationalized format
Format::prefixedTimeSince($timestamp, $ucfirst)
'<span class="time-since" title="%s">%s</span>',
DateFormatter::formatDateTime($time),
DateFormatter::timeSince($time, $timeOnly)
);
});
$this->addHelperFunction('timeUntil', function ($timestamp) {
if (! $timestamp) return '';
$this->addHelperFunction('timeUntil', function ($time, $timeOnly = false) {
if (! $time) {
return '';
}
return sprintf(
'<span class="timeuntil" title="%s">%s</span>',
date('Y-m-d H:i:s', $timestamp), // TODO: internationalized format
Format::timeUntil($timestamp)
'<span class="time-until" title="%s">%s</span>',
DateFormatter::formatDateTime($time),
DateFormatter::timeUntil($time, $timeOnly)
);
});
$this->addHelperFunction('prefixedTimeUntil', function ($timestamp, $ucfirst = false) {
if (! $timestamp) return '';
return sprintf(
'<span class="timeuntil" title="%s">%s</span>',
date('Y-m-d H:i:s', $timestamp), // TODO: internationalized format
Format::prefixedTimeUntil($timestamp, $ucfirst)
);
});
$this->addHelperFunction('dateTimeRenderer', function ($dateTimeOrTimestamp, $future = false) {
return DateTimeRenderer::create($dateTimeOrTimestamp, $future);
});

View File

@ -3,10 +3,10 @@
namespace Icinga\Web\Widget\Chart;
use Icinga\Util\DateTimeFactory;
use DateInterval;
use DateTime;
use Icinga\Util\Color;
use Icinga\Web\Widget\AbstractWidget;
use DateInterval;
/**
* Display a colored grid that visualizes a set of values for each day
@ -313,7 +313,7 @@ class HistoryColorGrid extends AbstractWidget {
private function monthName($month, $year)
{
// TODO: find a way to render years without messing up the layout
$dt = DateTimeFactory::create($year . '-' . $month . '-01');
$dt = new DateTime($year . '-' . $month . '-01');
return $dt->format('M');
}
@ -324,7 +324,7 @@ class HistoryColorGrid extends AbstractWidget {
*/
private function weekdayName($weekday)
{
$sun = DateTimeFactory::create('last Sunday');
$sun = new DateTime('last Sunday');
$interval = new DateInterval('P' . $weekday . 'D');
$sun->add($interval);
return substr($sun->format('D'), 0, 2);

View File

@ -299,7 +299,7 @@ class ListCommand extends Command
$leaf,
$screen->underline($row->service_description),
$screen->colorize($utils->objectStateFlags('service', $row) . $perf, 'lightblue'),
Format::prefixedTimeSince($row->service_last_state_change, true)
ucfirst(Format::timeSince($row->service_last_state_change))
);
if ($this->isVerbose) {
$out .= $emptyLine . preg_replace(

View File

@ -46,7 +46,7 @@ class Monitoring_HostsController extends Controller
'icon' => 'host'
)
)->extend(new DashboardAction())->activate('show');
$this->view->listAllLink = Url::fromRequest()->setPath('monitoring/list/hosts')->setQueryString($filterString);
}
@ -78,11 +78,6 @@ class Monitoring_HostsController extends Controller
$this->view->form = $form;
$this->view->objects = $this->hostList;
$this->view->stats = $this->hostList->getStateSummary();
$this->view->hostStatesPieChart = InlinePie::createFromStateSummary(
$this->view->stats,
$this->translate('Host State'),
InlinePie::$colorsHostStatesHandledUnhandled
);
$this->_helper->viewRenderer('partials/command/objects-command-form', null, true);
return $form;
}

View File

@ -1,11 +1,8 @@
<?php
/* Icinga Web 2 | (c) 2013-2015 Icinga Development Team | GPLv2+ */
use \DateTime;
use \DateInterval;
use Icinga\Web\Url;
use Icinga\Util\Format;
use Icinga\Util\DateTimeFactory;
use Icinga\Module\Monitoring\Controller;
use Icinga\Module\Monitoring\Timeline\TimeLine;
use Icinga\Module\Monitoring\Timeline\TimeRange;
@ -234,7 +231,7 @@ class Monitoring_TimelineController extends Controller
*/
private function buildTimeRanges()
{
$startTime = DateTimeFactory::create();
$startTime = new DateTime();
$startParam = $this->_request->getParam('start');
$startTimestamp = is_numeric($startParam) ? intval($startParam) : strtotime($startParam);
if ($startTimestamp !== false) {
@ -271,8 +268,7 @@ class Monitoring_TimelineController extends Controller
*/
private function getTimeFormat()
{
// TODO(mh): Missing localized format (#6077)
return 'g:i A';
return 'H:i';
}
/**
@ -282,7 +278,6 @@ class Monitoring_TimelineController extends Controller
*/
private function getDateFormat()
{
// TODO(mh): Missing localized format (#6077)
return 'd/m/Y';
return 'Y-m-d';
}
}

View File

@ -1,4 +1,4 @@
<div class="controls">
<div class="controls">
<?php if (! $this->compact): ?>
<?= $this->tabs; ?>
<?php endif ?>
@ -8,13 +8,13 @@
</div>
</div>
<div class="content">
<h3><?= $this->translate('Comment detail information') ?></h3>
<table class="avp">
<table class="avp">
<tbody>
<tr data-base-target='_next'>
<?php if ($this->comment->objecttype === 'service'): ?>
<th> <?= $this->translate('Service') ?> </th>
<th> <?= $this->translate('Service') ?> </th>
<td>
<?= $this->icon('service', $this->translate('Service')); ?>
<?= $this->link()->service(
@ -26,7 +26,7 @@
?>
</td>
<?php else: ?>
<th> <?= $this->translate('Host') ?> </th>
<th> <?= $this->translate('Host') ?> </th>
<td>
<?= $this->icon('host', $this->translate('Host')); ?>
<?= $this->link()->host(
@ -34,7 +34,7 @@
$this->comment->host_display_name
);
?>
</td>
</td>
<?php endif ?>
</tr>
@ -42,29 +42,29 @@
<th><?= $this->translate('Author') ?></th>
<td><?= $this->icon('user', $this->translate('User')) ?> <?= $this->escape($this->comment->author) ?></td>
</tr>
<tr>
<th><?= $this->translate('Persistent') ?></th>
<td><?= $this->escape($this->comment->persistent) ? $this->translate('Yes') : $this->translate('No') ?></td>
</tr>
<tr>
<th><?= $this->translate('Created') ?></th>
<td><?= date('d.m.y H:i' ,$this->escape($this->comment->timestamp)) ?></td>
<td><?= $this->formatDateTime($this->comment->timestamp) ?></td>
</tr>
<tr>
<th><?= $this->translate('Expires') ?></th>
<td>
<?= $this->comment->expiration ? sprintf(
$this->translate('This comment expires on %s at %s.'),
date('d.m.y', $this->comment->expiration),
date('H:i', $this->comment->expiration)
$this->formatDate($this->comment->expiration),
$this->formatTime($this->comment->expiration)
) : $this->translate('This comment does not expire.');
?>
</td>
</tr>
<?php if (isset($delCommentForm)): // Form is unset if the current user lacks the respective permission ?>
<tr class="newsection">
<th><?= $this->translate('Commands') ?></th>
@ -73,7 +73,7 @@
</td>
</tr>
<?php endif ?>
</tbody>
</table>

View File

@ -1,13 +1,13 @@
<div class="controls">
<div class="controls">
<?php if (! $this->compact): ?>
<?= $this->tabs; ?>
<?php endif ?>
<?= $this->render('partials/downtime/downtime-header.phtml'); ?>
</div>
<div class="content">
<h3><?= $this->translate('Downtime detail information') ?></h3>
<table class="avp">
<table class="avp">
<tbody>
<tr>
<th>
@ -15,17 +15,17 @@
</th>
<td data-base-target="_next">
<?php if ($this->isService): ?>
<?php
<?php
$link = $this->link()->service(
$downtime->service_description,
$downtime->service_description,
$downtime->service_display_name,
$downtime->host_name,
$downtime->host_display_name
);
$icon = $this->icon('service', $this->translate('Service'));
$icon = $this->icon('service', $this->translate('Service'));
?>
<?php else: ?>
<?php
<?php
$icon = $this->icon('host', $this->translate('Host'));
$link = $this->link()->host($downtime->host_name, $downtime->host_display_name)
?>
@ -33,7 +33,7 @@
<?= $icon ?>
<?= $link ?>
</td>
</tr>
</tr>
<tr title="<?= $this->translate('The name of the person who scheduled this downtime'); ?>">
<th><?= $this->translate('Author') ?></th>
<td><?= $this->icon('user', $this->translate('User')) ?> <?= $this->escape($this->downtime->author_name) ?></td>
@ -44,19 +44,19 @@
</tr>
<tr title="<?= $this->translate('Date and time this downtime was entered'); ?>">
<th><?= $this->translate('Entry Time') ?></th>
<td> <?= date('d.m.y H:i' ,$this->escape($this->downtime->entry_time)) ?></td>
<td><?= $this->formatDateTime($this->downtime->entry_time) ?></td>
</tr>
<tr class="newsection">
<th><?= $this->escape(
$this->downtime->is_flexible ?
$this->downtime->is_flexible ?
$this->translate('Flexible') : $this->translate('Fixed')
); ?></th>
<td>
<?= $this->escape(
$this->downtime->is_flexible ?
$this->translate('Flexible downtimes have a hard start and end time,'
. ' but also an additional restriction on the duration in which '
. ' the host or service may actually be down.') :
$this->downtime->is_flexible ?
$this->translate('Flexible downtimes have a hard start and end time,'
. ' but also an additional restriction on the duration in which '
. ' the host or service may actually be down.') :
$this->translate('Fixed downtimes have a static start and end time.')
); ?>
</td>
@ -66,14 +66,14 @@
. 'this refers to the earliest possible time that the downtime'
. ' can start'); ?>">
<th><?= $this->translate('Scheduled start') ?></th>
<td><?= date('d.m.y H:i', $this->downtime->scheduled_start) ?></td>
<td><?= $this->formatDateTime($this->downtime->scheduled_start) ?></td>
</tr>
<tr title="<?= $this->translate('The date/time the scheduled downtime is '
. 'supposed to end. If this is a flexible (non-fixed) downtime, '
. 'this refers to the last possible time that the downtime can '
. 'start'); ?>">
<th><?= $this->translate('Scheduled end') ?></th>
<td><?= date('d.m.y H:i', $this->downtime->scheduled_end) ?></td>
<td><?= $this->formatDateTime($this->downtime->scheduled_end) ?></td>
</tr>
<?php if ($this->downtime->is_flexible): ?>
<tr title="<?= $this->translate('Indicates the number of seconds that the '
@ -81,31 +81,31 @@
. ' this is a flexible downtime, which can start at a variable '
. 'time, but lasts for the specified duration'); ?>">
<th tit><?= $this->translate('Duration') ?></th>
<td><?= $this->format()->duration($this->escape($this->downtime->duration)); ?></td>
<td><?= $this->formatDuration($this->downtime->duration) ?></td>
</tr>
<tr title="<?= $this->translate('he date/time the scheduled downtime was'
. ' actually started'); ?>">
<th><?= $this->translate('Actual start time') ?></th>
<td><?= date('d.m.y H:i', $downtime->start); ?></td>
<td><?= $this->formatDateTime($downtime->start) ?></td>
</tr>
<tr title="<?= $this->translate('The date/time the scheduled downtime '
. 'actually ended'); ?>">
<th><?= $this->translate('Actual end time') ?></th>
<td><?= date('d.m.y H:i', $downtime->end); ?></td>
<td><?= $this->formatDateTime($downtime->end) ?></td>
</tr>
<?php endif; ?>
<tr class="newsection">
<th><?= $this->translate('In effect') ?></th>
<td>
<?= $this->escape(
$this->downtime->is_in_effect ?
$this->downtime->is_in_effect ?
$this->translate('Yes') : $this->translate('No')
);
);
?>
</td>
</tr>
<?php if (isset($delDowntimeForm)): // Form is unset if the current user lacks the respective permission ?>
<tr class="newsection">
<th><?= $this->translate('Commands') ?></th>

View File

@ -36,7 +36,7 @@ if (count($comments) === 0) {
<td>
<?php if ($comment->objecttype === 'service'): ?>
<?= $this->icon('service', $this->translate('Service')); ?>
<?= $this->qlink(
sprintf(
$this->translate('%s on %s', 'Service running on host'),
@ -52,7 +52,7 @@ if (count($comments) === 0) {
))) ?>
<?php else: ?>
<?= $this->icon('host', $this->translate('Host')); ?>
<?= $this->qlink(
$comment->host_display_name,
'monitoring/comment/show',
@ -74,10 +74,9 @@ if (count($comments) === 0) {
?>
<br>
<?= $comment->expiration ? sprintf(
$this->translate('This comment expires on %s at %s.'),
date('d.m.y', $comment->expiration),
date('H:i', $comment->expiration)
) : $this->translate('This comment does not expire.'); ?>
$this->translate('This comment expires %s.'),
$this->timeUntil($comment->expiration)
) : $this->translate('This comment does not expire.'); ?>
</td>
<?php if (isset($delCommentForm)): // Form is unset if the current user lacks the respective permission ?>
<td style="width: 2em" data-base-target="self">

View File

@ -26,8 +26,8 @@ if (count($downtimes) === 0) {
return;
}
?>
<table data-base-target="_next"
class="action multiselect"
<table data-base-target="_next"
class="action multiselect"
data-icinga-multiselect-url="/icingaweb2/monitoring/downtimes/show"
data-icinga-multiselect-data="downtime_id">
<tbody>
@ -45,24 +45,15 @@ if (count($downtimes) === 0) {
<td class="state">
<strong><?= $downtime->is_in_effect ? $this->translate('Expires') : $this->translate('Starts'); ?></strong>
<br>
<?=
$this->dateTimeRenderer(
($downtime->is_in_effect ? $downtime->end : $downtime->start),
true
)->render(
$this->translate('on %s', 'datetime'),
$this->translate('at %s', 'time'),
$this->translate('in %s', 'timespan')
);
?>
<?= $this->timeUntil($downtime->is_in_effect ? $downtime->end : $downtime->start, $this->compact) ?>
</td>
<td>
<?php
<?php
if ($isService) {
echo $this->icon('service');
} else {
echo $this->icon('host');
}
}
?>
<?= $this->qlink(
sprintf($this->translate('%s on %s', 'Service running on host'), $downtime->service_display_name, $downtime->host_display_name),
@ -83,20 +74,20 @@ if (count($downtimes) === 0) {
$isService
? $this->translate('This flexible service downtime was started on %s at %s and lasts for %s until %s at %s.')
: $this->translate('This flexible host downtime was started on %s at %s and lasts for %s until %s at %s.'),
date('d.m.y', $downtime->start),
date('H:i', $downtime->start),
$this->format()->duration($downtime->duration),
date('d.m.y', $downtime->end),
date('H:i', $downtime->end)
$this->formatDate($downtime->start),
$this->formatTime($downtime->start),
$this->formatDuration($downtime->duration),
$this->formatDate($downtime->end),
$this->formatTime($downtime->end)
); ?>
<?php else: ?>
<?= sprintf(
$isService
? $this->translate('This flexible service downtime has been scheduled to start between %s - %s and to last for %s.')
: $this->translate('This flexible host downtime has been scheduled to start between %s - %s and to last for %s.'),
date('d.m.y H:i', $downtime->scheduled_start),
date('d.m.y H:i', $downtime->scheduled_end),
$this->format()->duration($downtime->duration)
$this->formatDateTime($downtime->scheduled_start),
$this->formatDateTime($downtime->scheduled_end),
$this->formatDuration($downtime->duration)
); ?>
<?php endif ?>
<?php else: ?>
@ -105,20 +96,20 @@ if (count($downtimes) === 0) {
$isService
? $this->translate('This fixed service downtime was started on %s at %s and expires on %s at %s.')
: $this->translate('This fixed host downtime was started on %s at %s and expires on %s at %s.'),
date('d.m.y', $downtime->start),
date('H:i', $downtime->start),
date('d.m.y', $downtime->end),
date('H:i', $downtime->end)
$this->formatDate($downtime->start),
$this->formatTime($downtime->start),
$this->formatDate($downtime->end),
$this->formatTime($downtime->end)
); ?>
<?php else: ?>
<?= sprintf(
$isService
? $this->translate('This fixed service downtime has been scheduled to start on %s at %s and to end on %s at %s.')
: $this->translate('This fixed host downtime has been scheduled to start on %s at %s and to end on %s at %s.'),
date('d.m.y', $downtime->scheduled_start),
date('H:i', $downtime->scheduled_start),
date('d.m.y', $downtime->scheduled_end),
date('H:i', $downtime->scheduled_end)
$this->formatDate($downtime->start),
$this->formatTime($downtime->start),
$this->formatDate($downtime->end),
$this->formatTime($downtime->end)
); ?>
<?php endif ?>
<?php endif ?>

View File

@ -75,7 +75,7 @@ foreach ($summary as $entry) {
$caption = sprintf(
$settings[$column]['tooltip'],
$value,
$this->dateFormat()->formatDate(strtotime($day))
$this->formatDate(strtotime($day))
);
$linkFilter = Filter::matchAll(
Filter::expression('timestamp', '<', strtotime($day . ' 23:59:59')),

View File

@ -85,7 +85,7 @@ if (count($history) === 0) {
<td class="state">
<strong><?= $this->escape($title); ?></strong>
<br>
<?= date('d.m. H:i', $event->timestamp); ?>
<?= $this->timeAgo($event->timestamp, $this->compact); ?>
</td>
<td>
<?php if ($isService): ?>

View File

@ -60,7 +60,7 @@ if (count($hostgroups) === 0) {
<td class="state">
<strong><?= Host::getStateText($state, true); ?></strong>
<br>
<?= $this->prefixedTimeSince($lastStateChange); ?>
<?= $this->timeSince($lastStateChange, $this->compact); ?>
</td>
<td class="groupname">
<?= $this->qlink(

View File

@ -40,13 +40,14 @@ if (count($hosts) === 0) {
<tr class="state <?= $hostStateName ?><?= $host->host_handled ? ' handled' : '' ?>">
<!-- State -->
<td class="state">
<strong><?= Host::getStateText($host->host_state, true); ?></strong><br />
<strong><?= Host::getStateText($host->host_state, true); ?></strong>
<?php if ((int) $host->host_state !== 99): ?>
<?= $this->prefixedTimeSince($host->host_last_state_change, true) ?>
<?php if ($host->host_state > 0 && (int) $host->host_state_type === 0): ?>
<br />
<strong>Soft <?= $host->host_attempt ?></strong>
<?php endif ?>
<br />
<?= $this->timeSince($host->host_last_state_change, $this->compact) ?>
<?php if ((int) $host->host_state > 0 && (int) $host->host_state_type === 0): ?>
<br />
<strong>Soft <?= $host->host_attempt ?></strong>
<?php endif ?>
<?php endif ?>
</td>

View File

@ -32,11 +32,7 @@ if (count($notifications) === 0) {
?>
<tr class="state <?= $stateName ?>">
<td class="state">
<?= $this->dateTimeRenderer($notification->notification_start_time)->render(
$this->translate('on %s', 'datetime'),
$this->translate('at %s', 'time'),
$this->translate('%s ago', 'timespan')
) ?>
<?= $this->timeAgo($notification->notification_start_time, $this->compact) ?>
</td>
<td style="font-size: 0.8em">
<?php if ($isService): ?>

View File

@ -29,49 +29,49 @@ if (count($servicegroups) === 0) {
<td class="state change critical unhandled">
<strong><?= $this->translate('CRITICAL'); ?></strong>
<br>
<?= $this->prefixedTimeSince($s->services_critical_last_state_change_unhandled); ?>
<?= $this->timeSince($s->services_critical_last_state_change_unhandled); ?>
</td>
<?php elseif ($s->services_unknown_last_state_change_unhandled): ?>
<td class="state change unknown unhandled">
<strong><?= $this->translate('UNKNOWN'); ?></strong>
<br>
<?= $this->prefixedTimeSince($s->services_unknown_last_state_change_unhandled); ?>
<?= $this->timeSince($s->services_unknown_last_state_change_unhandled); ?>
</td>
<?php elseif ($s->services_warning_last_state_change_unhandled): ?>
<td class="state change warning unhandled">
<strong><?= $this->translate('WARNING'); ?></strong>
<br>
<?= $this->prefixedTimeSince($s->services_warning_last_state_change_unhandled); ?>
<?= $this->timeSince($s->services_warning_last_state_change_unhandled); ?>
</td>
<?php elseif ($s->services_critical_last_state_change_handled): ?>
<td class="state change critical">
<strong><?= $this->translate('CRITICAL'); ?></strong>
<br>
<?= $this->prefixedTimeSince($s->services_critical_last_state_change_handled); ?>
<?= $this->timeSince($s->services_critical_last_state_change_handled); ?>
</td>
<?php elseif ($s->services_unknown_last_state_change_handled): ?>
<td class="state change unknown">
<strong><?= $this->translate('UNKNOWN'); ?></strong>
<br>
<?= $this->prefixedTimeSince($s->services_unknown_last_state_change_handled); ?>
<?= $this->timeSince($s->services_unknown_last_state_change_handled); ?>
</td>
<?php elseif ($s->services_warning_last_state_change_handled): ?>
<td class="state change warning">
<strong><?= $this->translate('WARNING'); ?></strong>
<br>
<?= $this->prefixedTimeSince($s->services_warning_last_state_change_handled); ?>
<?= $this->timeSince($s->services_warning_last_state_change_handled); ?>
</td>
<?php elseif ($s->services_ok_last_state_change): ?>
<td class="state change ok">
<strong><?= $this->translate('OK'); ?></strong>
<br>
<?= $this->prefixedTimeSince($s->services_ok_last_state_change); ?>
<?= $this->timeSince($s->services_ok_last_state_change); ?>
</td>
<?php else: ?>
<td class="state change pending">
<strong><?= $this->translate('PENDING'); ?></strong>
<br>
<?= $this->prefixedTimeSince($s->services_pending_last_state_change); ?>
<?= $this->timeSince($s->services_pending_last_state_change); ?>
</td>
<?php endif ?>
<td class="groupname">

View File

@ -48,12 +48,15 @@ if (count($services) === 0) {
?>
<tr class="state <?= $serviceStateName ?><?= $service->service_handled ? ' handled' : '' ?>">
<td class="state">
<strong><?= Service::getStateText($service->service_state, true); ?></strong><br />
<?php if (!$this->compact): ?><?= $this->prefixedTimeSince($service->service_last_state_change); ?><?php else: ?><?= $this->timeSince($service->service_last_state_change); ?><?php endif ?>
<?php if ($service->service_state > 0 && (int) $service->service_state_type === 0): ?>
<br />
<strong>Soft <?= $service->service_attempt ?></strong>
<?php endif ?>
<strong><?= Service::getStateText($service->service_state, true); ?></strong>
<?php if ((int) $service->service_state !== 99): ?>
<br />
<?= $this->timeSince($service->service_last_state_change, $this->compact) ?>
<?php if ((int) $service->service_state > 0 && (int) $service->service_state_type === 0): ?>
<br />
<strong>Soft <?= $service->service_attempt ?></strong>
<?php endif ?>
<?php endif ?>
</td>
<td>

View File

@ -24,4 +24,4 @@
?>
<strong><?= $this->escape($title); ?></strong><br>
<?= $this->icon($icon, $tooltip) ?>
<?= $this->prefixedTimeSince($comment->timestamp); ?>
<?= $this->timeAgo($comment->timestamp, $this->compact); ?>

View File

@ -3,16 +3,7 @@
<td class="state">
<strong><?= $downtime->is_in_effect ? $this->translate('Expires') : $this->translate('Starts'); ?></strong>
<br>
<?=
$this->dateTimeRenderer(
($downtime->is_in_effect ? $downtime->end : $downtime->start),
true
)->render(
$this->translate('on %s', 'datetime'),
$this->translate('at %s', 'time'),
$this->translate('in %s', 'timespan')
);
?>
<?= $this->timeUntil($downtime->is_in_effect ? $downtime->end : $downtime->start, $this->compact) ?>
</td>
<td>
<small>
@ -22,20 +13,20 @@
$this->isService
? $this->translate('This flexible service downtime was started on %s at %s and lasts for %s until %s at %s.')
: $this->translate('This flexible host downtime was started on %s at %s and lasts for %s until %s at %s.'),
date('d.m.y', $downtime->start),
date('H:i', $downtime->start),
$this->format()->duration($downtime->duration),
date('d.m.y', $downtime->end),
date('H:i', $downtime->end)
$this->formatDate($downtime->start),
$this->formatTime($downtime->start),
$this->formatDuration($downtime->duration),
$this->formatDate($downtime->end),
$this->formatTime($downtime->end)
); ?>
<?php else: ?>
<?= sprintf(
$this->isService
? $this->translate('This flexible service downtime has been scheduled to start between %s - %s and to last for %s.')
: $this->translate('This flexible host downtime has been scheduled to start between %s - %s and to last for %s.'),
date('d.m.y H:i', $downtime->scheduled_start),
date('d.m.y H:i', $downtime->scheduled_end),
$this->format()->duration($downtime->duration)
$this->formatDateTime($downtime->scheduled_start),
$this->formatDateTime($downtime->scheduled_end),
$this->formatDuration($downtime->duration)
); ?>
<?php endif ?>
<?php else: ?>
@ -44,20 +35,20 @@
$this->isService
? $this->translate('This fixed service downtime was started on %s at %s and expires on %s at %s.')
: $this->translate('This fixed host downtime was started on %s at %s and expires on %s at %s.'),
date('d.m.y', $downtime->start),
date('H:i', $downtime->start),
date('d.m.y', $downtime->end),
date('H:i', $downtime->end)
$this->formatDate($downtime->start),
$this->formatTime($downtime->start),
$this->formatDate($downtime->end),
$this->formatTime($downtime->end)
); ?>
<?php else: ?>
<?= sprintf(
$this->isService
? $this->translate('This fixed service downtime has been scheduled to start on %s at %s and to end on %s at %s.')
: $this->translate('This fixed host downtime has been scheduled to start on %s at %s and to end on %s at %s.'),
date('d.m.y', $downtime->scheduled_start),
date('H:i', $downtime->scheduled_start),
date('d.m.y', $downtime->scheduled_end),
date('H:i', $downtime->scheduled_end)
$this->formatDate($downtime->start),
$this->formatTime($downtime->start),
$this->formatDate($downtime->end),
$this->formatTime($downtime->end)
); ?>
<?php endif ?>
<?php endif ?>

View File

@ -8,16 +8,7 @@
<td class="state">
<strong><?= $downtime->is_in_effect ? $this->translate('Expires') : $this->translate('Starts'); ?></strong>
<br>
<?=
$this->dateTimeRenderer(
($downtime->is_in_effect ? $downtime->end : $downtime->start),
true
)->render(
$this->translate('on %s', 'datetime'),
$this->translate('at %s', 'time'),
$this->translate('in %s', 'timespan')
);
?>
<?= $this->timeUntil($downtime->is_in_effect ? $downtime->end : $downtime->start, $this->compact) ?>
</td>
<td class="name oneline">
<?php if ($downtime->isService): ?>
@ -27,27 +18,27 @@
<?= $this->icon('host', $this->translate('Host')) ?>
<b><?= $downtime->host_name ?>.</b>
<?php endif; ?>
<?php if ($downtime->is_flexible): ?>
<?php if ($downtime->is_in_effect): ?>
<?= sprintf(
$this->isService
? $this->translate('This flexible service downtime was started on %s at %s and lasts for %s until %s at %s.')
: $this->translate('This flexible host downtime was started on %s at %s and lasts for %s until %s at %s.'),
date('d.m.y', $downtime->start),
date('H:i', $downtime->start),
$this->format()->duration($downtime->duration),
date('d.m.y', $downtime->end),
date('H:i', $downtime->end)
$this->formatDate($downtime->start),
$this->formatTime($downtime->start),
$this->formatDuration($downtime->duration),
$this->formatDate($downtime->end),
$this->formatTime($downtime->end)
); ?>
<?php else: ?>
<?= sprintf(
$this->isService
? $this->translate('This flexible service downtime has been scheduled to start between %s - %s and to last for %s.')
: $this->translate('This flexible host downtime has been scheduled to start between %s - %s and to last for %s.'),
date('d.m.y H:i', $downtime->scheduled_start),
date('d.m.y H:i', $downtime->scheduled_end),
$this->format()->duration($downtime->duration)
$this->formatDateTime($downtime->scheduled_start),
$this->formatDateTime($downtime->scheduled_end),
$this->formatDuration($downtime->duration)
); ?>
<?php endif ?>
<?php else: ?>
@ -56,20 +47,20 @@
$this->isService
? $this->translate('This fixed service downtime was started on %s at %s and expires on %s at %s.')
: $this->translate('This fixed host downtime was started on %s at %s and expires on %s at %s.'),
date('d.m.y', $downtime->start),
date('H:i', $downtime->start),
date('d.m.y', $downtime->end),
date('H:i', $downtime->end)
$this->formatDate($downtime->start),
$this->formatTime($downtime->start),
$this->formatDate($downtime->end),
$this->formatTime($downtime->end)
); ?>
<?php else: ?>
<?= sprintf(
$this->isService
? $this->translate('This fixed service downtime has been scheduled to start on %s at %s and to end on %s at %s.')
: $this->translate('This fixed host downtime has been scheduled to start on %s at %s and to end on %s at %s.'),
date('d.m.y', $downtime->scheduled_start),
date('H:i', $downtime->scheduled_start),
date('d.m.y', $downtime->scheduled_end),
date('H:i', $downtime->scheduled_end)
$this->formatDate($downtime->start),
$this->formatTime($downtime->start),
$this->formatDate($downtime->end),
$this->formatTime($downtime->end)
); ?>
<?php endif ?>
<?php endif ?>
@ -91,4 +82,4 @@
)
) ?>
<?php endif ?>
</p>
</p>

View File

@ -6,7 +6,7 @@ use Icinga\Module\Monitoring\Object\Host;
<tr class="state <?= Host::getStateText($object->host_state); ?><?= $object->host_handled ? ' handled' : ''; ?>">
<td class="state">
<strong><?= Host::getStateText($object->host_state, true); ?></strong><br>
<?= $this->prefixedTimeSince($object->host_last_state_change, true); ?>
<?= $this->timeSince($object->host_last_state_change); ?>
</td>
<td>
<?= $this->iconImage()->host($object) ?>

View File

@ -7,7 +7,7 @@ use Icinga\Module\Monitoring\Object\Service;
<tr class="state <?= Host::getStateText($object->host_state); ?><?= $object->host_handled ? ' handled' : ''; ?>">
<td class="state">
<strong><?= Host::getStateText($object->host_state, true); ?></strong><br>
<?= $this->prefixedTimeSince($object->host_last_state_change, true); ?>
<?= $this->timeSince($object->host_last_state_change) ?>
</td>
<td>
<?= $this->iconImage()->service($object) ?>
@ -25,7 +25,7 @@ use Icinga\Module\Monitoring\Object\Service;
<tr class="state <?= Service::getStateText($object->service_state); ?><?= $object->service_handled ? ' handled' : ''; ?>">
<td class="state">
<strong><?= Service::getStateText($object->service_state, true); ?></strong><br>
<?= $this->prefixedTimeSince($object->service_last_state_change, true); ?>
<?= $this->timeSince($object->service_last_state_change) ?>
</td>
<td>
<?= $this->iconImage()->host($object) ?>

View File

@ -27,15 +27,15 @@ if (! $this->compact): ?>
</tr>
<tr>
<th><?= $this->translate('Program Start Time') ?></th>
<td><?= $this->dateFormat()->formatDateTime($this->programStatus->program_start_time) ?></td>
<td><?= $this->formatDateTime($this->programStatus->program_start_time) ?></td>
</tr>
<tr>
<th><?= $this->translate('Last Status Update'); ?></th>
<td><?= sprintf($this->translate('%s ago'), $this->timeSince($this->programStatus->status_update_time)); ?></td>
<td><?= $this->timeAgo($this->programStatus->status_update_time); ?></td>
</tr>
<tr>
<th><?= $this->translate('Last External Command Check'); ?></th>
<td><?= sprintf($this->translate('%s ago'), $this->timeSince($this->programStatus->last_command_check)); ?></td>
<td><?= $this->timeAgo($this->programStatus->last_command_check); ?></td>
</tr>
<tr>
<th><?= $this->translate('Last Log File Rotation'); ?></th>
@ -66,7 +66,10 @@ if (! $this->compact): ?>
<?php if ((bool) $this->programStatus->is_currently_running === true): ?>
<div class="backend-running">
<?= sprintf(
$this->translate('Backend %s has been up and running with PID %d since %s'),
$this->translate(
'%1$s has been up and running with PID %2$d %3$s',
'Last format parameter represents the time running'
),
$this->backendName,
$this->programStatus->process_id,
$this->timeSince($this->programStatus->program_start_time)) ?>

View File

@ -20,7 +20,7 @@ if ($object->getType() === $object::TYPE_HOST) {
<?php if (isset($checkNowForm)) { // Form is unset if the current user lacks the respective permission
echo $checkNowForm;
} ?>
<?= $this->timeSince($object->last_check) ?>
<?= $this->timeAgo($object->last_check) ?>
</td>
</tr>
<tr>
@ -54,7 +54,8 @@ if ($object->getType() === $object::TYPE_HOST) {
)
);
}
} ?> <?= $this->timeUntil($object->next_check) ?>
} ?>
<?= $this->timeUntil($object->next_check) ?>
</td>
</tr>
<tr>

View File

@ -44,7 +44,7 @@ foreach ($object->comments as $comment) {
?>
<tr>
<th><?= $this->escape($comment->author); ?> (<?= $this->timeSince($comment->timestamp); ?>)</th>
<th><?= $this->escape($comment->author); ?> (<?= $this->timeAgo($comment->timestamp); ?>)</th>
<td data-base-target="_self">
<?php if (isset($delCommentForm)) { // Form is unset if the current user lacks the respective permission
$delCommentForm = clone $delCommentForm;

View File

@ -47,21 +47,27 @@ foreach ($object->downtimes as $downtime) {
) : $this->escape($downtime->comment);
if ((bool) $downtime->is_in_effect) {
$state = 'in downtime since ';
$time = $this->timeSince($downtime->start);
$state = sprintf(
$this->translate('in downtime %s', 'Last format parameter represents the time in downtime'),
$this->timeSince($downtime->start)
);
} else {
if ((bool) $downtime->is_fixed) {
$state = 'scheduled ';
$time = $this->timeUntil($downtime->start);
$state = sprintf(
$this->translate('scheduled %s', 'Last format parameter represents the time scheduled'),
$this->timeUntil($downtime->start)
);
} else {
$state = 'scheduled flexible ';
$time = $this->timeUntil($downtime->start);
$state = sprintf(
$this->translate('scheduled flexible %s', 'Last format parameter represents the time scheduled'),
$this->timeUntil($downtime->start)
);
}
}
?>
<tr>
<th><?= $this->escape($downtime->author_name); ?></th>
<th><?= $this->escape($downtime->author_name); ?> (<?= $this->timeAgo($downtime->entry_time); ?>)</th>
<td data-base-target="_self">
<?php if (isset($delDowntimeForm)) { // Form is unset if the current user lacks the respective permission
$delDowntimeForm = clone $delDowntimeForm;
@ -73,14 +79,7 @@ foreach ($object->downtimes as $downtime) {
);
echo $delDowntimeForm;
} ?>
<span class="sr-only"><?= $this->translate('Downtime'); ?></span>
<?=
$this->qlink(
$state,
'monitoring/downtime/show',
array('downtime_id' => $downtime->id),
array('data-base-target' => '_next')
) . $time ; ?> - <?= str_replace(array('\r\n', '\n'), '<br>', $commentText); ?>
<span class="sr-only"><?= $this->translate('Downtime'); ?></span><?= $state; ?> - <?= str_replace(array('\r\n', '\n'), '<br>', $commentText); ?>
</td>
</tr>
<?php } // endforeach ?>

View File

@ -1,59 +1,66 @@
<tr>
<th><?= $this->translate('Notifications') ?></th>
<td>
<?php if ($this->hasPermission('monitoring/command/send-custom-notification')) {
if ($object->getType() === $object::TYPE_HOST) {
$ackLink = $this->href(
'monitoring/host/send-custom-notification',
array('host' => $object->getName())
);
} else {
$ackLink = $this->href(
'monitoring/service/send-custom-notification',
array('host' => $object->getHost()->getName(), 'service' => $object->getName())
);
}
?>
<?= $this->qlink(
$this->translate('Send notification'),
$ackLink,
null,
array(
'icon' => 'bell',
'data-base-target' => '_self',
'title' => $this->translate(
'Send a custom notification, share information about the'
. ' object to contacts.'
)
)
) ?><br />
<?php } ?>
<?php
// We are not interested in notifications for OK or pending objects
if (! in_array((int) $object->state, array(0, 99))) {
if ($object->current_notification_number > 0) {
if ((int) $object->current_notification_number === 1) {
$msg = sprintf(
$this->translate('A notication has been sent for this issue %s ago'),
$this->timeSince($object->last_notification)
);
} else {
$msg = sprintf(
$this->translate('%s notications have been sent for this issue'),
$object->current_notification_number
) . '<br />' . sprintf(
$this->translate('The last one occured %s ago'),
$this->timeSince($object->last_notification)
);
<th><?= $this->translate('Notifications') ?></th>
<td>
<?php
/** @var \Icinga\Module\Monitoring\Object\MonitoredObject $object */
if ($this->hasPermission('monitoring/command/send-custom-notification')) {
if ($object->getType() === $object::TYPE_HOST) {
/** @var \Icinga\Module\Monitoring\Object\Host $object */
echo $this->qlink(
$this->translate('Send notification'),
'monitoring/host/send-custom-notification',
array('host_name' => $object->getName()),
array(
'icon' => 'bell',
'data-base-target' => '_self',
'title' => $this->translate(
'Send a custom notification to contacts responsible for this host'
)
)
);
} else {
/** @var \Icinga\Module\Monitoring\Object\Service $object */
echo $this->qlink(
$this->translate('Send notification'),
'monitoring/service/send-custom-notification',
array('host_name' => $object->getHost()->getName(), 'service_description' => $object->getName()),
array(
'icon' => 'bell',
'data-base-target' => '_self',
'title' => $this->translate(
'Send a custom notification to contacts responsible for this service'
)
)
);
}
if (! in_array((int) $object->state, array(0, 99))) {
echo '<br />';
}
} elseif (in_array((int) $object->state, array(0, 99))) {
echo '&#45;';
}
echo $msg;
} else {
echo '('
. $this->translate('No notification has been sent for this issue')
. ')';
}
}
?>
</td>
// We are not interested in notifications for OK or pending objects
if (! in_array((int) $object->state, array(0, 99))) {
if ($object->current_notification_number > 0) {
if ((int) $object->current_notification_number === 1) {
$msg = sprintf(
$this->translate('A notification has been sent for this issue %s.'),
$this->timeAgo($object->last_notification)
);
} else {
$msg = sprintf(
$this->translate('%d notifications have been sent for this issue.'),
$object->current_notification_number
) . '<br />' . sprintf(
$this->translate('The last one was sent %s.'),
$this->timeAgo($object->last_notification)
);
}
} else {
$msg = $this->translate('No notification has been sent for this issue.');
}
echo $msg;
}
?>
</td>
</tr>

View File

@ -234,3 +234,11 @@ div.backend-not-running {
text-align: center;
padding: 0.1em;
}
td.state {
.time-ago,
.time-since,
.time-until {
text-transform: capitalize;
}
}

View File

@ -445,8 +445,9 @@ div.box.contents.zero {
div.box.contents.zero span {
font-weight: bold;
line-height: 2em;
color: white;
color: #666;
}
div.box.contents.zero h3 {
@ -454,7 +455,7 @@ div.box.contents.zero h3 {
font-size: 12em;
line-height: 1em;
color: white;
color: #666;
}
div.box.ok_hosts.state_up {

View File

@ -577,70 +577,60 @@
);
},
/**
* Refresh partial time counters
*
* This function runs every second.
*/
refreshTimeSince: function () {
$('.timesince').each(function (idx, el) {
// todo remove after replace timeSince
var mp = el.innerHTML.match(/^(.*?)(-?\d+)d\s(-?\d+)h/);
if (mp !== null) {
return true;
}
var m = el.innerHTML.match(/^(.*?)(-?\d+)(.+\s)(-?\d+)(.+)/);
if (m !== null) {
var nm = parseInt(m[2]);
var ns = parseInt(m[4]);
if (ns < 59) {
ns++;
$('.time-ago, .time-since').each(function (idx, el) {
var partialTime = /(\d{1,2})m (\d{1,2})s/.exec(el.innerHTML);
if (partialTime !== null) {
var minute = parseInt(partialTime[1], 10),
second = parseInt(partialTime[2], 10);
if (second < 59) {
++second;
} else {
ns = 0;
nm++;
++minute;
second = 0;
}
$(el).html(m[1] + nm + m[3] + ns + m[5]);
el.innerHTML = el.innerHTML.substr(0, partialTime.index) + minute.toString() + 'm '
+ second.toString() + 's' + el.innerHTML.substr(partialTime.index + partialTime[0].length);
}
});
$('.timeuntil').each(function (idx, el) {
// todo remove after replace timeUntil
var mp = el.innerHTML.match(/^(.*?)(-?\d+)d\s(-?\d+)h/);
if (mp !== null) {
return true;
}
var m = el.innerHTML.match(/^(.*?)(-?\d+)(.+\s)(-?\d+)(.+)/);
if (m !== null) {
var nm = parseInt(m[2]);
var ns = parseInt(m[4]);
var signed = '';
var sec = 0;
if (nm < 0) {
signed = '-';
nm = nm * -1;
sec = nm * 60 + ns;
sec++;
} else if (nm == 0 && ns == 0) {
signed = '-';
sec = 1;
} else if (nm == 0 && m[2][0] == '-') {
signed = '-';
sec = ns;
sec++;
} else if (nm == 0 && m[2][0] != '-') {
sec = ns;
sec--;
$('.time-until').each(function (idx, el) {
var partialTime = /(-?)(\d{1,2})m (\d{1,2})s/.exec(el.innerHTML);
if (partialTime !== null) {
var minute = parseInt(partialTime[2], 10),
second = parseInt(partialTime[3], 10),
invert = partialTime[1];
if (invert.length) {
// Count up because partial time is negative
if (second < 59) {
++second;
} else {
++minute;
second = 0;
}
} else {
signed = '';
sec = nm * 60 + ns;
sec--;
// Count down because partial time is positive
if (second === 0) {
if (minute === 0) {
// Invert counter
minute = 0;
second = 1;
invert = '-';
} else {
--minute;
second = 59;
}
} else {
--second;
}
}
nm = Math.floor(sec/60);
ns = sec - nm * 60;
$(el).html(m[1] + signed + nm + m[3] + ns + m[5]);
el.innerHTML = el.innerHTML.substr(0, partialTime.index) + invert + minute.toString() + 'm '
+ second.toString() + 's' + el.innerHTML.substr(partialTime.index + partialTime[0].length);
}
});
},

View File

@ -1,69 +0,0 @@
<?php
/* Icinga Web 2 | (c) 2013-2015 Icinga Development Team | GPLv2+ */
namespace Tests\Icinga\Util;
use DateTimeZone;
use Icinga\Test\BaseTestCase;
use Icinga\Util\DateTimeFactory;
class DateTimeFactoryTest extends BaseTestCase
{
/**
* @expectedException Icinga\Exception\ConfigurationError
*/
public function testWhetherSetConfigThrowsAnExceptionWhenTimezoneMissing()
{
DateTimeFactory::setConfig(array());
}
/**
* @expectedException Icinga\Exception\ConfigurationError
*/
public function testWhetherSetConfigThrowsAnExceptionWhenTimezoneInvalid()
{
DateTimeFactory::setConfig(array('timezone' => 'invalid'));
}
public function testWhetherParseWorksWithASpecificTimezone()
{
$dt = DateTimeFactory::parse('17-04-14 17:00', 'd-m-y H:i', new DateTimeZone('Europe/Berlin'));
$dt->setTimezone(new DateTimeZone('UTC'));
$this->assertEquals(
'15',
$dt->format('H'),
'DateTimeFactory::parse does not properly parse a given datetime or does not respect the given timezone'
);
}
public function testWhetherParseWorksWithoutASpecificTimezone()
{
$this->assertEquals(
'15',
DateTimeFactory::parse('17-04-14 15:00', 'd-m-y H:i')->format('H'),
'DateTimeFactory::parse does not properly parse a given datetime'
);
}
public function testWhetherCreateWorksWithASpecificTimezone()
{
$dt = DateTimeFactory::create('2014-04-17 5PM', new DateTimeZone('Europe/Berlin'));
$dt->setTimezone(new DateTimeZone('UTC'));
$this->assertEquals(
'15',
$dt->format('H'),
'DateTimeFactory::create does not properly parse a given datetime or does not respect the given timezone'
);
}
public function testWhetherCreateWorksWithoutASpecificTimezone()
{
$this->assertEquals(
'15',
DateTimeFactory::create('2014-04-17 3PM')->format('H'),
'DateTimeFactory::create does not properly parse a given datetime'
);
}
}

View File

@ -1,101 +0,0 @@
<?php
/* Icinga Web 2 | (c) 2013-2015 Icinga Development Team | GPLv2+ */
namespace Tests\Icinga\Web;
use DateTime;
use Icinga\Test\BaseTestCase;
use Icinga\Web\View\DateTimeRenderer;
class DateTimeRendererTest extends BaseTestCase
{
public function testWhetherCreateCreatesDateTimeRenderer()
{
$dateTime = new DateTime();
$dt = DateTimeRenderer::create($dateTime);
$this->assertInstanceOf(
'Icinga\Web\View\DateTimeRenderer',
$dt,
'Dashboard::create() could not create DateTimeRenderer'
);
}
/**
* @depends testWhetherCreateCreatesDateTimeRenderer
*/
public function testWhetherIsDateTimeReturnsRightType()
{
$dateTime = new DateTime('+1 day');
$dt = DateTimeRenderer::create($dateTime);
$this->assertTrue(
$dt->isDateTime(),
'Dashboard::isDateTime() returns wrong type'
);
}
/**
* @depends testWhetherCreateCreatesDateTimeRenderer
*/
public function testWhetherIsTimeReturnsRightType()
{
$dateTime = new DateTime('+1 hour');
$dt = DateTimeRenderer::create($dateTime);
$this->assertTrue(
$dt->isTime(),
'Dashboard::isTime() returns wrong type'
);
}
/**
* @depends testWhetherCreateCreatesDateTimeRenderer
*/
public function testWhetherIsTimespanReturnsRightType()
{
$dateTime = new DateTime('+1 minute');
$dt = DateTimeRenderer::create($dateTime);
$this->assertTrue(
$dt->isTimespan(),
'Dashboard::isTimespan() returns wrong type'
);
}
/**
* @depends testWhetherCreateCreatesDateTimeRenderer
*/
public function testWhetherNormalizeReturnsNormalizedDateTime()
{
$dateTime = time();
$dt = DateTimeRenderer::normalize($dateTime);
$this->assertInstanceOf(
'DateTime',
$dt,
'Dashboard::normalize() returns wrong instance'
);
}
/**
* @depends testWhetherCreateCreatesDateTimeRenderer
*/
public function testWhetherRenderReturnsRightText()
{
$dateTime = new DateTime('+1 minute');
$dt = DateTimeRenderer::create($dateTime);
$text = $dt->render(
'#1 The service is down since %s',
'#2 The service is down since %s o\'clock.',
'#3 The service is down for %s.'
);
$this->assertRegExp(
'/#3/',
$text,
'Dashboard::render() returns wrong text'
);
}
}