314 lines
7.4 KiB
PHP
314 lines
7.4 KiB
PHP
<?php
|
|
|
|
namespace Icinga\Module\Director\Objects;
|
|
|
|
use Icinga\Data\Filter\Filter;
|
|
use Icinga\Exception\ProgrammingError;
|
|
use Icinga\Module\Director\IcingaConfig\AssignRenderer;
|
|
use Icinga\Module\Director\IcingaConfig\IcingaConfigHelper as c;
|
|
|
|
class IcingaObjectAssignments
|
|
{
|
|
protected $object;
|
|
|
|
protected $stored;
|
|
|
|
protected $current;
|
|
|
|
public function __construct(IcingaObject $object)
|
|
{
|
|
if (! $object->isApplyRule()) {
|
|
throw new ProgrammingError(
|
|
'I can only assign for applied objects, got %s',
|
|
$object->object_type
|
|
);
|
|
}
|
|
|
|
$this->object = $object;
|
|
}
|
|
|
|
public function store()
|
|
{
|
|
if ($this->hasBeenModified()) {
|
|
$this->reallyStore();
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public function setValues($values)
|
|
{
|
|
if (is_string($values)) {
|
|
return $this->setValues(array($values));
|
|
}
|
|
|
|
$this->current = array();
|
|
if (is_object($values)) {
|
|
$values = (array) $values;
|
|
}
|
|
|
|
ksort($values);
|
|
foreach ((array) $values as $type => $value) {
|
|
if (is_numeric($type)) {
|
|
$this->addRule($value);
|
|
} else {
|
|
if (is_string($value)) {
|
|
$this->addRule($value, $type);
|
|
continue;
|
|
}
|
|
|
|
foreach ($value as $key => $strings) {
|
|
$this->addRule($strings, $type);
|
|
}
|
|
}
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function getFormValues()
|
|
{
|
|
$result = array();
|
|
foreach ($this->getCurrent() as $rule) {
|
|
$f = array(
|
|
'assign_type' => $rule['assign_type']
|
|
);
|
|
|
|
$filter = Filter::fromQueryString($rule['filter_string']);
|
|
if (!$filter->isExpression()) {
|
|
throw new IcingaException(
|
|
'We currently support only flat filters in our forms, got %',
|
|
(string) $filter
|
|
);
|
|
}
|
|
|
|
$f['property'] = $filter->getColumn();
|
|
$f['operator'] = $filter->getSign();
|
|
$f['expression'] = trim(stripcslashes($filter->getExpression()), '"');
|
|
|
|
$result[] = $f;
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
public function setFormValues($values)
|
|
{
|
|
$rows = array();
|
|
|
|
foreach ($values as $key => $val) {
|
|
if (! is_numeric($key)) {
|
|
// Skip buttons or similar
|
|
continue;
|
|
}
|
|
|
|
if (!array_key_exists($val['assign_type'], $rows)) {
|
|
$rows[$val['assign_type']] = array();
|
|
}
|
|
|
|
if (empty($val['property'])) {
|
|
continue;
|
|
}
|
|
|
|
if (is_numeric($val['expression'])) {
|
|
$expression = $val['expression'];
|
|
} else {
|
|
$expression = '"' . addcslashes($val['expression'], '"') . '"';
|
|
}
|
|
|
|
$rows[$val['assign_type']][] = $this->rerenderFilter(
|
|
implode('', array(
|
|
$val['property'],
|
|
$val['operator'],
|
|
$expression,
|
|
))
|
|
);
|
|
|
|
}
|
|
|
|
return $this->setValues($rows);
|
|
}
|
|
|
|
protected function addRule($string, $type = 'assign')
|
|
{
|
|
// TODO: validate
|
|
$this->current[] = array(
|
|
'assign_type' => $type,
|
|
'filter_string' => $this->rerenderFilter($string)
|
|
);
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function getValues()
|
|
{
|
|
return $this->getCurrent();
|
|
}
|
|
|
|
public function getUnmodifiedValues()
|
|
{
|
|
return $this->getStored();
|
|
}
|
|
|
|
public function toConfigString()
|
|
{
|
|
return $this->renderRules($this->getCurrent());
|
|
}
|
|
|
|
public function toUnmodifiedConfigString()
|
|
{
|
|
return $this->renderRules($this->getStored());
|
|
}
|
|
|
|
protected function renderRules($rules)
|
|
{
|
|
if (empty($rules)) {
|
|
return '';
|
|
}
|
|
|
|
$filters = array();
|
|
|
|
foreach ($rules as $rule) {
|
|
$filters[] = AssignRenderer::forFilter(
|
|
Filter::fromQueryString($rule['filter_string'])
|
|
)->render($rule['assign_type']);
|
|
}
|
|
|
|
return "\n " . implode("\n ", $filters) . "\n";
|
|
}
|
|
|
|
public function getPlain()
|
|
{
|
|
if ($this->current === null) {
|
|
if (! $this->object->hasBeenLoadedFromDb()) {
|
|
return array();
|
|
}
|
|
|
|
$this->current = $this->getStored();
|
|
}
|
|
|
|
return $this->createPlain($this->current);
|
|
}
|
|
|
|
public function getUnmodifiedPlain()
|
|
{
|
|
if (! $this->object->hasBeenLoadedFromDb()) {
|
|
return array();
|
|
}
|
|
|
|
return $this->createPlain($this->getStored());
|
|
}
|
|
|
|
public function hasBeenModified()
|
|
{
|
|
if ($this->current === null) {
|
|
return false;
|
|
}
|
|
|
|
return json_encode($this->getCurrent()) !== json_encode($this->getStored());
|
|
}
|
|
|
|
protected function getCurrent()
|
|
{
|
|
if ($this->current === null) {
|
|
$this->current = $this->getStored();
|
|
}
|
|
|
|
return $this->current;
|
|
}
|
|
|
|
protected function getStored()
|
|
{
|
|
if ($this->stored === null) {
|
|
$this->stored = $this->loadFromDb();
|
|
}
|
|
|
|
return $this->stored;
|
|
}
|
|
|
|
protected function rerenderFilter($string)
|
|
{
|
|
return rawurldecode(Filter::fromQueryString($string)->toQueryString());
|
|
}
|
|
|
|
protected function createPlain($dbRows)
|
|
{
|
|
$result = array();
|
|
foreach ($dbRows as $row) {
|
|
if (! array_key_exists($row['assign_type'], $result)) {
|
|
$result[$row['assign_type']] = array();
|
|
}
|
|
|
|
$result[$row['assign_type']][] = $row['filter_string'];
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
protected function getDb()
|
|
{
|
|
return $this->object->getDb();
|
|
}
|
|
|
|
protected function loadFromDb()
|
|
{
|
|
$db = $this->getDb();
|
|
$object = $this->object;
|
|
|
|
$query = $db->select()->from(
|
|
$this->getTableName(),
|
|
array('assign_type', 'filter_string')
|
|
)->where($this->createWhere())->order('assign_type', 'filter_string');
|
|
|
|
$this->stored = array();
|
|
foreach ($db->fetchAll($query) as $row) {
|
|
$this->stored[] = (array) $row;
|
|
}
|
|
|
|
return $this->stored;
|
|
}
|
|
|
|
protected function createWhere()
|
|
{
|
|
return $this->getRelationColumn()
|
|
. ' = '
|
|
. $this->getObjectId();
|
|
}
|
|
|
|
protected function getObjectId()
|
|
{
|
|
return (int) $this->object->id;
|
|
}
|
|
|
|
protected function getRelationColumn()
|
|
{
|
|
return $this->object->getShortTableName() . '_id';
|
|
}
|
|
|
|
protected function getTableName()
|
|
{
|
|
return $this->object->getTableName() . '_assignment';
|
|
}
|
|
|
|
protected function reallyStore()
|
|
{
|
|
$db = $this->getDb();
|
|
$table = $this->getTableName();
|
|
$objectId = $this->object->id;
|
|
$relationCol = $this->getRelationColumn();
|
|
|
|
$db->delete($table, $this->createWhere());
|
|
|
|
foreach ($this->getCurrent() as $row) {
|
|
$data = (array) $row;
|
|
$data[$relationCol] = $objectId;
|
|
$db->insert($table, $data);
|
|
}
|
|
|
|
$this->stored = $this->current;
|
|
|
|
return $this;
|
|
}
|
|
}
|