Merge pull request #4640 from Icinga/php-81-support

PHP 8.1 Support
This commit is contained in:
Johannes Meyer 2022-03-24 15:40:01 +01:00 committed by GitHub
commit 42997566bb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
91 changed files with 383 additions and 1326 deletions

View File

@ -17,14 +17,8 @@ jobs:
strategy:
fail-fast: false
matrix:
php: ['5.6', '7.0', '7.1', '7.2', '7.3', '7.4', '8.0']
php: ['7.2', '7.3', '7.4', '8.0', '8.1']
os: ['ubuntu-latest']
include:
- php: '5.6'
allow_failure: true
phplint_options: "--exclude='{(?>.*/)?test/php/.*}' --exclude=library/Icinga/Test/BaseTestCase.php"
- php: '7.0'
allow_failure: true
steps:
- name: Checkout code base
@ -52,16 +46,16 @@ jobs:
runs-on: ${{ matrix.os }}
env:
phpunit-version: 9.5.4
phpunit-version: 9.5
strategy:
fail-fast: false
matrix:
php: ['7.2', '7.3', '7.4', '8.0']
php: ['7.2', '7.3', '7.4', '8.0', '8.1']
os: ['ubuntu-latest']
include:
- php: '7.2'
phpunit-version: 8.5.15
phpunit-version: 8.5
services:
mysql:

View File

