322 lines
7.5 KiB
PHP
322 lines
7.5 KiB
PHP
<?php
|
|
|
|
namespace Icinga\Module\Director\Objects;
|
|
|
|
use Exception;
|
|
use Icinga\Module\Director\IcingaConfig\IcingaConfigHelper as c;
|
|
|
|
abstract class IcingaRanges
|
|
{
|
|
/** @var IcingaTimePeriodRange[]|IcingaScheduledDowntimeRange[] */
|
|
protected $storedRanges = [];
|
|
|
|
/** @var IcingaTimePeriodRange[]|IcingaScheduledDowntimeRange[] */
|
|
protected $ranges = [];
|
|
|
|
protected $modified = false;
|
|
|
|
protected $object;
|
|
|
|
private $position = 0;
|
|
|
|
protected $idx = array();
|
|
|
|
public function __construct(IcingaObject $object)
|
|
{
|
|
$this->object = $object;
|
|
}
|
|
|
|
#[\ReturnTypeWillChange]
|
|
public function count()
|
|
{
|
|
return count($this->ranges);
|
|
}
|
|
|
|
#[\ReturnTypeWillChange]
|
|
public function rewind()
|
|
{
|
|
$this->position = 0;
|
|
}
|
|
|
|
public function hasBeenModified()
|
|
{
|
|
return $this->modified;
|
|
}
|
|
|
|
#[\ReturnTypeWillChange]
|
|
public function current()
|
|
{
|
|
if (! $this->valid()) {
|
|
return null;
|
|
}
|
|
|
|
return $this->ranges[$this->idx[$this->position]];
|
|
}
|
|
|
|
#[\ReturnTypeWillChange]
|
|
public function key()
|
|
{
|
|
return $this->idx[$this->position];
|
|
}
|
|
|
|
#[\ReturnTypeWillChange]
|
|
public function next()
|
|
{
|
|
++$this->position;
|
|
}
|
|
|
|
#[\ReturnTypeWillChange]
|
|
public function valid()
|
|
{
|
|
return array_key_exists($this->position, $this->idx);
|
|
}
|
|
|
|
public function get($key)
|
|
{
|
|
if (array_key_exists($key, $this->ranges)) {
|
|
return $this->ranges[$key];
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public function getValues()
|
|
{
|
|
$res = array();
|
|
foreach ($this->ranges as $key => $range) {
|
|
$res[$key] = $range->range_value;
|
|
}
|
|
|
|
return (object) $res;
|
|
}
|
|
|
|
public function getOriginalValues()
|
|
{
|
|
$res = array();
|
|
foreach ($this->storedRanges as $key => $range) {
|
|
$res[$key] = $range->range_value;
|
|
}
|
|
|
|
return (object) $res;
|
|
}
|
|
|
|
public function getRanges()
|
|
{
|
|
return $this->ranges;
|
|
}
|
|
|
|
protected function modify($range, $value)
|
|
{
|
|
$this->ranges[$range]->range_key = $value;
|
|
}
|
|
|
|
public function set($ranges)
|
|
{
|
|
foreach ($ranges as $range => $value) {
|
|
$this->setRange($range, $value);
|
|
}
|
|
|
|
$toDelete = array_diff(array_keys($this->ranges), array_keys($ranges));
|
|
foreach ($toDelete as $range) {
|
|
$this->remove($range);
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function setRange($range, $value)
|
|
{
|
|
if ($value === null && array_key_exists($range, $this->ranges)) {
|
|
$this->remove($range);
|
|
return $this;
|
|
}
|
|
|
|
if (array_key_exists($range, $this->ranges)) {
|
|
if ($this->ranges[$range]->range_value === $value) {
|
|
return $this;
|
|
} else {
|
|
$this->ranges[$range]->range_value = $value;
|
|
$this->modified = true;
|
|
}
|
|
} else {
|
|
$class = $this->getRangeClass();
|
|
$this->ranges[$range] = $class::create([
|
|
$this->objectIdColumn => $this->object->get('id'),
|
|
'range_key' => $range,
|
|
'range_value' => $value,
|
|
]);
|
|
$this->modified = true;
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Magic isset check
|
|
*
|
|
* @return boolean
|
|
*/
|
|
public function __isset($range)
|
|
{
|
|
return array_key_exists($range, $this->ranges);
|
|
}
|
|
|
|
public function remove($range)
|
|
{
|
|
if (array_key_exists($range, $this->ranges)) {
|
|
unset($this->ranges[$range]);
|
|
}
|
|
|
|
$this->modified = true;
|
|
$this->refreshIndex();
|
|
}
|
|
|
|
public function clear()
|
|
{
|
|
$this->ranges = [];
|
|
$this->modified = true;
|
|
$this->refreshIndex();
|
|
}
|
|
|
|
protected function refreshIndex()
|
|
{
|
|
ksort($this->ranges);
|
|
$this->idx = array_keys($this->ranges);
|
|
}
|
|
|
|
public function listRangesNames()
|
|
{
|
|
return array_keys($this->ranges);
|
|
}
|
|
|
|
public function getType()
|
|
{
|
|
return $this->object->getShortTableName();
|
|
}
|
|
|
|
public function getRangeTableName()
|
|
{
|
|
return $this->object->getTableName() . '_range';
|
|
}
|
|
|
|
protected function loadFromDb()
|
|
{
|
|
$db = $this->object->getDb();
|
|
$connection = $this->object->getConnection();
|
|
|
|
$table = $this->getRangeTableName();
|
|
|
|
$query = $db->select()
|
|
->from(['o' => $table])
|
|
->where('o.' . $this->objectIdColumn . ' = ?', (int) $this->object->get('id'))
|
|
->order('o.range_key');
|
|
|
|
$class = $this->getRangeClass();
|
|
$this->ranges = $class::loadAll($connection, $query, 'range_key');
|
|
$this->setBeingLoadedFromDb();
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function setBeingLoadedFromDb()
|
|
{
|
|
$this->storedRanges = [];
|
|
|
|
foreach ($this->ranges as $key => $range) {
|
|
$range->setBeingLoadedFromDb();
|
|
$this->storedRanges[$key] = clone($range);
|
|
}
|
|
$this->refreshIndex();
|
|
$this->modified = false;
|
|
}
|
|
|
|
public function store()
|
|
{
|
|
$db = $this->object->getConnection();
|
|
if (! $this->hasBeenModified()) {
|
|
return false;
|
|
}
|
|
|
|
$table = $this->getRangeTableName();
|
|
$objectId = (int) $this->object->get('id');
|
|
$idColumn = $this->objectIdColumn;
|
|
foreach ($this->ranges as $range) {
|
|
if ($range->hasBeenModified()) {
|
|
$range->setConnection($db);
|
|
if ((int) $range->get($idColumn) !== $objectId) {
|
|
$range->set($idColumn, $objectId);
|
|
}
|
|
}
|
|
}
|
|
|
|
foreach (array_diff(array_keys($this->storedRanges), array_keys($this->ranges)) as $delete) {
|
|
$range = $this->storedRanges[$delete];
|
|
$range->setConnection($db);
|
|
$range->set($idColumn, $objectId);
|
|
$db->getDbAdapter()->delete($table, $range->createWhere());
|
|
unset($this->ranges[$delete]);
|
|
}
|
|
foreach ($this->ranges as $range) {
|
|
$range->store();
|
|
}
|
|
$this->setBeingLoadedFromDb();
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* @return IcingaTimePeriodRange|IcingaScheduledDowntimeRange|string IDE hint
|
|
*/
|
|
protected function getRangeClass()
|
|
{
|
|
return $this->rangeClass;
|
|
}
|
|
|
|
public static function loadForStoredObject(IcingaObject $object)
|
|
{
|
|
$ranges = new static($object);
|
|
return $ranges->loadFromDb();
|
|
}
|
|
|
|
public function toConfigString()
|
|
{
|
|
if (empty($this->ranges) && $this->object->object_type === 'template') {
|
|
return '';
|
|
}
|
|
|
|
$string = " ranges = {\n";
|
|
|
|
foreach ($this->ranges as $range) {
|
|
$string .= sprintf(
|
|
" %s\t= %s\n",
|
|
c::renderString($range->range_key),
|
|
c::renderString($range->range_value)
|
|
);
|
|
}
|
|
|
|
return $string . " }\n";
|
|
}
|
|
|
|
abstract public function toLegacyConfigString();
|
|
|
|
public function __toString()
|
|
{
|
|
try {
|
|
return $this->toConfigString();
|
|
} catch (Exception $e) {
|
|
trigger_error($e);
|
|
$previousHandler = set_exception_handler(
|
|
function () {
|
|
}
|
|
);
|
|
restore_error_handler();
|
|
if ($previousHandler !== null) {
|
|
call_user_func($previousHandler, $e);
|
|
die();
|
|
} else {
|
|
die($e->getMessage());
|
|
}
|
|
}
|
|
}
|
|
}
|