2015-10-16 18:38:28 +02:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace Icinga\Module\Director\Objects;
|
|
|
|
|
|
|
|
use Icinga\Exception\ProgrammingError;
|
|
|
|
use Iterator;
|
|
|
|
use Countable;
|
|
|
|
use Icinga\Module\Director\IcingaConfig\IcingaConfigRenderer;
|
|
|
|
use Icinga\Module\Director\IcingaConfig\IcingaConfigHelper as c;
|
|
|
|
use Icinga\Module\Director\Objects\IcingaCommandArgument;
|
|
|
|
|
|
|
|
class IcingaArguments implements Iterator, Countable, IcingaConfigRenderer
|
|
|
|
{
|
|
|
|
protected $storedArguments = array();
|
|
|
|
|
|
|
|
protected $arguments = array();
|
|
|
|
|
|
|
|
protected $modified = false;
|
|
|
|
|
|
|
|
protected $object;
|
|
|
|
|
|
|
|
private $position = 0;
|
|
|
|
|
|
|
|
protected $idx = array();
|
|
|
|
|
|
|
|
public function __construct(IcingaObject $object)
|
|
|
|
{
|
|
|
|
$this->object = $object;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function count()
|
|
|
|
{
|
|
|
|
return count($this->arguments);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function rewind()
|
|
|
|
{
|
|
|
|
$this->position = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function hasBeenModified()
|
|
|
|
{
|
|
|
|
return $this->modified;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function current()
|
|
|
|
{
|
|
|
|
if (! $this->valid()) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2015-12-02 02:50:41 +01:00
|
|
|
return $this->arguments[$this->idx[$this->position]];
|
2015-10-16 18:38:28 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public function key()
|
|
|
|
{
|
|
|
|
return $this->idx[$this->position];
|
|
|
|
}
|
|
|
|
|
|
|
|
public function next()
|
|
|
|
{
|
|
|
|
++$this->position;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function valid()
|
|
|
|
{
|
|
|
|
return array_key_exists($this->position, $this->idx);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function get($key)
|
|
|
|
{
|
|
|
|
if (array_key_exists($key, $this->arguments)) {
|
2016-03-28 23:49:04 +02:00
|
|
|
if ($this->arguments[$key]->shouldBeRemoved()) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2015-10-16 18:38:28 +02:00
|
|
|
return $this->arguments[$key];
|
|
|
|
}
|
|
|
|
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2015-12-02 02:50:41 +01:00
|
|
|
public function set($key, $value)
|
|
|
|
{
|
2016-08-01 12:45:47 +02:00
|
|
|
if ($value instanceof IcingaCommandArgument) {
|
|
|
|
$argument = $value;
|
|
|
|
} else {
|
|
|
|
$argument = IcingaCommandArgument::create(
|
|
|
|
$this->mungeCommandArgument($key, $value)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
$argument->set('command_id', $this->object->id);
|
|
|
|
|
2016-03-28 23:49:04 +02:00
|
|
|
$key = $argument->argument_name;
|
2016-03-21 10:12:49 +01:00
|
|
|
if (array_key_exists($key, $this->arguments)) {
|
|
|
|
$this->arguments[$key]->replaceWith($argument);
|
2016-03-28 23:49:04 +02:00
|
|
|
if ($this->arguments[$key]->hasBeenModified()) {
|
|
|
|
$this->modified = true;
|
|
|
|
}
|
2016-08-01 11:31:10 +02:00
|
|
|
} elseif (array_key_exists($key, $this->storedArguments)) {
|
|
|
|
$this->arguments[$key] = clone($this->storedArguments[$key]);
|
|
|
|
$this->arguments[$key]->replaceWith($argument);
|
|
|
|
if ($this->arguments[$key]->hasBeenModified()) {
|
|
|
|
$this->modified = true;
|
|
|
|
}
|
2016-03-21 10:12:49 +01:00
|
|
|
} else {
|
|
|
|
$this->add($argument);
|
2016-03-28 23:49:04 +02:00
|
|
|
$this->modified = true;
|
2016-03-21 10:12:49 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function mungeCommandArgument($key, $value)
|
|
|
|
{
|
2015-12-02 02:50:41 +01:00
|
|
|
$attrs = array(
|
2016-04-02 20:21:06 +02:00
|
|
|
'argument_name' => (string) $key,
|
2015-12-02 02:50:41 +01:00
|
|
|
);
|
|
|
|
|
|
|
|
$map = array(
|
|
|
|
'skip_key' => 'skip_key',
|
|
|
|
'repeat_key' => 'repeat_key',
|
2016-03-21 10:12:49 +01:00
|
|
|
'required' => 'required',
|
2016-04-02 20:21:06 +02:00
|
|
|
// 'order' => 'sort_order',
|
2015-12-02 02:50:41 +01:00
|
|
|
'description' => 'description',
|
|
|
|
'set_if' => 'set_if',
|
|
|
|
);
|
|
|
|
|
|
|
|
$argValue = null;
|
|
|
|
if (is_object($value)) {
|
2016-04-02 20:21:06 +02:00
|
|
|
if (property_exists($value, 'order')) {
|
|
|
|
$attrs['sort_order'] = (string) $value->order;
|
|
|
|
}
|
|
|
|
|
2015-12-02 02:50:41 +01:00
|
|
|
foreach ($map as $apiKey => $dbKey) {
|
|
|
|
if (property_exists($value, $apiKey)) {
|
|
|
|
$attrs[$dbKey] = $value->$apiKey;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (property_exists($value, 'type')) {
|
|
|
|
if ($value->type === 'Function') {
|
|
|
|
$attrs['argument_value'] = '/* Unable to fetch function body through API */';
|
|
|
|
$attrs['argument_format'] = 'expression';
|
|
|
|
}
|
2015-12-18 16:11:36 +01:00
|
|
|
} elseif (property_exists($value, 'value')) {
|
|
|
|
if (is_object($value->value)) {
|
|
|
|
if ($value->value->type === 'Function') {
|
|
|
|
$attrs['argument_value'] = '/* Unable to fetch function body through API */';
|
|
|
|
$attrs['argument_format'] = 'expression';
|
|
|
|
} else {
|
|
|
|
die('Unable to resolve command argument');
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
$argValue = $value->value;
|
|
|
|
if (is_string($argValue)) {
|
|
|
|
$attrs['argument_value'] = $argValue;
|
|
|
|
$attrs['argument_format'] = 'string';
|
|
|
|
} else {
|
2016-03-28 23:49:04 +02:00
|
|
|
$attrs['argument_value'] = $argValue;
|
2015-12-18 16:11:36 +01:00
|
|
|
$attrs['argument_format'] = 'json';
|
|
|
|
}
|
|
|
|
}
|
2015-12-02 02:50:41 +01:00
|
|
|
}
|
|
|
|
} else {
|
2015-12-18 16:11:36 +01:00
|
|
|
if (is_string($value)) {
|
|
|
|
$attrs['argument_value'] = $value;
|
|
|
|
$attrs['argument_format'] = 'string';
|
|
|
|
} else {
|
2016-03-28 23:49:04 +02:00
|
|
|
$attrs['argument_value'] = $value;
|
2015-12-18 16:11:36 +01:00
|
|
|
$attrs['argument_format'] = 'json';
|
|
|
|
}
|
2015-12-02 02:50:41 +01:00
|
|
|
}
|
|
|
|
|
2016-02-01 15:07:02 +01:00
|
|
|
if (array_key_exists('set_if', $attrs) && is_object($attrs['set_if'])) {
|
|
|
|
if ($attrs['set_if']->type === 'Function') {
|
|
|
|
$attrs['set_if'] = '/* Unable to fetch function body through API */';
|
|
|
|
$attrs['set_if_format'] = 'expression';
|
|
|
|
}
|
|
|
|
}
|
2015-12-02 02:50:41 +01:00
|
|
|
|
2016-03-21 10:12:49 +01:00
|
|
|
return $attrs;
|
|
|
|
}
|
2015-12-02 02:50:41 +01:00
|
|
|
|
2016-03-21 10:12:49 +01:00
|
|
|
// TODO -> UNFINISHED!!!
|
|
|
|
public function setArguments($arguments)
|
|
|
|
{
|
|
|
|
if (empty($arguments)) {
|
|
|
|
if (count($this->arguments)) {
|
|
|
|
$this->arguments = array();
|
|
|
|
$this->modified = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
$arguments = (array) $arguments;
|
|
|
|
|
|
|
|
foreach ($arguments as $arg => $val) {
|
|
|
|
$this->set($arg, $val);
|
|
|
|
}
|
|
|
|
|
|
|
|
foreach (array_diff(
|
|
|
|
array_keys($this->arguments),
|
|
|
|
array_keys($arguments)
|
|
|
|
) as $arg) {
|
2016-08-01 11:31:10 +02:00
|
|
|
if ($this->arguments[$arg]->hasBeenLoadedFromDb()) {
|
|
|
|
$this->arguments[$arg]->markForRemoval();
|
|
|
|
$this->modified = true;
|
|
|
|
} else {
|
|
|
|
unset($this->arguments[$arg]);
|
|
|
|
}
|
2016-03-21 10:12:49 +01:00
|
|
|
}
|
|
|
|
|
2015-12-02 02:50:41 +01:00
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
2015-10-16 18:38:28 +02:00
|
|
|
/**
|
|
|
|
* Magic isset check
|
|
|
|
*
|
|
|
|
* @return boolean
|
|
|
|
*/
|
2015-12-02 02:50:41 +01:00
|
|
|
public function __isset($argument)
|
2015-10-16 18:38:28 +02:00
|
|
|
{
|
2015-12-02 02:50:41 +01:00
|
|
|
return array_key_exists($argument, $this->arguments);
|
2015-10-16 18:38:28 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public function remove($argument)
|
|
|
|
{
|
2015-12-02 02:50:41 +01:00
|
|
|
if (array_key_exists($argument, $this->arguments)) {
|
2016-08-01 13:06:52 +02:00
|
|
|
$this->arguments[$argument]->markForRemoval();
|
|
|
|
$this->modified = true;
|
|
|
|
$this->refreshIndex();
|
2015-10-16 18:38:28 +02:00
|
|
|
}
|
|
|
|
|
2016-08-01 13:06:52 +02:00
|
|
|
return $this;
|
2015-10-16 18:38:28 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
protected function refreshIndex()
|
|
|
|
{
|
2015-12-02 02:50:41 +01:00
|
|
|
ksort($this->arguments);
|
|
|
|
$this->idx = array_keys($this->arguments);
|
2015-10-16 18:38:28 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public function add(IcingaCommandArgument $argument)
|
|
|
|
{
|
|
|
|
if (array_key_exists($argument->argument_name, $this->arguments)) {
|
|
|
|
// TODO: Fail unless $argument equals existing one
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
$this->arguments[$argument->argument_name] = $argument;
|
|
|
|
$connection = $this->object->getConnection();
|
|
|
|
$this->modified = true;
|
|
|
|
$this->refreshIndex();
|
|
|
|
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function getGroupTableName()
|
|
|
|
{
|
|
|
|
return $this->object->getTableName() . 'group';
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function loadFromDb()
|
|
|
|
{
|
|
|
|
$db = $this->object->getDb();
|
|
|
|
$connection = $this->object->getConnection();
|
|
|
|
|
|
|
|
$table = $this->object->getTableName();
|
|
|
|
$query = $db->select()->from(
|
|
|
|
array('o' => $table),
|
|
|
|
array()
|
|
|
|
)->join(
|
|
|
|
array('a' => 'icinga_command_argument'),
|
|
|
|
'o.id = a.command_id',
|
|
|
|
'*'
|
|
|
|
)->where('o.object_name = ?', $this->object->object_name)
|
|
|
|
->order('a.sort_order')->order('a.argument_name');
|
|
|
|
|
2016-03-28 23:49:04 +02:00
|
|
|
$this->arguments = IcingaCommandArgument::loadAll($connection, $query, 'argument_name');
|
2015-10-16 18:38:28 +02:00
|
|
|
$this->cloneStored();
|
2016-02-03 11:15:20 +01:00
|
|
|
$this->refreshIndex();
|
2015-10-16 18:38:28 +02:00
|
|
|
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
2016-03-18 13:46:06 +01:00
|
|
|
public function toPlainObject(
|
|
|
|
$resolved = false,
|
|
|
|
$skipDefaults = false,
|
|
|
|
array $chosenProperties = null,
|
|
|
|
$resolveIds = true
|
|
|
|
) {
|
|
|
|
$args = array();
|
|
|
|
foreach ($this->arguments as $arg) {
|
2016-03-28 23:49:04 +02:00
|
|
|
if ($arg->shouldBeRemoved()) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2016-03-24 13:35:31 +01:00
|
|
|
$args[$arg->argument_name] = $arg->toPlainObject(
|
|
|
|
$resolved,
|
|
|
|
$skipDefaults,
|
|
|
|
null,
|
|
|
|
$resolveIds
|
|
|
|
);
|
2016-03-18 13:46:06 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return $args;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function toUnmodifiedPlainObject()
|
|
|
|
{
|
|
|
|
$args = array();
|
2016-03-28 23:49:04 +02:00
|
|
|
foreach ($this->storedArguments as $key => $arg) {
|
|
|
|
$args[$arg->argument_name] = $arg->toPlainObject();
|
2016-03-18 13:46:06 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return $args;
|
|
|
|
}
|
|
|
|
|
2015-10-16 18:38:28 +02:00
|
|
|
protected function cloneStored()
|
|
|
|
{
|
|
|
|
$this->storedArguments = array();
|
|
|
|
foreach ($this->arguments as $k => $v) {
|
|
|
|
$this->storedArguments[$k] = clone($v);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public static function loadForStoredObject(IcingaObject $object)
|
|
|
|
{
|
2015-11-30 21:40:32 +01:00
|
|
|
$arguments = new static($object);
|
|
|
|
return $arguments->loadFromDb();
|
2015-10-16 18:38:28 +02:00
|
|
|
}
|
|
|
|
|
2015-12-02 02:50:41 +01:00
|
|
|
public function store()
|
|
|
|
{
|
|
|
|
$db = $this->object->getConnection();
|
|
|
|
|
2016-03-28 23:49:04 +02:00
|
|
|
$dummy = IcingaCommandArgument::create();
|
|
|
|
|
|
|
|
$deleted = array();
|
|
|
|
foreach ($this->arguments as $key => $argument) {
|
|
|
|
if ($argument->shouldBeRemoved()) {
|
|
|
|
$deleted[] = $key;
|
|
|
|
} else {
|
|
|
|
$argument->command_id = $this->object->id;
|
|
|
|
$argument->store($db);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
foreach ($deleted as $key) {
|
2016-08-01 13:06:52 +02:00
|
|
|
$this->arguments[$key]->delete();
|
2016-03-28 23:49:04 +02:00
|
|
|
unset($this->arguments[$key]);
|
2015-12-02 02:50:41 +01:00
|
|
|
}
|
|
|
|
|
2016-08-01 11:31:10 +02:00
|
|
|
$this->cloneStored();
|
2015-12-02 02:50:41 +01:00
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
2015-10-16 18:38:28 +02:00
|
|
|
public function toConfigString()
|
|
|
|
{
|
|
|
|
if (empty($this->arguments)) {
|
|
|
|
return '';
|
|
|
|
}
|
|
|
|
|
|
|
|
$args = array();
|
|
|
|
foreach ($this->arguments as $arg) {
|
2016-03-28 23:49:04 +02:00
|
|
|
if ($arg->shouldBeRemoved()) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2015-10-16 18:38:28 +02:00
|
|
|
$args[$arg->argument_name] = $arg->toConfigString();
|
|
|
|
}
|
|
|
|
return c::renderKeyValue('arguments', c::renderDictionary($args));
|
|
|
|
}
|
|
|
|
|
|
|
|
public function __toString()
|
|
|
|
{
|
|
|
|
try {
|
|
|
|
return $this->toConfigString();
|
|
|
|
} catch (Exception $e) {
|
|
|
|
trigger_error($e);
|
2016-02-26 11:58:37 +01:00
|
|
|
$previousHandler = set_exception_handler(
|
|
|
|
function () {
|
|
|
|
}
|
|
|
|
);
|
2015-10-16 18:38:28 +02:00
|
|
|
restore_error_handler();
|
|
|
|
if ($previousHandler !== null) {
|
|
|
|
call_user_func($previousHandler, $e);
|
|
|
|
die();
|
|
|
|
} else {
|
|
|
|
die($e->getMessage());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|