@ -1,6 +1,6 @@
# Icinga Web 2
[![PHP Support](https://img.shields.io/badge/php-%3E%3D%205.6-777BB4?logo=PHP)](https://php.net/)
[![PHP Support](https://img.shields.io/badge/php-%3E%3D%207.2-777BB4?logo=PHP)](https://php.net/)
![Build Status](https://github.com/icinga/icingaweb2/workflows/PHP%20Tests/badge.svg?branch=master)
[![Github Tag](https://img.shields.io/github/tag/Icinga/icingaweb2.svg)](https://github.com/Icinga/icingaweb2)

View File

@ -41,7 +41,7 @@ class ApplicationStateController extends Controller
setcookie(
'icingaweb2-session',
$now,
null,
0,
$params['path'],
$params['domain'],
$params['secure'],

View File

@ -448,7 +448,7 @@ class RoleForm extends RepositoryForm
$b = array_shift($bParts);
} while ($a === $b);
return strnatcmp($a, $b);
return strnatcmp($a ?? '', $b ?? '');
});
}

View File

@ -38,8 +38,7 @@ thoroughly.
* [Icinga 2](https://icinga.com/products/icinga-2/) with the IDO database backend (MySQL or PostgreSQL)
* A web server, e.g. Apache or Nginx
* PHP version >= 7.3
* Older versions (5.6+) are only supported up until Icinga Web v2.11
* PHP version >= 7.2
### Optional Requirements
* For exports to PDF also the following PHP modules are required: mbstring, GD, Imagick
@ -388,8 +387,7 @@ You will need to install certain dependencies depending on your setup:
* [Icinga 2](https://icinga.com/products/icinga-2/) with the IDO database backend (MySQL or PostgreSQL)
* A web server, e.g. Apache or Nginx
* PHP version >= 7.3
* Older versions (5.6+) are only supported up until version 2.11
* PHP version >= 7.2
* [Icinga PHP Library (ipl)](https://github.com/Icinga/icinga-php-library) (>= 0.8)
* [Icinga PHP Thirdparty](https://github.com/Icinga/icinga-php-thirdparty) (>= 0.10)
* The following PHP modules must be installed: cURL, json, gettext, fileinfo, intl, dom, OpenSSL and xml

View File

@ -232,7 +232,7 @@ class Benchmark
round(($m->timestamp - floor($m->timestamp)) * 1000)
);
$vals = array(
date('H:i:s', $m->timestamp) . '.' . $micro,
date('H:i:s', (int) $m->timestamp) . '.' . $micro,
$m->message
);

View File

@ -119,11 +119,11 @@ class Cli extends ApplicationBootstrap
if ($this->params->shift('autocomplete')) {
$this->params->unshift('autocomplete');
}
$watch = $this->params->shift('watch');
if ($watch === true) {
$watch = 5;
}
if (preg_match('~^\d+$~', $watch)) {
$this->watchTimeout = 5;
} elseif (is_numeric($watch)) {
$this->watchTimeout = (int) $watch;
}

View File

@ -122,7 +122,7 @@ class Config implements Countable, Iterator, Selectable
*
* @return int
*/
public function count()
public function count(): int
{
return $this->select()->count();
}
@ -130,11 +130,11 @@ class Config implements Countable, Iterator, Selectable
/**
* Reset the current position of the internal config object
*
* @return ConfigObject
* @return void
*/
public function rewind()
public function rewind(): void
{
return $this->config->rewind();
$this->config->rewind();
}
/**
@ -142,7 +142,7 @@ class Config implements Countable, Iterator, Selectable
*
* @return ConfigObject
*/
public function current()
public function current(): ConfigObject
{
return $this->config->current();
}
@ -152,7 +152,7 @@ class Config implements Countable, Iterator, Selectable
*
* @return bool
*/
public function valid()
public function valid(): bool
{
return $this->config->valid();
}
@ -162,7 +162,7 @@ class Config implements Countable, Iterator, Selectable
*
* @return string
*/
public function key()
public function key(): string
{
return $this->config->key();
}
@ -170,11 +170,11 @@ class Config implements Countable, Iterator, Selectable
/**
* Advance the position of the current iteration and return the new section
*
* @return ConfigObject
* @return void
*/
public function next()
public function next(): void
{
return $this->config->next();
$this->config->next();
}
/**

View File

@ -34,26 +34,17 @@ class TicketPattern implements ArrayAccess
*/
protected $pattern;
/**
* {@inheritdoc}
*/
public function offsetExists($offset)
public function offsetExists($offset): bool
{
return isset($this->match[$offset]);
}
/**
* {@inheritdoc}
*/
public function offsetGet($offset)
public function offsetGet($offset): ?string
{
return array_key_exists($offset, $this->match) ? $this->match[$offset] : null;
}
/**
* {@inheritdoc}
*/
public function offsetSet($offset, $value)
public function offsetSet($offset, $value): void
{
if ($offset === null) {
$this->match[] = $value;
@ -62,10 +53,7 @@ class TicketPattern implements ArrayAccess
}
}
/**
* {@inheritdoc}
*/
public function offsetUnset($offset)
public function offsetUnset($offset): void
{
unset($this->match[$offset]);
}

View File

@ -6,6 +6,7 @@ namespace Icinga\Application;
use ArrayIterator;
use IteratorAggregate;
use Icinga\Application\Libraries\Library;
use Traversable;
class Libraries implements IteratorAggregate
{
@ -17,7 +18,7 @@ class Libraries implements IteratorAggregate
*
* @return ArrayIterator
*/
public function getIterator()
public function getIterator(): Traversable
{
return new ArrayIterator($this->libraries);
}

View File

@ -14,7 +14,7 @@ use ipl\I18n\StaticTranslator;
*
* @return string
*/
function N_($messageId)
function N_(string $messageId): string
{
return $messageId;
}
@ -30,7 +30,7 @@ if (extension_loaded('gettext')) {
/**
* @see Translator::translate() For the function documentation.
*/
function t($messageId, $context = null)
function t(string $messageId, ?string $context = null): string
{
return StaticTranslator::$instance->translate($messageId, $context);
}
@ -38,7 +38,7 @@ if (extension_loaded('gettext')) {
/**
* @see Translator::translateInDomain() For the function documentation.
*/
function mt($domain, $messageId, $context = null)
function mt(string $domain, string $messageId, ?string $context = null): string
{
return StaticTranslator::$instance->translateInDomain($domain, $messageId, $context);
}
@ -46,21 +46,21 @@ if (extension_loaded('gettext')) {
/**
* @see Translator::translatePlural() For the function documentation.
*/
function tp($messageId, $messageId2, $number, $context = null)
function tp(string $messageId, string $messageId2, ?int $number, ?string $context = null): string
{
return StaticTranslator::$instance->translatePlural($messageId, $messageId2, $number, $context);
return StaticTranslator::$instance->translatePlural($messageId, $messageId2, $number ?? 0, $context);
}
/**
* @see Translator::translatePluralInDomain() For the function documentation.
*/
function mtp($domain, $messageId, $messageId2, $number, $context = null)
function mtp(string $domain, string $messageId, string $messageId2, ?int $number, ?string $context = null): string
{
return StaticTranslator::$instance->translatePluralInDomain(
$domain,
$messageId,
$messageId2,
$number,
$number ?? 0,
$context
);
}
@ -70,7 +70,7 @@ if (extension_loaded('gettext')) {
/**
* @see Translator::translate() For the function documentation.
*/
function t($messageId, $context = null)
function t(string $messageId, ?string $context = null): string
{
return $messageId;
}
@ -78,7 +78,7 @@ if (extension_loaded('gettext')) {
/**
* @see Translator::translate() For the function documentation.
*/
function mt($domain, $messageId, $context = null)
function mt(string $domain, string $messageId, ?string $context = null): string
{
return $messageId;
}
@ -86,7 +86,7 @@ if (extension_loaded('gettext')) {
/**
* @see Translator::translatePlural() For the function documentation.
*/
function tp($messageId, $messageId2, $number, $context = null)
function tp(string $messageId, string $messageId2, ?int $number, ?string $context = null): string
{
if ((int) $number !== 1) {
return $messageId2;
@ -98,7 +98,7 @@ if (extension_loaded('gettext')) {
/**
* @see Translator::translatePlural() For the function documentation.
*/
function mtp($domain, $messageId, $messageId2, $number, $context = null)
function mtp(string $domain, string $messageId, string $messageId2, ?int $number, ?string $context = null): string
{
if ((int) $number !== 1) {
return $messageId2;

View File

@ -331,7 +331,7 @@ class Auth
setcookie(
'icingaweb2-session',
time(),
null,
0,
$params['path'],
$params['domain'],
$params['secure'],

View File

@ -184,12 +184,12 @@ class AuthChain implements Authenticatable, Iterator
/**
* Rewind the chain
*
* @return ConfigObject
* @return void
*/
public function rewind()
public function rewind(): void
{
$this->currentBackend = null;
return $this->config->rewind();
$this->config->rewind();
}
/**
@ -197,7 +197,7 @@ class AuthChain implements Authenticatable, Iterator
*
* @return UserBackendInterface
*/
public function current()
public function current(): UserBackendInterface
{
return $this->currentBackend;
}
@ -207,7 +207,7 @@ class AuthChain implements Authenticatable, Iterator
*
* @return string
*/
public function key()
public function key(): string
{
return $this->config->key();
}
@ -215,11 +215,11 @@ class AuthChain implements Authenticatable, Iterator
/**
* Move forward to the next user backend config
*
* @return ConfigObject
* @return void
*/
public function next()
public function next(): void
{
return $this->config->next();
$this->config->next();
}
/**
@ -228,7 +228,7 @@ class AuthChain implements Authenticatable, Iterator
*
* @return bool
*/
public function valid()
public function valid(): bool
{
if (! $this->config->valid()) {
// Stop when there are no more backends to check

View File

@ -203,6 +203,10 @@ class DbUserBackend extends DbRepository implements UserBackendInterface, Inspec
$lob = stream_get_contents($lob);
}
if ($lob === null) {
return '';
}
return $this->ds->getDbType() === 'pgsql' ? pg_unescape_bytea($lob) : $lob;
}

View File

@ -88,7 +88,7 @@ class LdapUserBackend extends LdapRepository implements UserBackendInterface, Do
*/
public function setBaseDn($baseDn)
{
if (($baseDn = trim($baseDn))) {
if ($baseDn && ($baseDn = trim($baseDn))) {
$this->baseDn = $baseDn;
}
@ -160,7 +160,7 @@ class LdapUserBackend extends LdapRepository implements UserBackendInterface, Do
*/
public function setFilter($filter)
{
if (($filter = trim($filter))) {
if ($filter && ($filter = trim($filter))) {
if ($filter[0] === '(') {
$filter = substr($filter, 1, -1);
}
@ -195,9 +195,7 @@ class LdapUserBackend extends LdapRepository implements UserBackendInterface, Do
*/
public function setDomain($domain)
{
$domain = trim($domain);
if (strlen($domain)) {
if ($domain && ($domain = trim($domain))) {
$this->domain = $domain;
}

View File

@ -169,7 +169,7 @@ class LdapUserGroupBackend extends LdapRepository implements Inspectable, UserGr
*/
public function setUserBaseDn($baseDn)
{
if (($baseDn = trim($baseDn))) {
if ($baseDn && ($baseDn = trim($baseDn))) {
$this->userBaseDn = $baseDn;
}
@ -195,7 +195,7 @@ class LdapUserGroupBackend extends LdapRepository implements Inspectable, UserGr
*/
public function setGroupBaseDn($baseDn)
{
if (($baseDn = trim($baseDn))) {
if ($baseDn && ($baseDn = trim($baseDn))) {
$this->groupBaseDn = $baseDn;
}
@ -336,7 +336,7 @@ class LdapUserGroupBackend extends LdapRepository implements Inspectable, UserGr
*/
public function setUserFilter($filter)
{
if (($filter = trim($filter))) {
if ($filter && ($filter = trim($filter))) {
if ($filter[0] === '(') {
$filter = substr($filter, 1, -1);
}
@ -366,7 +366,7 @@ class LdapUserGroupBackend extends LdapRepository implements Inspectable, UserGr
*/
public function setGroupFilter($filter)
{
if (($filter = trim($filter))) {
if ($filter && ($filter = trim($filter))) {
$this->groupFilter = $filter;
}
@ -431,9 +431,7 @@ class LdapUserGroupBackend extends LdapRepository implements Inspectable, UserGr
*/
public function setDomain($domain)
{
$domain = trim($domain);
if (strlen($domain)) {
if ($domain && ($domain = trim($domain))) {
$this->domain = $domain;
}

View File

@ -131,7 +131,7 @@ class SVGRenderer
'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'
);
$this->document = $implementation->createDocument(null, null, $docType);
$this->document = $implementation->createDocument(null, '', $docType);
$this->svg = $this->createOuterBox();
$this->document->appendChild($this->svg);
}

View File

@ -68,10 +68,16 @@ class CommentParser
public function dump()
{
$res = $this->title . "\n" . str_repeat('=', strlen($this->title)) . "\n\n";
if ($this->title) {
$res = $this->title . "\n" . str_repeat('=', strlen($this->title)) . "\n\n";
} else {
$res = '';
}
foreach ($this->paragraphs as $p) {
$res .= wordwrap($p, 72) . "\n\n";
}
return $res;
}
}

View File

@ -276,6 +276,10 @@ class Loader
protected function searchMatch($needle, $haystack)
{
if ($needle === null) {
$needle = '';
}
$this->lastSuggestions = preg_grep(sprintf('/^%s.*$/', preg_quote($needle, '/')), $haystack);
$match = array_search($needle, $haystack, true);
if (false !== $match) {
@ -358,7 +362,7 @@ class Loader
} elseif (! empty($step['object'])) {
$object = (string) $step['object'] . $step['type'];
}
if (is_array($step['args'])) {
if (isset($step['args']) && is_array($step['args'])) {
foreach ($step['args'] as & $arg) {
if (is_object($arg)) {
$arg = sprintf('[%s]', get_class($arg));

View File

@ -50,11 +50,11 @@ class ConfigObject extends ArrayDatasource implements Iterator, ArrayAccess
/**
* Reset the current position of $this->data
*
* @return mixed
* @return void
*/
public function rewind()
public function rewind(): void
{
return reset($this->data);
reset($this->data);
}
/**
@ -62,6 +62,7 @@ class ConfigObject extends ArrayDatasource implements Iterator, ArrayAccess
*
* @return mixed
*/
#[\ReturnTypeWillChange]
public function current()
{
return current($this->data);
@ -72,7 +73,7 @@ class ConfigObject extends ArrayDatasource implements Iterator, ArrayAccess
*
* @return bool
*/
public function valid()
public function valid(): bool
{
return key($this->data) !== null;
}
@ -80,9 +81,9 @@ class ConfigObject extends ArrayDatasource implements Iterator, ArrayAccess
/**
* Return the section's or property's name of the current iteration
*
* @return mixed
* @return string
*/
public function key()
public function key(): string
{
return key($this->data);
}
@ -90,11 +91,11 @@ class ConfigObject extends ArrayDatasource implements Iterator, ArrayAccess
/**
* Advance the position of the current iteration and return the new section's or property's value
*
* @return mixed
* @return void
*/
public function next()
public function next(): void
{
return next($this->data);
next($this->data);
}
/**
@ -153,7 +154,7 @@ class ConfigObject extends ArrayDatasource implements Iterator, ArrayAccess
*
* @return bool
*/
public function offsetExists($key)
public function offsetExists($key): bool
{
return isset($this->$key);
}
@ -163,8 +164,9 @@ class ConfigObject extends ArrayDatasource implements Iterator, ArrayAccess
*
* @param string $key The name of the property or section
*
* @return mixed|NULL The value or NULL in case $key does not exist
* @return ?mixed The value or NULL in case $key does not exist
*/
#[\ReturnTypeWillChange]
public function offsetGet($key)
{
return $this->get($key);
@ -178,7 +180,7 @@ class ConfigObject extends ArrayDatasource implements Iterator, ArrayAccess
*
* @throws ProgrammingError If the key is null
*/
public function offsetSet($key, $value)
public function offsetSet($key, $value): void
{
if ($key === null) {
throw new ProgrammingError('Appending values without an explicit key is not supported');
@ -192,7 +194,7 @@ class ConfigObject extends ArrayDatasource implements Iterator, ArrayAccess
*
* @param string $key The property or section to remove
*/
public function offsetUnset($key)
public function offsetUnset($key): void
{
unset($this->$key);
}

View File

@ -356,13 +356,13 @@ class DbQuery extends SimpleQuery
}
return '(' . implode(" $operator ", $sql) . ')';
} elseif ($sign === '=' && strpos($expression, '*') !== false) {
} elseif ($sign === '=' && $expression !== null && strpos($expression, '*') !== false) {
if ($expression === '*') {
return $col . ' IS NOT NULL';
}
return $col . ' LIKE ' . $this->escapeForSql($this->escapeWildcards($expression));
} elseif ($sign === '!=' && strpos($expression, '*') !== false) {
} elseif ($sign === '!=' && $expression !== null && strpos($expression, '*') !== false) {
if ($expression === '*') {
return $col . ' IS NULL';
}
@ -410,7 +410,7 @@ class DbQuery extends SimpleQuery
*
* @return int
*/
public function count()
public function count(): int
{
if ($this->count === null) {
$this->count = parent::count();

View File

@ -152,7 +152,10 @@ class FilterExpression extends Filter
*/
protected function strtolowerRecursive($var)
{
if ($var === null || is_scalar($var)) {
if ($var === null) {
return '';
}
if (is_scalar($var)) {
return strtolower($var);
}
if (is_array($var)) {
@ -206,7 +209,7 @@ class FilterExpression extends Filter
return false;
}
return (bool) preg_match($pattern, $rowValue);
return $rowValue !== null && preg_match($pattern, $rowValue);
}
public function andFilter(Filter $filter)

View File

@ -263,7 +263,7 @@ class FilterQueryString
$this->string = $string;
$this->length = strlen($string);
$this->length = $string ? strlen($string) : 0;
if ($this->length === 0) {
return Filter::matchAll();

View File

@ -165,7 +165,7 @@ class SimpleQuery implements QueryInterface, Queryable, Iterator
/**
* Start or rewind the iteration
*/
public function rewind()
public function rewind(): void
{
if ($this->iterator === null) {
$iterator = $this->ds->query($this);
@ -184,8 +184,9 @@ class SimpleQuery implements QueryInterface, Queryable, Iterator
/**
* Fetch and return the current row of this query's result
*
* @return object
* @return mixed
*/
#[\ReturnTypeWillChange]
public function current()
{
return $this->iterator->current();
@ -196,7 +197,7 @@ class SimpleQuery implements QueryInterface, Queryable, Iterator
*
* @return bool
*/
public function valid()
public function valid(): bool
{
$valid = $this->iterator->valid();
if ($valid && $this->peekAhead && $this->hasLimit() && $this->iteratorPosition + 1 === $this->getLimit()) {
@ -221,6 +222,7 @@ class SimpleQuery implements QueryInterface, Queryable, Iterator
*
* @return mixed
*/
#[\ReturnTypeWillChange]
public function key()
{
return $this->iterator->key();
@ -229,7 +231,7 @@ class SimpleQuery implements QueryInterface, Queryable, Iterator
/**
* Advance to the next row of this query's result
*/
public function next()
public function next(): void
{
$this->iterator->next();
$this->iteratorPosition += 1;
@ -376,7 +378,7 @@ class SimpleQuery implements QueryInterface, Queryable, Iterator
$column = $this->flippedColumns[$column];
}
$result = strcmp(strtolower($a->$column), strtolower($b->$column));
$result = strcmp(strtolower($a->$column ?: ''), strtolower($b->$column ?: ''));
if ($result === 0) {
return $this->compare($a, $b, ++$orderIndex);
}
@ -648,7 +650,7 @@ class SimpleQuery implements QueryInterface, Queryable, Iterator
*
* @return int
*/
public function count()
public function count(): int
{
$query = clone $this;
$query->limit(0, 0);

View File

@ -5,6 +5,7 @@ namespace Icinga\Data\Tree;
use IteratorAggregate;
use LogicException;
use Traversable;
/**
* A simple tree
@ -80,10 +81,9 @@ class SimpleTree implements IteratorAggregate
}
/**
* {@inheritdoc}
* @return TreeNodeIterator
*/
public function getIterator()
public function getIterator(): Traversable
{
return new TreeNodeIterator($this->sentinel);
}

View File

@ -28,59 +28,37 @@ class TreeNodeIterator implements RecursiveIterator
$this->children = new ArrayIterator($node->getChildren());
}
/**
* {@inheritdoc}
*/
public function current()
public function current(): TreeNode
{
return $this->children->current();
}
/**
* {@inheritdoc}
*/
public function key()
public function key(): int
{
return $this->children->key();
}
/**
* {@inheritdoc}
*/
public function next()
public function next(): void
{
$this->children->next();
}
/**
* {@inheritdoc}
*/
public function rewind()
public function rewind(): void
{
$this->children->rewind();
}
/**
* {@inheritdoc}
*/
public function valid()
public function valid(): bool
{
return $this->children->valid();
}
/**
* {@inheritdoc}
*/
public function hasChildren()
public function hasChildren(): bool
{
return $this->current()->hasChildren();
}
/**
* {@inheritdoc}
* @return TreeNodeIterator
*/
public function getChildren()
public function getChildren(): TreeNodeIterator
{
return new static($this->current());
}

View File

@ -48,7 +48,7 @@ class DateFormatter
{
$invert = false;
$now = time();
$time = (float) $time;
$time = (int) $time;
$diff = $time - $now;
if ($diff < 0) {
$diff = abs($diff);
@ -94,7 +94,7 @@ class DateFormatter
*/
public static function formatDate($date)
{
return date('Y-m-d', (float) $date);
return date('Y-m-d', (int) $date);
}
/**
@ -106,7 +106,7 @@ class DateFormatter
*/
public static function formatDateTime($dateTime)
{
return date('Y-m-d H:i:s', (float) $dateTime);
return date('Y-m-d H:i:s', (int) $dateTime);
}
/**
@ -141,7 +141,7 @@ class DateFormatter
*/
public static function formatTime($time)
{
return date('H:i:s', (float) $time);
return date('H:i:s', (int) $time);
}
/**

View File

@ -11,6 +11,7 @@ use Icinga\Exception\NotWritableError;
use InvalidArgumentException;
use RecursiveDirectoryIterator;
use RecursiveIteratorIterator;
use Traversable;
use UnexpectedValueException;
/**
@ -35,10 +36,17 @@ class LocalFileStorage implements StorageInterface
$this->baseDir = rtrim($baseDir, DIRECTORY_SEPARATOR);
}
public function getIterator()
public function getIterator(): Traversable
{
try {
return new LocalFileStorageIterator($this->baseDir);
return new RecursiveIteratorIterator(
new RecursiveDirectoryIterator(
$this->baseDir,
RecursiveDirectoryIterator::CURRENT_AS_FILEINFO
| RecursiveDirectoryIterator::KEY_AS_PATHNAME
| RecursiveDirectoryIterator::SKIP_DOTS
)
);
} catch (UnexpectedValueException $e) {
throw new NotReadableError('Couldn\'t read the directory "%s": %s', $this->baseDir, $e);
}

View File

@ -1,44 +0,0 @@
<?php
/* Icinga Web 2 | (c) 2017 Icinga Development Team | GPLv2+ */
namespace Icinga\File\Storage;
use RecursiveDirectoryIterator;
use RecursiveIteratorIterator;
/**
* @deprecated This class will be removed once we require PHP 5.6
*/
class LocalFileStorageIterator extends RecursiveIteratorIterator
{
/**
* Constructor
*
* @param string $baseDir
*/
public function __construct($baseDir)
{
parent::__construct(new RecursiveDirectoryIterator($baseDir, RecursiveDirectoryIterator::SKIP_DOTS));
}
public function key()
{
parent::key();
return $this->current();
}
public function current()
{
/** @var RecursiveDirectoryIterator $innerIterator */
$innerIterator = $this->getInnerIterator();
/** @var \SplFileInfo $current */
$current = parent::current();
$subPath = $innerIterator->getSubPath();
return $subPath === ''
? $current->getFilename()
: str_replace(DIRECTORY_SEPARATOR, '/', $subPath) . '/' . $current->getFilename();
}
}

View File

@ -19,7 +19,7 @@ interface StorageInterface extends IteratorAggregate
*
* @throws NotReadableError If the file list can't be read
*/
public function getIterator();
public function getIterator(): Traversable;
/**
* Return whether the given file exists

View File

@ -44,7 +44,7 @@ class FileIterator extends EnumeratingFilterIterator
*
* @return array
*/
public function current()
public function current(): array
{
return $this->currentData;
}
@ -56,7 +56,7 @@ class FileIterator extends EnumeratingFilterIterator
*
* @throws FileReaderException If PHP failed parsing the PCRE pattern
*/
public function accept()
public function accept(): bool
{
$data = array();
$matched = preg_match(

View File

@ -89,7 +89,7 @@ class FileReader implements Selectable, Countable
*
* @return int
*/
public function count()
public function count(): int
{
if ($this->count === null) {
$this->count = iterator_count($this->iterate());

View File

@ -30,7 +30,7 @@ class LogFileIterator implements Iterator
/**
* Value for static::current()
*
* @var string
* @var array
*/
protected $current;
@ -68,40 +68,31 @@ class LogFileIterator implements Iterator
$this->fields = $fields;
}
public function rewind()
public function rewind(): void
{
$this->file->rewind();
$this->index = 0;
$this->nextMessage();
}
public function next()
public function next(): void
{
$this->file->next();
++$this->index;
$this->nextMessage();
}
/**
* @return string
*/
public function current()
public function current(): array
{
return $this->current;
}
/**
* @return int
*/
public function key()
public function key(): int
{
return $this->index;
}
/**
* @return boolean
*/
public function valid()
public function valid(): bool
{
return $this->valid;
}

View File

@ -61,31 +61,11 @@ abstract class LdapRepository extends Repository
*/
protected function getNormedAttribute($name)
{
$loweredName = strtolower($name);
$loweredName = strtolower($name ?? '');
if (array_key_exists($loweredName, $this->normedAttributes)) {
return $this->normedAttributes[$loweredName];
}
return $name;
}
/**
* Return whether the given object DN is related to the given base DN
*
* Will use the current connection's root DN if $baseDn is not given.
*
* @deprecated This was only used by LdapUserGroupBackend::isMemberAttributeAmbiguous
* It will be removed with 2.6.0!
*
* @param string $dn The object DN to check
* @param string $baseDn The base DN to compare the object DN with
*
* @return bool
*/
protected function isRelatedDn($dn, $baseDn = null)
{
$normalizedDn = strtolower(join(',', array_map('trim', explode(',', $dn))));
$normalizedBaseDn = strtolower(join(',', array_map('trim', explode(',', $baseDn ?: $this->ds->getDn()))));
return strpos($normalizedDn, $normalizedBaseDn) !== false;
}
}

View File

@ -344,7 +344,9 @@ class RepositoryQuery implements QueryInterface, SortRules, FilterColumns, Itera
}
}
$baseDirection = strtoupper($sortColumns['order']) === static::SORT_DESC ? static::SORT_DESC : static::SORT_ASC;
$baseDirection = isset($sortColumns['order']) && strtoupper($sortColumns['order']) === static::SORT_DESC
? static::SORT_DESC
: static::SORT_ASC;
foreach ($sortColumns['columns'] as $column) {
list($column, $specificDirection) = $this->splitOrder($column);
@ -690,7 +692,7 @@ class RepositoryQuery implements QueryInterface, SortRules, FilterColumns, Itera
*
* @return int
*/
public function count()
public function count(): int
{
return $this->query->count();
}
@ -708,7 +710,7 @@ class RepositoryQuery implements QueryInterface, SortRules, FilterColumns, Itera
/**
* Start or rewind the iteration
*/
public function rewind()
public function rewind(): void
{
if ($this->iterator === null) {
if (! $this->hasOrder()) {
@ -735,8 +737,9 @@ class RepositoryQuery implements QueryInterface, SortRules, FilterColumns, Itera
/**
* Fetch and return the current row of this query's result
*
* @return object
* @return mixed
*/
#[\ReturnTypeWillChange]
public function current()
{
$row = $this->iterator->current();
@ -763,7 +766,7 @@ class RepositoryQuery implements QueryInterface, SortRules, FilterColumns, Itera
*
* @return bool
*/
public function valid()
public function valid(): bool
{
if (! $this->iterator->valid()) {
Benchmark::measure('Query result iteration finished');
@ -778,6 +781,7 @@ class RepositoryQuery implements QueryInterface, SortRules, FilterColumns, Itera
*
* @return mixed
*/
#[\ReturnTypeWillChange]
public function key()
{
return $this->iterator->key();
@ -786,7 +790,7 @@ class RepositoryQuery implements QueryInterface, SortRules, FilterColumns, Itera
/**
* Advance to the next row of this query's result
*/
public function next()
public function next(): void
{
$this->iterator->next();
}

View File

@ -432,9 +432,7 @@ class User
*/
public function setDomain($domain)
{
$domain = trim($domain);
if (strlen($domain)) {
if ($domain && ($domain = trim($domain))) {
$this->domain = $domain;
}

View File

@ -49,7 +49,7 @@ class Preferences implements Countable
*
* @return int The number of preferences
*/
public function count()
public function count(): int
{
return count($this->preferences);
}

View File

@ -50,7 +50,7 @@ class DirectoryIterator implements RecursiveIterator
/**
* Current key
*
* @var string
* @var string|false
*/
private $key;
@ -122,35 +122,23 @@ class DirectoryIterator implements RecursiveIterator
return is_dir($path) && is_readable($path);
}
/**
* {@inheritdoc}
*/
public function hasChildren()
public function hasChildren(): bool
{
return static::isReadable($this->current);
}
/**
* {@inheritdoc}
*/
public function getChildren()
public function getChildren(): DirectoryIterator
{
return new static($this->current, $this->extension, $this->flags);
}
/**
* {@inheritdoc}
*/
#[\ReturnTypeWillChange]
public function current()
{
return $this->current;
}
/**
* {@inheritdoc}
*/
public function next()
public function next(): void
{
do {
$this->files->next();
@ -200,26 +188,18 @@ class DirectoryIterator implements RecursiveIterator
$this->key = $file;
}
/**
* {@inheritdoc}
*/
#[\ReturnTypeWillChange]
public function key()
{
return $this->key;
}
/**
* {@inheritdoc}
*/
public function valid()
public function valid(): bool
{
return $this->current !== false;
}
/**
* {@inheritdoc}
*/
public function rewind()
public function rewind(): void
{
if ($this->files === null) {
$files = scandir($this->path);

View File

@ -17,19 +17,13 @@ abstract class EnumeratingFilterIterator extends FilterIterator
*/
private $index;
/**
* @return void
*/
public function rewind()
public function rewind(): void
{
parent::rewind();
$this->index = 0;
}
/**
* @return int
*/
public function key()
public function key(): int
{
return $this->index++;
}

View File

@ -114,9 +114,7 @@ class File extends SplFileObject
}
}
/**
* @see SplFileObject::fwrite()
*/
#[\ReturnTypeWillChange]
public function fwrite($str, $length = null)
{
$this->assertOpenForWriting();
@ -126,10 +124,7 @@ class File extends SplFileObject
return $retVal;
}
/**
* @see SplFileObject::ftruncate()
*/
public function ftruncate($size)
public function ftruncate($size): bool
{
$this->assertOpenForWriting();
$this->setupErrorHandler();
@ -138,9 +133,7 @@ class File extends SplFileObject
return $retVal;
}
/**
* @see SplFileObject::ftell()
*/
#[\ReturnTypeWillChange]
public function ftell()
{
$this->setupErrorHandler();
@ -149,10 +142,7 @@ class File extends SplFileObject
return $retVal;
}
/**
* @see SplFileObject::flock()
*/
public function flock($operation, &$wouldblock = null)
public function flock($operation, &$wouldblock = null): bool
{
$this->setupErrorHandler();
$retVal = parent::flock($operation, $wouldblock);
@ -160,9 +150,7 @@ class File extends SplFileObject
return $retVal;
}
/**
* @see SplFileObject::fgetc()
*/
#[\ReturnTypeWillChange]
public function fgetc()
{
$this->setupErrorHandler();
@ -171,10 +159,7 @@ class File extends SplFileObject
return $retVal;
}
/**
* @see SplFileObject::fflush()
*/
public function fflush()
public function fflush(): bool
{
$this->setupErrorHandler();
$retVal = parent::fflush();

View File

@ -19,6 +19,10 @@ class StringHelper
*/
public static function trimSplit($value, $delimiter = ',', $limit = null)
{
if ($value === null) {
return [];
}
if ($limit !== null) {
$exploded = explode($delimiter, $value, $limit);
} else {
@ -40,6 +44,10 @@ class StringHelper
*/
public static function cname($name, $separator = '_')
{
if ($name === null) {
return '';
}
return str_replace(' ', '', ucwords(str_replace($separator, ' ', strtolower($name))));
}
@ -54,6 +62,10 @@ class StringHelper
*/
public static function ellipsis($string, $maxLength, $ellipsis = '...')
{
if ($string === null) {
return '';
}
if (strlen($string) > $maxLength) {
return substr($string, 0, $maxLength - strlen($ellipsis)) . $ellipsis;
}
@ -72,6 +84,10 @@ class StringHelper
*/
public static function ellipsisCenter($string, $maxLength, $ellipsis = '...')
{
if ($string === null) {
return '';
}
$start = ceil($maxLength / 2.0);
$end = floor($maxLength / 2.0);
if (strlen($string) > $maxLength) {
@ -117,6 +133,10 @@ class StringHelper
*/
public static function endsWith($string, $suffix)
{
if ($string === null) {
return false;
}
$stringSuffix = substr($string, -strlen($suffix));
return $stringSuffix !== false ? $stringSuffix === $suffix : false;
}

View File

@ -5,6 +5,7 @@ namespace Icinga\Web;
use ArrayIterator;
use IteratorAggregate;
use Traversable;
/**
* Maintain a set of cookies
@ -23,7 +24,7 @@ class CookieSet implements IteratorAggregate
*
* @return ArrayIterator An iterator for traversing the cookies in this set
*/
public function getIterator()
public function getIterator(): Traversable
{
return new ArrayIterator($this->cookies);
}

View File

@ -47,59 +47,37 @@ class DomNodeIterator implements RecursiveIterator
$this->children = new IteratorIterator($node->childNodes);
}
/**
* {@inheritdoc}
*/
public function current()
public function current(): ?DOMNode
{
return $this->children->current();
}
/**
* {@inheritdoc}
*/
public function key()
public function key(): int
{
return $this->children->key();
}
/**
* {@inheritdoc}
*/
public function next()
public function next(): void
{
$this->children->next();
}
/**
* {@inheritdoc}
*/
public function rewind()
public function rewind(): void
{
$this->children->rewind();
}
/**
* {@inheritdoc}
*/
public function valid()
public function valid(): bool
{
return $this->children->valid();
}
/**
* {@inheritdoc}
*/
public function hasChildren()
public function hasChildren(): bool
{
return $this->current()->hasChildNodes();
}
/**
* {@inheritdoc}
* @return DomNodeIterator
*/
public function getChildren()
public function getChildren(): DomNodeIterator
{
return new static($this->current());
}

View File

@ -67,50 +67,32 @@ class Navigation implements ArrayAccess, Countable, IteratorAggregate
*/
protected $layout;
/**
* {@inheritdoc}
*/
public function offsetExists($offset)
public function offsetExists($offset): bool
{
return isset($this->items[$offset]);
}
/**
* {@inheritdoc}
*/
public function offsetGet($offset)
public function offsetGet($offset): ?NavigationItem
{
return isset($this->items[$offset]) ? $this->items[$offset] : null;
return $this->items[$offset] ?? null;
}
/**
* {@inheritdoc}
*/
public function offsetSet($offset, $value)
public function offsetSet($offset, $value): void
{
$this->items[$offset] = $value;
}
/**
* {@inheritdoc}
*/
public function offsetUnset($offset)
public function offsetUnset($offset): void
{
unset($this->items[$offset]);
}
/**
* {@inheritdoc}
*/
public function count()
public function count(): int
{
return count($this->items);
}
/**
* {@inheritdoc}
*/
public function getIterator()
public function getIterator(): Traversable
{
$this->order();
return new ArrayIterator($this->items);

View File

@ -13,6 +13,7 @@ use Icinga\Exception\IcingaException;
use Icinga\Exception\ProgrammingError;
use Icinga\Web\Navigation\Renderer\NavigationItemRenderer;
use Icinga\Web\Url;
use Traversable;
/**
* A navigation item
@ -171,9 +172,9 @@ class NavigationItem implements IteratorAggregate
}
/**
* {@inheritdoc}
* @return Navigation
*/
public function getIterator()
public function getIterator(): Traversable
{
return $this->getChildren();
}

View File

@ -165,52 +165,32 @@ class NavigationRenderer implements RecursiveIterator, NavigationRendererInterfa
return $this;
}
/**
* {@inheritdoc}
*/
public function getChildren()
public function getChildren(): NavigationRenderer
{
return new static($this->current()->getChildren(), $this->skipOuterElement);
}
/**
* {@inheritdoc}
*/
public function hasChildren()
public function hasChildren(): bool
{
return $this->current()->hasChildren();
}
/**
* {@inheritdoc}
*
* @return NavigationItem
*/
public function current()
public function current(): NavigationItem
{
return $this->iterator->current();
}
/**
* {@inheritdoc}
*/
public function key()
public function key(): int
{
return $this->iterator->key();
}
/**
* {@inheritdoc}
*/
public function next()
public function next(): void
{
$this->iterator->next();
}
/**
* {@inheritdoc}
*/
public function rewind()
public function rewind(): void
{
$this->iterator->rewind();
if (! $this->skipOuterElement) {
@ -218,10 +198,7 @@ class NavigationRenderer implements RecursiveIterator, NavigationRendererInterfa
}
}
/**
* {@inheritdoc}
*/
public function valid()
public function valid(): bool
{
$valid = $this->iterator->valid();
if (! $this->skipOuterElement && !$valid) {

View File

@ -121,34 +121,22 @@ class RecursiveNavigationRenderer extends RecursiveIteratorIterator implements N
return $this->getInnerIterator()->getHeading();
}
/**
* {@inheritdoc}
*/
public function beginIteration()
public function beginIteration(): void
{
$this->content[] = $this->getInnerIterator()->beginMarkup();
}
/**
* {@inheritdoc}
*/
public function endIteration()
public function endIteration(): void
{
$this->content[] = $this->getInnerIterator()->endMarkup();
}
/**
* {@inheritdoc}
*/
public function beginChildren()
public function beginChildren(): void
{
$this->content[] = $this->getInnerIterator()->beginChildrenMarkup($this->getDepth() + 1);
}
/**
* {@inheritdoc}
*/
public function endChildren()
public function endChildren(): void
{
$this->content[] = $this->getInnerIterator()->endChildrenMarkup();
$this->content[] = $this->getInnerIterator()->endItemMarkup();

View File

@ -73,7 +73,7 @@ class QueryAdapter implements Zend_Paginator_Adapter_Interface
*
* @return int
*/
public function count()
public function count(): int
{
if ($this->count === null) {
$this->count = $this->query->count();

View File

@ -389,12 +389,12 @@ class Response extends Zend_Controller_Response_Http
/** @var Cookie $cookie */
setcookie(
$cookie->getName(),
$cookie->getValue(),
$cookie->getExpire(),
$cookie->getValue() ?? '',
$cookie->getExpire() ?? 0,
$cookie->getPath(),
$cookie->getDomain(),
$cookie->getDomain() ?? '',
$cookie->isSecure(),
$cookie->isHttpOnly()
$cookie->isHttpOnly() ?? true
);
}
}

View File

@ -7,6 +7,7 @@ use Exception;
use ArrayIterator;
use Icinga\Exception\IcingaException;
use IteratorAggregate;
use Traversable;
/**
* Container for session values
@ -32,7 +33,7 @@ class SessionNamespace implements IteratorAggregate
*
* @return ArrayIterator
*/
public function getIterator()
public function getIterator(): Traversable
{
return new ArrayIterator($this->getAll());
}

View File

@ -104,7 +104,7 @@ class View extends Zend_View_Abstract
*/
public function escape($value)
{
return htmlspecialchars($value, ENT_COMPAT | ENT_SUBSTITUTE | ENT_HTML5, self::CHARSET, true);
return htmlspecialchars($value ?: '', ENT_COMPAT | ENT_SUBSTITUTE | ENT_HTML5, self::CHARSET, true);
}
/**

View File

@ -225,7 +225,7 @@ class SortBox extends AbstractWidget
// TODO(el): ToggleButton :)
$toggle = array('asc' => 'sort-name-down', 'desc' => 'sort-name-up');
unset($toggle[strtolower($direction) ?: 'asc']);
unset($toggle[isset($direction) ? strtolower($direction) : 'asc']);
$newDirection = key($toggle);
$icon = current($toggle);

View File

@ -403,7 +403,7 @@ EOT;
*
* @see Countable
*/
public function count()
public function count(): int
{
return count($this->tabs);
}

View File

@ -64,11 +64,10 @@ class Zend_Controller_Action_HelperBroker_PriorityStack implements IteratorAggre
* Magic property overloading for unsetting if helper is exists by name
*
* @param string $helperName The helper name
* @return Zend_Controller_Action_Helper_Abstract
*/
public function __unset($helperName)
{
return $this->offsetUnset($helperName);
$this->offsetUnset($helperName);
}
/**
@ -86,9 +85,9 @@ class Zend_Controller_Action_HelperBroker_PriorityStack implements IteratorAggre
/**
* Return something iterable
*
* @return array
* @return Traversable
*/
public function getIterator()
public function getIterator(): Traversable
{
return new ArrayObject($this->_helpersByPriority);
}
@ -97,9 +96,9 @@ class Zend_Controller_Action_HelperBroker_PriorityStack implements IteratorAggre
* offsetExists()
*
* @param int|string $priorityOrHelperName
* @return Zend_Controller_Action_HelperBroker_PriorityStack
* @return bool
*/
public function offsetExists($priorityOrHelperName)
public function offsetExists($priorityOrHelperName): bool
{
if (is_string($priorityOrHelperName)) {
return array_key_exists($priorityOrHelperName, $this->_helpersByNameRef);
@ -112,9 +111,9 @@ class Zend_Controller_Action_HelperBroker_PriorityStack implements IteratorAggre
* offsetGet()
*
* @param int|string $priorityOrHelperName
* @return Zend_Controller_Action_HelperBroker_PriorityStack
* @return Zend_Controller_Action_Helper_Abstract
*/
public function offsetGet($priorityOrHelperName)
public function offsetGet($priorityOrHelperName): Zend_Controller_Action_Helper_Abstract
{
if (!$this->offsetExists($priorityOrHelperName)) {
throw new Zend_Controller_Action_Exception('A helper with priority ' . $priorityOrHelperName . ' does not exist.');
@ -132,9 +131,8 @@ class Zend_Controller_Action_HelperBroker_PriorityStack implements IteratorAggre
*
* @param int $priority
* @param Zend_Controller_Action_Helper_Abstract $helper
* @return Zend_Controller_Action_HelperBroker_PriorityStack
*/
public function offsetSet($priority, $helper)
public function offsetSet($priority, $helper): void
{
$priority = (int) $priority;
@ -161,16 +159,14 @@ class Zend_Controller_Action_HelperBroker_PriorityStack implements IteratorAggre
}
krsort($this->_helpersByPriority); // always make sure priority and LIFO are both enforced
return $this;
}
/**
* offsetUnset()
*
* @param int|string $priorityOrHelperName Priority integer or the helper name
* @return Zend_Controller_Action_HelperBroker_PriorityStack
*/
public function offsetUnset($priorityOrHelperName)
public function offsetUnset($priorityOrHelperName): void
{
if (!$this->offsetExists($priorityOrHelperName)) {
throw new Zend_Controller_Action_Exception('A helper with priority or name ' . $priorityOrHelperName . ' does not exist.');
@ -187,7 +183,6 @@ class Zend_Controller_Action_HelperBroker_PriorityStack implements IteratorAggre
unset($this->_helpersByNameRef[$helperName]);
unset($this->_helpersByPriority[$priority]);
return $this;
}
/**
@ -195,7 +190,7 @@ class Zend_Controller_Action_HelperBroker_PriorityStack implements IteratorAggre
*
* @return int
*/
public function count()
public function count(): int
{
return count($this->_helpersByPriority);
}

View File

@ -271,11 +271,12 @@ class Zend_Controller_Router_Route extends Zend_Controller_Router_Route_Abstract
// Translate value if required
$part = $this->_parts[$pos];
if ($this->_isTranslated
&& $part !== null
&& (substr($part, 0, 1) === '@' && substr($part, 1, 1) !== '@'
&& $name === null)
|| $name !== null && in_array($name, $this->_translatable)
) {
if (substr($part, 0, 1) === '@') {
if ($part && substr($part, 0, 1) === '@') {
$part = substr($part, 1);
}
@ -284,7 +285,7 @@ class Zend_Controller_Router_Route extends Zend_Controller_Router_Route_Abstract
}
}
if (substr($part, 0, 2) === '@@') {
if ($part && substr($part, 0, 2) === '@@') {
$part = substr($part, 1);
}

View File

@ -286,7 +286,9 @@ abstract class Zend_Db_Adapter_Pdo_Abstract extends Zend_Db_Adapter_Abstract
*/
protected function _quote($value)
{
if (is_int($value) || is_float($value)) {
if ($value === null) {
$value = '';
} elseif (is_int($value) || is_float($value)) {
return $value;
}
$this->_connect();

View File

@ -135,7 +135,7 @@ abstract class Zend_Db_Statement implements Zend_Db_Statement_Interface
$sql = $this->_stripQuoted($sql);
// split into text and params
$this->_sqlSplit = preg_split('/(\?|\:[a-zA-Z0-9_]+)/',
$this->_sqlSplit = empty($sql) ? [] : preg_split('/(\?|\:[a-zA-Z0-9_]+)/',
$sql, -1, PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY);
// map params
@ -186,14 +186,18 @@ abstract class Zend_Db_Statement implements Zend_Db_Statement_Interface
// remove 'foo\'bar'
if (!empty($q)) {
$escapeChar = preg_quote($escapeChar);
// this segfaults only after 65,000 characters instead of 9,000
$sql = preg_replace("/$q([^$q{$escapeChar}]*|($qe)*)*$q/s", '', $sql);
if ($sql !== null) {
// this segfaults only after 65,000 characters instead of 9,000
$sql = preg_replace("/$q([^$q{$escapeChar}]*|($qe)*)*$q/s", '', $sql);
}
}
// get a version of the SQL statement with all quoted
// values and delimited identifiers stripped out
// remove "foo\"bar"
$sql = preg_replace("/\"(\\\\\"|[^\"])*\"/Us", '', $sql);
if ($sql !== null) {
$sql = preg_replace("/\"(\\\\\"|[^\"])*\"/Us", '', $sql);
}
// get the character for delimited id quotes,
// this is usually " but in MySQL is `
@ -205,7 +209,10 @@ abstract class Zend_Db_Statement implements Zend_Db_Statement_Interface
$de = substr($de, 1, 2);
$de = preg_quote($de);
// Note: $de and $d where never used..., now they are:
$sql = preg_replace("/$d($de|\\\\{2}|[^$d])*$d/Us", '', $sql);
if ($sql !== null) {
$sql = preg_replace("/$d($de|\\\\{2}|[^$d])*$d/Us", '', $sql);
}
return $sql;
}

View File

@ -240,6 +240,12 @@ class Zend_Db_Statement_Pdo extends Zend_Db_Statement implements IteratorAggrega
if ($style === null) {
$style = $this->_fetchMode;
}
if ($cursor === null) {
$cursor = PDO::FETCH_ORI_NEXT;
}
if ($offset === null) {
$offset = 0;
}
try {
return $this->_stmt->fetch($style, $cursor, $offset);
} catch (PDOException $e) {
@ -252,7 +258,7 @@ class Zend_Db_Statement_Pdo extends Zend_Db_Statement implements IteratorAggrega
*
* @return IteratorIterator
*/
public function getIterator()
public function getIterator(): Traversable
{
return new IteratorIterator($this->_stmt);
}

View File

@ -3246,6 +3246,7 @@ class Zend_Form implements Iterator, Countable, Zend_Validate_Interface
* @throws Zend_Form_Exception
* @return Zend_Form_Element|Zend_Form_DisplayGroup|Zend_Form
*/
#[\ReturnTypeWillChange]
public function current()
{
$this->_sort();
@ -3268,7 +3269,7 @@ class Zend_Form implements Iterator, Countable, Zend_Validate_Interface
*
* @return string
*/
public function key()
public function key(): string
{
$this->_sort();
return key($this->_order);
@ -3279,7 +3280,7 @@ class Zend_Form implements Iterator, Countable, Zend_Validate_Interface
*
* @return void
*/
public function next()
public function next(): void
{
$this->_sort();
next($this->_order);
@ -3290,7 +3291,7 @@ class Zend_Form implements Iterator, Countable, Zend_Validate_Interface
*
* @return void
*/
public function rewind()
public function rewind(): void
{
$this->_sort();
reset($this->_order);
@ -3301,7 +3302,7 @@ class Zend_Form implements Iterator, Countable, Zend_Validate_Interface
*
* @return bool
*/
public function valid()
public function valid(): bool
{
$this->_sort();
return (current($this->_order) !== false);
@ -3312,7 +3313,7 @@ class Zend_Form implements Iterator, Countable, Zend_Validate_Interface
*
* @return int
*/
public function count()
public function count(): int
{
return count($this->_order);
}

View File

@ -158,7 +158,7 @@ class Zend_Form_Decorator_Description extends Zend_Form_Decorator_Abstract
}
$description = $element->getDescription();
$description = trim($description);
$description = trim($description ?: '');
if (!empty($description) && (null !== ($translator = $element->getTranslator()))) {
$description = $translator->translate($description);

View File

@ -91,7 +91,7 @@ class Zend_Form_Decorator_HtmlTag extends Zend_Form_Decorator_Abstract
$val = implode(' ', $val);
}
}
$val = htmlspecialchars($val, ENT_COMPAT, $enc);
$val = htmlspecialchars($val ?? '', ENT_COMPAT, $enc);
$xhtml .= " $key=\"$val\"";
}
return $xhtml;

View File

@ -298,7 +298,7 @@ class Zend_Form_Decorator_Label extends Zend_Form_Decorator_Abstract
}
$label = $element->getLabel();
$label = trim($label);
$label = trim($label ?? '');
if (empty($label)) {
return '';

View File

@ -1036,7 +1036,7 @@ class Zend_Form_DisplayGroup implements Iterator,Countable
*
* @return Zend_Form_Element
*/
public function current()
public function current(): Zend_Form_Element
{
$this->_sort();
current($this->_elementOrder);
@ -1049,7 +1049,7 @@ class Zend_Form_DisplayGroup implements Iterator,Countable
*
* @return string
*/
public function key()
public function key(): string
{
$this->_sort();
return key($this->_elementOrder);
@ -1060,7 +1060,7 @@ class Zend_Form_DisplayGroup implements Iterator,Countable
*
* @return void
*/
public function next()
public function next(): void
{
$this->_sort();
next($this->_elementOrder);
@ -1071,7 +1071,7 @@ class Zend_Form_DisplayGroup implements Iterator,Countable
*
* @return void
*/
public function rewind()
public function rewind(): void
{
$this->_sort();
reset($this->_elementOrder);
@ -1082,7 +1082,7 @@ class Zend_Form_DisplayGroup implements Iterator,Countable
*
* @return bool
*/
public function valid()
public function valid(): bool
{
$this->_sort();
return (current($this->_elementOrder) !== false);
@ -1093,7 +1093,7 @@ class Zend_Form_DisplayGroup implements Iterator,Countable
*
* @return int
*/
public function count()
public function count(): int
{
return count($this->_elements);
}

View File

@ -510,7 +510,7 @@ class Zend_Paginator implements Countable, IteratorAggregate
*
* @return integer
*/
public function count()
public function count(): int
{
if (!$this->_pageCount) {
$this->_pageCount = $this->_calculatePageCount();
@ -812,7 +812,7 @@ class Zend_Paginator implements Countable, IteratorAggregate
*
* @return Traversable
*/
public function getIterator()
public function getIterator(): Traversable
{
return $this->getCurrentItems();
}

View File

@ -70,6 +70,16 @@ class Zend_Paginator_SerializableLimitIterator extends LimitIterator implements
));
}
public function __serialize(): array
{
return array(
'it' => $this->getInnerIterator(),
'offset' => $this->_offset,
'count' => $this->_count,
'pos' => $this->getPosition(),
);
}
/**
* @param string $data representation of the instance
*/
@ -80,12 +90,19 @@ class Zend_Paginator_SerializableLimitIterator extends LimitIterator implements
$this->seek($dataArr['pos']+$dataArr['offset']);
}
public function __unserialize(array $data): void
{
$this->__construct($data['it'], $data['offset'], $data['count']);
$this->seek($data['pos']+$data['offset']);
}
/**
* Returns value of the Iterator
*
* @param int $offset
* @return mixed
*/
#[\ReturnTypeWillChange]
public function offsetGet($offset)
{
$currentOffset = $this->key();
@ -102,7 +119,7 @@ class Zend_Paginator_SerializableLimitIterator extends LimitIterator implements
* @param int $offset
* @param mixed $value
*/
public function offsetSet($offset, $value)
public function offsetSet($offset, $value): void
{
}
@ -111,7 +128,7 @@ class Zend_Paginator_SerializableLimitIterator extends LimitIterator implements
*
* @param int $offset
*/
public function offsetExists($offset)
public function offsetExists($offset): bool
{
if ($offset > 0 && $offset < $this->_count) {
try {
@ -136,7 +153,7 @@ class Zend_Paginator_SerializableLimitIterator extends LimitIterator implements
*
* @param int $offset
*/
public function offsetUnset($offset)
public function offsetUnset($offset): void
{
}
}

View File

@ -230,7 +230,7 @@ class Zend_View_Helper_HeadLink extends Zend_View_Helper_Placeholder_Container_S
* @param array $value
* @return void
*/
public function offsetSet($index, $value)
public function offsetSet($index, $value): void
{
if (!$this->_isValid($value)) {
$e = new Zend_View_Exception('offsetSet() expects a data token; please use one of the custom offsetSet*() methods');
@ -238,7 +238,7 @@ class Zend_View_Helper_HeadLink extends Zend_View_Helper_Placeholder_Container_S
throw $e;
}
return $this->getContainer()->offsetSet($index, $value);
$this->getContainer()->offsetSet($index, $value);
}
/**

View File

@ -168,7 +168,8 @@ class Zend_View_Helper_HeadMeta extends Zend_View_Helper_Placeholder_Container_S
$item = $this->createData($type, $args[0], $args[1], $args[2]);
if ('offsetSet' == $action) {
return $this->offsetSet($index, $item);
$this->offsetSet($index, $item);
return $this;
}
$this->$action($item);
@ -254,7 +255,7 @@ class Zend_View_Helper_HeadMeta extends Zend_View_Helper_Placeholder_Container_S
* @return void
* @throws Zend_View_Exception
*/
public function offsetSet($index, $value)
public function offsetSet($index, $value): void
{
if (!$this->_isValid($value)) {
$e = new Zend_View_Exception('Invalid value passed to offsetSet; please use offsetSetName() or offsetSetHttpEquiv()');
@ -262,7 +263,7 @@ class Zend_View_Helper_HeadMeta extends Zend_View_Helper_Placeholder_Container_S
throw $e;
}
return $this->getContainer()->offsetSet($index, $value);
$this->getContainer()->offsetSet($index, $value);
}
/**
@ -272,7 +273,7 @@ class Zend_View_Helper_HeadMeta extends Zend_View_Helper_Placeholder_Container_S
* @return void
* @throws Zend_View_Exception
*/
public function offsetUnset($index)
public function offsetUnset($index): void
{
if (!in_array($index, $this->getContainer()->getKeys())) {
$e = new Zend_View_Exception('Invalid index passed to offsetUnset()');
@ -280,7 +281,7 @@ class Zend_View_Helper_HeadMeta extends Zend_View_Helper_Placeholder_Container_S
throw $e;
}
return $this->getContainer()->offsetUnset($index);
$this->getContainer()->offsetUnset($index);
}
/**

View File

@ -363,7 +363,7 @@ class Zend_View_Helper_HeadScript extends Zend_View_Helper_Placeholder_Container
* @param mixed $value
* @return void
*/
public function offsetSet($index, $value)
public function offsetSet($index, $value): void
{
if (!$this->_isValid($value)) {
$e = new Zend_View_Exception('Invalid argument passed to offsetSet(); please use one of the helper methods, offsetSetScript() or offsetSetFile()');
@ -371,7 +371,7 @@ class Zend_View_Helper_HeadScript extends Zend_View_Helper_Placeholder_Container
throw $e;
}
return $this->getContainer()->offsetSet($index, $value);
$this->getContainer()->offsetSet($index, $value);
}
/**

View File

@ -217,7 +217,7 @@ class Zend_View_Helper_HeadStyle extends Zend_View_Helper_Placeholder_Container_
* @param mixed $value
* @return void
*/
public function offsetSet($index, $value)
public function offsetSet($index, $value): void
{
if (!$this->_isValid($value)) {
$e = new Zend_View_Exception('Invalid value passed to offsetSet; please use offsetSetStyle()');
@ -225,7 +225,7 @@ class Zend_View_Helper_HeadStyle extends Zend_View_Helper_Placeholder_Container_
throw $e;
}
return $this->getContainer()->offsetSet($index, $value);
$this->getContainer()->offsetSet($index, $value);
}
/**

View File

@ -258,7 +258,7 @@ abstract class Zend_View_Helper_Placeholder_Container_Standalone extends Zend_Vi
*
* @return int
*/
public function count()
public function count(): int
{
$container = $this->getContainer();
return count($container);
@ -270,7 +270,7 @@ abstract class Zend_View_Helper_Placeholder_Container_Standalone extends Zend_Vi
* @param string|int $offset
* @return bool
*/
public function offsetExists($offset)
public function offsetExists($offset): bool
{
return $this->getContainer()->offsetExists($offset);
}
@ -281,6 +281,7 @@ abstract class Zend_View_Helper_Placeholder_Container_Standalone extends Zend_Vi
* @param string|int $offset
* @return mixed
*/
#[\ReturnTypeWillChange]
public function offsetGet($offset)
{
return $this->getContainer()->offsetGet($offset);
@ -293,9 +294,9 @@ abstract class Zend_View_Helper_Placeholder_Container_Standalone extends Zend_Vi
* @param mixed $value
* @return void
*/
public function offsetSet($offset, $value)
public function offsetSet($offset, $value): void
{
return $this->getContainer()->offsetSet($offset, $value);
$this->getContainer()->offsetSet($offset, $value);
}
/**
@ -304,9 +305,9 @@ abstract class Zend_View_Helper_Placeholder_Container_Standalone extends Zend_Vi
* @param string|int $offset
* @return void
*/
public function offsetUnset($offset)
public function offsetUnset($offset): void
{
return $this->getContainer()->offsetUnset($offset);
$this->getContainer()->offsetUnset($offset);
}
/**
@ -314,7 +315,7 @@ abstract class Zend_View_Helper_Placeholder_Container_Standalone extends Zend_Vi
*
* @return Iterator
*/
public function getIterator()
public function getIterator(): Traversable
{
return $this->getContainer()->getIterator();
}

View File

@ -41,7 +41,7 @@ class DocSectionFilterIterator extends RecursiveFilterIterator implements Counta
* @return bool Whether the current element of the iterator is acceptable
* through this filter
*/
public function accept()
public function accept(): bool
{
$section = $this->current();
/** @var \Icinga\Module\Doc\DocSection $section */
@ -51,18 +51,12 @@ class DocSectionFilterIterator extends RecursiveFilterIterator implements Counta
return false;
}
/**
* {@inheritdoc}
*/
public function getChildren()
public function getChildren(): self
{
return new static($this->getInnerIterator()->getChildren(), $this->chapter);
}
/**
* {@inheritdoc}
*/
public function count()
public function count(): int
{
return iterator_count($this);
}

View File

@ -9,10 +9,6 @@ use Icinga\Module\Doc\Search\DocSearchMatch;
/**
* Renderer for doc searches
*
* @method DocSearchIterator getInnerIterator() {
* @{inheritdoc}
* }
*/
class DocSearchRenderer extends DocRenderer
{
@ -33,45 +29,30 @@ class DocSearchRenderer extends DocRenderer
parent::__construct($iterator, RecursiveIteratorIterator::SELF_FIRST);
}
/**
* {@inheritdoc}
*/
public function beginIteration()
public function beginIteration(): void
{
$this->content[] = '<nav role="navigation"><ul class="toc">';
}
/**
* {@inheritdoc}
*/
public function endIteration()
public function endIteration(): void
{
$this->content[] = '</ul></nav>';
}
/**
* {@inheritdoc}
*/
public function beginChildren()
public function beginChildren(): void
{
if ($this->getInnerIterator()->getMatches()) {
$this->content[] = '<ul class="toc">';
}
}
/**
* {@inheritdoc}
*/
public function endChildren()
public function endChildren(): void
{
if ($this->getInnerIterator()->getMatches()) {
$this->content[] = '</ul>';
}
}
/**
* {@inheritdoc}
*/
public function render()
{
foreach ($this as $section) {

View File

@ -3,16 +3,11 @@
namespace Icinga\Module\Doc\Renderer;
use Icinga\Web\View;
use Icinga\Data\Tree\TreeNodeIterator;
use RecursiveIteratorIterator;
/**
* TOC renderer
*
* @method TreeNodeIterator getInnerIterator() {
* {@inheritdoc}
* }
*/
class DocTocRenderer extends DocRenderer
{
@ -47,41 +42,26 @@ class DocTocRenderer extends DocRenderer
parent::__construct($iterator, RecursiveIteratorIterator::SELF_FIRST);
}
/**
* {@inheritdoc}
*/
public function beginIteration()
public function beginIteration(): void
{
$this->content[] = sprintf('<nav role="navigation"><%s class="%s">', static::HTML_LIST_TAG, static::CSS_CLASS);
}
/**
* {@inheritdoc}
*/
public function endIteration()
public function endIteration(): void
{
$this->content[] = sprintf('</%s></nav>', static::HTML_LIST_TAG);
}
/**
* {@inheritdoc}
*/
public function beginChildren()
public function beginChildren(): void
{
$this->content[] = sprintf('<%s class="%s">', static::HTML_LIST_TAG, static::CSS_CLASS);
}
/**
* {@inheritdoc}
*/
public function endChildren()
public function endChildren(): void
{
$this->content[] = sprintf('</%s>', static::HTML_LIST_TAG);
}
/**
* {@inheritdoc}
*/
public function render()
{
if ($this->getInnerIterator()->isEmpty()) {

View File

@ -9,10 +9,6 @@ use Icinga\Data\Tree\TreeNodeIterator;
/**
* Iterator over doc sections that match a given search criteria
*
* @method TreeNodeIterator getInnerIterator() {
* {@inheritdoc}
* }
*/
class DocSearchIterator extends RecursiveFilterIterator
{
@ -48,7 +44,7 @@ class DocSearchIterator extends RecursiveFilterIterator
* @return bool Whether the current element of the iterator is acceptable
* through this filter
*/
public function accept()
public function accept(): bool
{
$section = $this->current();
/** @var $section \Icinga\Module\Doc\DocSection */
@ -84,10 +80,7 @@ class DocSearchIterator extends RecursiveFilterIterator
return $this->search;
}
/**
* {@inheritdoc}
*/
public function getChildren()
public function getChildren(): self
{
return new static($this->getInnerIterator()->getChildren(), $this->search);
}

View File

@ -1,652 +0,0 @@
<?php
/* Icinga Web 2 | (c) 2014 Icinga Development Team | GPLv2+ */
namespace Icinga\Module\Monitoring\Controllers;
use stdClass;
use DateInterval;
use DatePeriod;
use DateTime;
use Zend_Controller_Action_Exception;
use Icinga\Chart\GridChart;
use Icinga\Chart\Unit\LinearUnit;
use Icinga\Chart\Unit\StaticAxis;
use Icinga\Data\Filter\FilterExpression;
use Icinga\Module\Monitoring\Controller;
use Icinga\Module\Monitoring\Web\Widget\SelectBox;
use Icinga\Web\Url;
use Icinga\Web\Widget\Tabextension\DashboardAction;
use Icinga\Web\Widget\Tabextension\MenuAction;
class AlertsummaryController extends Controller
{
/**
* @var array
*/
private $notificationData;
/**
* @var array
*/
private $problemData;
/**
* Init data set
*/
public function init()
{
$this->notificationData = $this->createNotificationData();
$this->problemData = $this->createProblemData();
}
/**
* Create full report
*/
public function indexAction()
{
$this->getTabs()->add(
'alertsummary',
array(
'title' => $this->translate(
'Show recent alerts and visualize notifications and problems'
. ' based on their amount and chronological distribution'
),
'label' => $this->translate('Alert Summary'),
'url' => Url::fromRequest()
)
)->extend(new DashboardAction())->extend(new MenuAction())->activate('alertsummary');
$this->view->title = $this->translate('Alert Summary');
$this->view->intervalBox = $this->createIntervalBox();
list($recentAlerts, $recentAlertsUrl) = $this->createRecentAlerts();
$this->view->recentAlerts = $recentAlerts;
$this->view->recentAlertsUrl = $recentAlertsUrl;
$this->view->interval = $this->getInterval();
$this->view->defectChart = $this->createDefectImage();
$this->view->healingChart = $this->createHealingChart();
$this->view->perf = $this->createNotificationPerfdata();
$this->view->trend = $this->createTrendInformation();
$this->setAutorefreshInterval(15);
$query = $this->backend->select()->from(
'notification',
array(
'host_name',
'host_display_name',
'service_description',
'service_display_name',
'notification_output',
'notification_contact_name',
'notification_start_time',
'notification_state'
)
);
$this->applyRestriction('monitoring/filter/objects', $query);
$this->view->notifications = $query;
$this->view->notificationsUrl = 'monitoring/list/notifications';
$this->setupLimitControl();
if (($limit = $this->params->get('limit'))) {
$query->limit($limit);
} else {
$query->limit(25);
}
}
/**
* Create data for charts
*
* @return array
*/
private function createNotificationData()
{
$interval = $this->getInterval();
$query = $this->backend->select()->from(
'notification',
array(
'notification_start_time'
)
);
$this->applyRestriction('monitoring/filter/objects', $query);
$query->addFilter(
new FilterExpression(
'notification_start_time',
'>=',
$this->getBeginDate($interval)->format('Y-m-d H:i:s')
)
);
$query->order('notification_start_time', 'asc');
$records = $query->getQuery()->fetchAll();
$data = array();
$period = $this->createPeriod($interval);
foreach ($period as $entry) {
$id = $this->getPeriodFormat($interval, $entry->getTimestamp());
$data[$id] = array($id, 0);
}
foreach ($records as $item) {
$id = $this->getPeriodFormat($interval, $item->notification_start_time);
if (empty($data[$id])) {
$data[$id] = array($id, 0);
}
$data[$id][1]++;
}
return $data;
}
/**
* Trend information for notifications
*
* @return stdClass
*/
private function createTrendInformation()
{
$date = new DateTime();
$beginDate = $date->sub(new DateInterval('P3D'));
$query = $this->backend->select()->from(
'notification',
array(
'notification_start_time'
)
);
$this->applyRestriction('monitoring/filter/objects', $query);
$query->addFilter(
new FilterExpression(
'notification_start_time',
'>=',
$beginDate->format('Y-m-d H:i:s')
)
);
$query->order('notification_start_time', 'asc');
$records = $query->getQuery()->fetchAll();
$slots = array();
$period = new DatePeriod($beginDate, new DateInterval('P1D'), 2, DatePeriod::EXCLUDE_START_DATE);
foreach ($period as $entry) {
$slots[$entry->format('Y-m-d')] = 0;
}
foreach ($records as $item) {
$id = strftime('%Y-%m-%d', $item->notification_start_time);
if (isset($slots[$id])) {
$slots[$id]++;
}
}
$yesterday = array_shift($slots);
$today = array_shift($slots);
$out = new stdClass();
if ($yesterday === $today) {
$out->trend = $this->translate('unchanged');
} elseif ($yesterday > $today) {
$out->trend = $this->translate('down');
} else {
$out->trend = $this->translate('up');
}
if ($yesterday <= 0) {
$out->percent = 100;
} elseif ($yesterday === $today) {
$out->percent = 0;
} else {
$out->percent = sprintf(
'%.2f',
100 - ((100/($yesterday > $today ? $yesterday : $today)) * ($yesterday > $today ? $today : $yesterday))
);
}
return $out;
}
/**
* Perfdata for notifications
*
* @return stdClass
*/
private function createNotificationPerfdata()
{
$interval = $this->getInterval();
$query = $this->backend->select()->from(
'notification',
array(
'notification_start_time'
)
);
$this->applyRestriction('monitoring/filter/objects', $query);
$query->addFilter(
new FilterExpression(
'notification_start_time',
'>=',
$this->getBeginDate($interval)->format('Y-m-d H:i:s')
)
);
$query->order('notification_start_time', 'desc');
$records = $query->getQuery()->fetchAll();
$slots = array();
foreach ($records as $item) {
$id = strftime('%Y-%m-%d %H:%I:00', $item->notification_start_time);
if (empty($slots[$id])) {
$slots[$id] = 0;
}
$slots[$id]++;
}
$out = new stdClass();
if (! empty($slots)) {
$out->avg = sprintf('%.2f', array_sum($slots) / count($slots));
} else {
$out->avg = '0.0';
}
$out->last = array_shift($slots);
return $out;
}
/**
* Problems for notifications
*
* @return array
*/
private function createProblemData()
{
$interval = $this->getInterval();
$query = $this->backend->select()->from(
'eventhistory',
array(
'timestamp'
)
);
$this->applyRestriction('monitoring/filter/objects', $query);
$query->addFilter(
new FilterExpression(
'timestamp',
'>=',
$this->getBeginDate($interval)->getTimestamp()
)
);
$query->addFilter(
new FilterExpression(
'state',
'>',
0
)
);
$defects = array();
$records = $query->getQuery()->fetchAll();
$period = $this->createPeriod($interval);
foreach ($period as $entry) {
$id = $this->getPeriodFormat($interval, $entry->getTimestamp());
$defects[$id] = array($id, 0);
}
foreach ($records as $item) {
$id = $this->getPeriodFormat($interval, $item->timestamp);
if (empty($defects[$id])) {
$defects[$id] = array($id, 0);
}
$defects[$id][1]++;
}
return $defects;
}
/**
* Healing svg image
*
* @return GridChart
*/
public function createHealingChart()
{
$gridChart = new GridChart();
$gridChart->title = $this->translate('Healing Chart');
$gridChart->description = $this->translate('Notifications and average reaction time per hour.');
$gridChart->alignTopLeft();
$gridChart->setAxisLabel($this->createPeriodDescription(), $this->translate('Notifications'))
->setXAxis(new StaticAxis())
->setYAxis(new LinearUnit(10))
->setAxisMin(null, 0);
$interval = $this->getInterval();
$query = $this->backend->select()->from(
'notification',
array(
'notification_object_id',
'notification_start_time',
'notification_state',
'acknowledgement_entry_time'
)
);
$this->applyRestriction('monitoring/filter/objects', $query);
$query->addFilter(
new FilterExpression(
'notification_start_time',
'>=',
$this->getBeginDate($interval)->format('Y-m-d H:i:s')
)
);
$query->order('notification_start_time', 'asc');
$records = $query->getQuery()->fetchAll();
$interval = $this->getInterval();
$period = $this->createPeriod($interval);
$dAvg = array();
$dMax = array();
$notifications = array();
$rData = array();
foreach ($period as $entry) {
$id = $this->getPeriodFormat($interval, $entry->getTimestamp());
$dMax[$id] = array($id, 0);
$dAvg[$id] = array($id, 0, 0);
$notifications[$id] = array($id, 0);
}
foreach ($records as $item) {
$id = $this->getPeriodFormat($interval, $item->notification_start_time);
if ($item->notification_state == '0' && isset($rData[$item->notification_object_id])) {
$rData[$item->notification_object_id]['recover'] =
$item->notification_start_time - $rData[$item->notification_object_id]['entry'];
} elseif ($item->notification_state !== '0') {
$recover = 0;
if ($item->acknowledgement_entry_time) {
$recover = $item->acknowledgement_entry_time - $item->notification_start_time;
/*
* Acknowledgements may happen before the actual notification starts, since notifications
* can be configured to start a certain time after the problem. In that case we assume
* a reaction time of 0s.
*/
if ($recover < 0) {
$recover = 0;
}
}
$rData[$item->notification_object_id] = array(
'id' => $id,
'entry' => $item->notification_start_time,
'recover' => $recover
);
}
}
foreach ($rData as $item) {
$notifications[$item['id']][1]++;
if ($item['recover'] > $dMax[$item['id']][1]) {
$dMax[$item['id']][1] = (int) $item['recover'];
}
$dAvg[$item['id']][1] += (int) $item['recover'];
$dAvg[$item['id']][2]++;
}
foreach ($dAvg as &$item) {
if ($item[2] > 0) {
$item[1] = ($item[1]/$item[2])/60/60;
}
}
foreach ($dMax as &$item) {
$item[1] = $item[1]/60/60;
}
$gridChart->drawBars(
array(
'label' => $this->translate('Notifications'),
'color' => '#07C0D9',
'data' => $notifications,
'showPoints' => true,
'tooltip' => '<b>{title}:</b> {value} {label}'
)
);
$gridChart->drawLines(
array(
'label' => $this->translate('Avg (min)'),
'color' => '#ffaa44',
'data' => $dAvg,
'showPoints' => true,
'tooltip' => $this->translate('<b>{title}:</b> {value}m min. reaction time')
)
);
$gridChart->drawLines(
array(
'label' => $this->translate('Max (min)'),
'color' => '#ff5566',
'data' => $dMax,
'showPoints' => true,
'tooltip' => $this->translate('<b>{title}:</b> {value}m max. reaction time')
)
);
return $gridChart;
}
/**
* Notifications and defects
*
* @return GridChart
*/
public function createDefectImage()
{
$gridChart = new GridChart();
$gridChart->title = $this->translate('Defect Chart');
$gridChart->description = $this->translate('Notifications and defects per hour');
$gridChart->alignTopLeft();
$gridChart->setAxisLabel($this->createPeriodDescription(), $this->translate('Notifications'))
->setXAxis(new StaticAxis())
->setYAxis(new LinearUnit(10))
->setAxisMin(null, 0);
$gridChart->drawBars(
array(
'label' => $this->translate('Notifications'),
'color' => '#07C0D9',
'data' => $this->notificationData,
'showPoints' => true,
'tooltip' => '<b>{title}:</b> {value} {label}'
)
);
$gridChart->drawLines(
array(
'label' => $this->translate('Defects'),
'color' => '#ff5566',
'data' => $this->problemData,
'showPoints' => true,
'tooltip' => '<b>{title}:</b> {value} {label}'
)
);
return $gridChart;
}
/**
* Top recent alerts
*
* @return array
*/
private function createRecentAlerts()
{
$query = $this->backend->select()->from(
'notification',
array(
'host_name',
'host_display_name',
'service_description',
'service_display_name',
'notification_output',
'notification_contact_name',
'notification_start_time',
'notification_state'
)
);
$this->applyRestriction('monitoring/filter/objects', $query);
$query->order('notification_start_time', 'desc');
return array(
$query->limit(5),
'monitoring/list/notifications?sort=notification_start_time&dir=desc'
);
}
/**
* Interval selector box
*
* @return SelectBox
*/
private function createIntervalBox()
{
$box = new SelectBox(
'intervalBox',
array(
'1d' => $this->translate('One day'),
'1w' => $this->translate('One week'),
'1m' => $this->translate('One month'),
'1y' => $this->translate('One year')
),
$this->translate('Report interval'),
'interval'
);
$box->applyRequest($this->getRequest());
return $box;
}
/**
* Return reasonable date time format for an interval
*
* @param string $interval
* @param string $timestamp
*
* @return string
*/
private function getPeriodFormat($interval, $timestamp)
{
$format = '';
if ($interval === '1d') {
$format = '%H:00';
} elseif ($interval === '1w') {
$format = '%Y-%m-%d';
} elseif ($interval === '1m') {
$format = '%Y-%m-%d';
} elseif ($interval === '1y') {
$format = '%Y-%m';
}
return strftime($format, $timestamp);
}
/**
* Create a reasonable period based in interval strings
*
* @param $interval
* @return DatePeriod
*/
private function createPeriod($interval)
{
if ($interval === '1d') {
return new DatePeriod($this->getBeginDate($interval), new DateInterval('PT1H'), 24);
} elseif ($interval === '1w') {
return new DatePeriod($this->getBeginDate($interval), new DateInterval('P1D'), 7);
} elseif ($interval === '1m') {
return new DatePeriod($this->getBeginDate($interval), new DateInterval('P1D'), 31);
} elseif ($interval === '1y') {
return new DatePeriod($this->getBeginDate($interval), new DateInterval('P1M'), 12);
}
}
/**
* Return start timestamps based on interval strings
*
* @param $interval
* @return DateTime|null
*/
private function getBeginDate($interval)
{
$new = new DateTime();
if ($interval === '1d') {
return $new->sub(new DateInterval('P1D'));
} elseif ($interval === '1w') {
return $new->sub(new DateInterval('P1W'));
} elseif ($interval === '1m') {
return $new->sub(new DateInterval('P1M'));
} elseif ($interval === '1y') {
return $new->sub(new DateInterval('P1Y'));
}
return null;
}
/**
* Getter for interval
*
* @return string
*
* @throws Zend_Controller_Action_Exception
*/
private function getInterval()
{
$interval = $this->getParam('interval', '1d');
if (false === in_array($interval, array('1d', '1w', '1m', '1y'))) {
throw new Zend_Controller_Action_Exception($this->translate('Value for interval not valid'));
}
return $interval;
}
/**
* Create a human-readable description of the current interval size
*
* @return string The description of the current interval size
*/
private function createPeriodDescription()
{
$int = $this->getInterval();
switch ($int) {
case '1d':
return $this->translate('Hour');
break;
case '1w':
return $this->translate('Day');
break;
case '1m':
return $this->translate('Day');
break;
case '1y':
return $this->translate('Month');
break;
}
}
}

View File

@ -275,7 +275,7 @@ class TimelineController extends Controller
{
$startTime = new DateTime();
$startParam = $this->_request->getParam('start');
$startTimestamp = is_numeric($startParam) ? intval($startParam) : strtotime($startParam);
$startTimestamp = is_numeric($startParam) ? intval($startParam) : strtotime($startParam ?? '');
if ($startTimestamp !== false) {
$startTime->setTimestamp($startTimestamp);
} else {
@ -284,7 +284,7 @@ class TimelineController extends Controller
$endTime = clone $startTime;
$endParam = $this->_request->getParam('end');
$endTimestamp = is_numeric($endParam) ? intval($endParam) : strtotime($endParam);
$endTimestamp = is_numeric($endParam) ? intval($endParam) : strtotime($endParam ?? '');
if ($endTimestamp !== false) {
$endTime->setTimestamp($endTimestamp);
} else {

View File

@ -1,79 +0,0 @@
<?php if (! $this->compact): ?>
<div class="controls">
<?= $this->tabs; ?>
<div style="float: right;" class="dont-print">
<?= $intervalBox; ?>
</div>
<?= $this->limiter; ?>
</div>
<?php endif ?>
<div class="content alertsummary">
<!-- <h1><?= $this->translate('Alert summary'); ?></h1> -->
<div class="hbox">
<div class="hbox-item">
<h2><?= $this->translate('Notifications and Problems'); ?></h2>
<div style="width: 400px; height: 400px;">
<?= $defectChart->render(); ?>
</div>
</div>
<div class="hbox-item">
<h2><?= $this->translate('Time to Reaction (Ack, Recover)'); ?></h2>
<div style="width: 400px; height: 400px;">
<?= $healingChart->render(); ?>
</div>
</div>
</div>
<h2><?= $this->translate('Trend'); ?></h2>
<div class="alertsummary-flex-container">
<div class="alertsummary-flex">
<?= $this->translate('Average') ?>
<strong><?= $this->perf->avg; ?></strong>
<?= $this->translate('notifications per hour'); ?>,
<strong><?= $this->perf->last; ?></strong>
<?= $this->translate('in the last hour'); ?>.
<?= $this->translate('Trend for the last 24h'); ?>
(<?= $this->trend->percent; ?>%
<strong><?= $this->translate($this->trend->trend); ?></strong>)
<span>
<?php if ($this->trend->trend === 'up'): ?>
<?= $this->icon('up-open'); ?>
<?php elseif ($this->trend->trend === 'unchanged'): ?>
<?= $this->icon('right-open'); ?>
<?php else: ?>
<?= $this->icon('down-open'); ?>
<?php endif; ?>
</span>
</div>
</div>
<?php if ($this->recentAlerts): ?>
<h1><?= $this->translate('Top 5 Recent Alerts'); ?></h1>
<div class="alertsummary-flex-container">
<div class="alertsummary-flex">
<?= $this->partial('list/notifications.phtml', array(
'notifications' => $this->recentAlerts,
'compact' => true,
'notificationsUrl' => $recentAlertsUrl
)); ?>
</div>
</div>
<?php endif; ?>
<h1><?= $this->translate('History'); ?></h1>
<div class="alertsummary-flex-container">
<div class="alertsummary-flex">
<?= $this->partial('list/notifications.phtml', array(
'notifications' => $this->notifications,
'compact' => true,
'notificationsUrl' => $notificationsUrl
)); ?>
</div>
</div>
</div>

View File

@ -30,7 +30,7 @@ $history->limit($limit * $page);
?>
<div class="content">
<?php
$dateFormat = $this->translate('%A, %B %e, %Y', 'date.verbose');
$dateFormatter = new IntlDateFormatter(setlocale(LC_TIME, 0), IntlDateFormatter::FULL, IntlDateFormatter::LONG);
$lastDate = null;
$flappingMsg = $this->translate('Flapping with a %.2f%% state change rate');
$rowAction = Url::fromPath('monitoring/event/show');
@ -161,7 +161,7 @@ $rowAction = Url::fromPath('monitoring/event/show');
break;
} ?>
<?php
$currentDate = strftime($dateFormat, (int) $event->timestamp);
$currentDate = $dateFormatter->format($event->timestamp);
if ($currentDate !== $lastDate):
$lastDate = $currentDate;
?>

View File

@ -22,10 +22,7 @@ class ColumnFilterIterator extends FilterIterator
parent::__construct(new ArrayIterator($columns));
}
/**
* {@inheritdoc}
*/
public function accept()
public function accept(): bool
{
$column = $this->current();
return ! ($column instanceof Zend_Db_Expr || $column === '(NULL)');

View File

@ -10,7 +10,7 @@ class CustomvarProtectionIterator extends IteratorIterator
{
const IS_CV_RE = '~^_(host|service)_([a-zA-Z0-9_]+)$~';
public function current()
public function current(): object
{
$row = parent::current();

View File

@ -17,6 +17,7 @@ use Icinga\Module\Monitoring\Backend\Ido\Query\IdoQuery;
use Icinga\Module\Monitoring\Backend\MonitoringBackend;
use Icinga\Web\Request;
use Icinga\Web\Url;
use Traversable;
/**
* A read-only view of an underlying query
@ -58,7 +59,7 @@ abstract class DataView implements QueryInterface, SortRules, FilterColumns, Ite
*
* @return IdoQuery
*/
public function getIterator()
public function getIterator(): Traversable
{
return $this->getQuery();
}
@ -499,7 +500,7 @@ abstract class DataView implements QueryInterface, SortRules, FilterColumns, Ite
*
* @return int
*/
public function count()
public function count(): int
{
return $this->query->count();
}

View File

@ -9,6 +9,7 @@ use Icinga\Data\Filter\Filter;
use Icinga\Data\Filterable;
use IteratorAggregate;
use Icinga\Module\Monitoring\Backend\MonitoringBackend;
use Traversable;
abstract class ObjectList implements Countable, IteratorAggregate, Filterable
{
@ -118,10 +119,7 @@ abstract class ObjectList implements Countable, IteratorAggregate, Filterable
return $this->objects;
}
/**
* @return int
*/
public function count()
public function count(): int
{
if ($this->count === null) {
$this->count = (int) $this->backend
@ -135,7 +133,7 @@ abstract class ObjectList implements Countable, IteratorAggregate, Filterable
return $this->count;
}
public function getIterator()
public function getIterator(): Traversable
{
if ($this->objects === null) {
$this->fetch();

View File

@ -5,6 +5,7 @@ namespace Icinga\Module\Monitoring\Plugin;
use ArrayIterator;
use IteratorAggregate;
use Traversable;
class PerfdataSet implements IteratorAggregate
{
@ -36,7 +37,7 @@ class PerfdataSet implements IteratorAggregate
*/
protected function __construct($perfdataStr)
{
if (($perfdataStr = trim($perfdataStr)) !== '') {
if ($perfdataStr && ($perfdataStr = trim($perfdataStr))) {
$this->perfdataStr = $perfdataStr;
$this->parse();
}
@ -47,7 +48,7 @@ class PerfdataSet implements IteratorAggregate
*
* @return ArrayIterator
*/
public function getIterator()
public function getIterator(): Traversable
{
return new ArrayIterator($this->asArray());
}

View File

@ -12,6 +12,7 @@ use Icinga\Data\Filter\Filter;
use Icinga\Web\Hook;
use Icinga\Web\Session\SessionNamespace;
use Icinga\Module\Monitoring\DataView\DataView;
use Traversable;
/**
* Represents a set of events in a specific range of time
@ -100,7 +101,7 @@ class TimeLine implements IteratorAggregate
*
* @return ArrayIterator
*/
public function getIterator()
public function getIterator(): Traversable
{
return new ArrayIterator($this->toArray());
}

View File

@ -207,7 +207,7 @@ class TimeRange implements Iterator
/**
* Reset the iterator to its initial state
*/
public function rewind()
public function rewind(): void
{
$this->current = clone $this->start;
}
@ -217,7 +217,7 @@ class TimeRange implements Iterator
*
* @return bool
*/
public function valid()
public function valid(): bool
{
if ($this->negative) {
return $this->current > $this->end;
@ -231,7 +231,7 @@ class TimeRange implements Iterator
*
* @return StdClass
*/
public function current()
public function current(): object
{
return $this->getTimeframe($this->current);
}
@ -241,7 +241,7 @@ class TimeRange implements Iterator
*
* @return int
*/
public function key()
public function key(): int
{
return $this->current->getTimestamp();
}
@ -249,7 +249,7 @@ class TimeRange implements Iterator
/**
* Advance the iterator position by one
*/
public function next()
public function next(): void
{
$this->applyInterval($this->current, 0);
}

View File

@ -5,6 +5,7 @@ namespace Icinga\Module\Setup;
use LogicException;
use RecursiveIterator;
use Traversable;
/**
* Container to store and handle requirements
@ -258,7 +259,7 @@ class RequirementSet implements RecursiveIterator
*
* @return bool
*/
public function hasChildren()
public function hasChildren(): bool
{
$current = $this->current();
return $current instanceof static;
@ -267,9 +268,9 @@ class RequirementSet implements RecursiveIterator
/**
* Return a iterator for the current nested set of requirements
*
* @return RecursiveIterator
* @return ?RecursiveIterator
*/
public function getChildren()
public function getChildren(): ?RecursiveIterator
{
return $this->current();
}
@ -277,7 +278,7 @@ class RequirementSet implements RecursiveIterator
/**
* Rewind the iterator to its first element
*/
public function rewind()
public function rewind(): void
{
reset($this->requirements);
}
@ -287,7 +288,7 @@ class RequirementSet implements RecursiveIterator
*
* @return bool
*/
public function valid()
public function valid(): bool
{
return $this->key() !== null;
}
@ -297,6 +298,7 @@ class RequirementSet implements RecursiveIterator
*
* @return Requirement|RequirementSet
*/
#[\ReturnTypeWillChange]
public function current()
{
return current($this->requirements);
@ -307,7 +309,7 @@ class RequirementSet implements RecursiveIterator
*
* @return int
*/
public function key()
public function key(): int
{
return key($this->requirements);
}
@ -315,7 +317,7 @@ class RequirementSet implements RecursiveIterator
/**
* Advance the iterator to the next element
*/
public function next()
public function next(): void
{
next($this->requirements);
}

View File

@ -7,17 +7,17 @@ use RecursiveIteratorIterator;
class RequirementsRenderer extends RecursiveIteratorIterator
{
public function beginIteration()
public function beginIteration(): void
{
$this->tags[] = '<ul class="requirements">';
}
public function endIteration()
public function endIteration(): void
{
$this->tags[] = '</ul>';
}
public function beginChildren()
public function beginChildren(): void
{
$this->tags[] = '<li>';
$currentSet = $this->getSubIterator();
@ -25,7 +25,7 @@ class RequirementsRenderer extends RecursiveIteratorIterator
$this->tags[] = '<ul class="set-state ' . $state . '">';
}
public function endChildren()
public function endChildren(): void
{
$this->tags[] = '</ul>';
$this->tags[] = '</li>';

View File

@ -6,6 +6,7 @@ namespace Icinga\Module\Setup;
use ArrayIterator;
use IteratorAggregate;
use Icinga\Module\Setup\Exception\SetupException;
use Traversable;
/**
* Container for multiple configuration steps
@ -21,7 +22,7 @@ class Setup implements IteratorAggregate
$this->steps = array();
}
public function getIterator()
public function getIterator(): Traversable
{
return new ArrayIterator($this->getSteps());
}

View File

@ -566,29 +566,14 @@ class WebWizard extends Wizard implements SetupWizard
public function getRequirements($skipModules = false)
{
$set = new RequirementSet();
$phpVersion = Platform::getPhpVersion();
if (version_compare($phpVersion, '5.6', '>=')
&& version_compare($phpVersion, '7.3', '<')
) {
$set->add(new PhpVersionRequirement(array(
'optional' => true,
'condition' => array('>=', '7.3'),
'description' => mt(
'setup',
'Running Icinga Web 2 requires PHP version 7.3.'
. ' Older versions are only supported up until version 2.11.'
)
)));
} else {
$set->add(new PhpVersionRequirement(array(
'condition' => array('>=', '7.3'),
'description' => mt(
'setup',
'Running Icinga Web 2 requires PHP version 7.3.'
)
)));
}
$set->add(new PhpVersionRequirement(array(
'condition' => array('>=', '7.2'),
'description' => sprintf(mt(
'setup',
'Running Icinga Web 2 requires PHP version %s.'
), '7.2')
)));
$set->add(new OSRequirement(array(
'optional' => true,

View File

@ -51,7 +51,10 @@ class LocalFileStorageTest extends BaseTestCase
{
$lfs = new TemporaryLocalFileStorage();
$lfs->create('foobar', 'Hello world!');
static::assertSame(array('foobar'), array_values(iterator_to_array($lfs->getIterator())));
foreach ($lfs as $path => $_) {
$this->assertEquals($lfs->resolvePath('foobar'), $path);
}
}
public function testGetIteratorThrowsNotReadableError()