icingaweb2-module-director/library/Director/Objects/IcingaTemplateChoice.php

322 lines
8.4 KiB
PHP

<?php
namespace Icinga\Module\Director\Objects;
use Icinga\Exception\ProgrammingError;
use Icinga\Module\Director\Db;
use Icinga\Module\Director\DirectorObject\Automation\ExportInterface;
use Icinga\Module\Director\Exception\DuplicateKeyException;
use Icinga\Module\Director\Web\Form\QuickForm;
class IcingaTemplateChoice extends IcingaObject implements ExportInterface
{
protected $objectTable;
protected $defaultProperties = [
'id' => null,
'object_name' => null,
'description' => null,
'min_required' => 0,
'max_allowed' => 1,
'required_template_id' => null,
'allowed_roles' => null,
];
private $choices;
private $newChoices;
public function getObjectShortTableName()
{
return substr(substr($this->table, 0, -16), 7);
}
public function getUniqueIdentifier()
{
return $this->getObjectName();
}
/**
* @param $plain
* @param Db $db
* @param bool $replace
* @return IcingaTemplateChoice
* @throws DuplicateKeyException
* @throws \Icinga\Exception\NotFoundError
*/
public static function import($plain, Db $db, $replace = false)
{
$properties = (array) $plain;
if (isset($properties['originalId'])) {
unset($properties['originalId']);
}
$name = $properties['object_name'];
$key = $name;
if ($replace && static::exists($key, $db)) {
$object = static::load($key, $db);
} elseif (static::exists($key, $db)) {
throw new DuplicateKeyException(
'Template Choice "%s" already exists',
$name
);
} else {
$object = static::create([], $db);
}
$object->setProperties($properties);
return $object;
}
public function export()
{
$plain = (object) $this->getProperties();
$plain->originalId = $plain->id;
unset($plain->id);
$requiredId = $plain->required_template_id;
unset($plain->required_template_id);
if ($requiredId) {
$db = $this->getDb();
$query = $db->select()->from(
['o' => $this->getObjectTableName()],
['o.id', 'o.object_name']
)->where("o.object_type = 'template'")
->where('o.template_choice_id = ?', $this->get('id'))
->order('o.object_name');
return $db->fetchPairs($query);
}
$plain->members = array_values($this->getMembers());
return $plain;
}
public function isMainChoice()
{
return $this->hasBeenLoadedFromDb()
&& $this->connection->settings()->get('main_host_choice');
}
public function getObjectTableName()
{
return substr($this->table, 0, -16);
}
/**
* @param QuickForm $form
* @param array $imports
* @param string $namePrefix
* @return \Zend_Form_Element
* @throws \Zend_Form_Exception
*/
public function createFormElement(QuickForm $form, $imports = [], $namePrefix = 'choice')
{
$required = $this->isRequired() && !$this->isTemplate();
$type = $this->allowsMultipleChoices() ? 'multiselect' : 'select';
$choices = $this->enumChoices();
$chosen = [];
foreach ($imports as $import) {
if (array_key_exists($import, $choices)) {
$chosen[] = $import;
}
}
$attributes = [
'label' => $this->getObjectName(),
'description' => $this->get('description'),
'required' => $required,
'ignore' => true,
'value' => $chosen,
'multiOptions' => $form->optionalEnum($choices),
'class' => 'autosubmit'
];
// unused
if ($type === 'extensibleSet') {
$attributes['sorted'] = true;
}
$key = $namePrefix . $this->get('id');
return $form->createElement($type, $key, $attributes);
}
public function isRequired()
{
return (int) $this->get('min_required') > 0;
}
public function allowsMultipleChoices()
{
return (int) $this->get('max_allowed') > 1;
}
public function hasBeenModified()
{
if ($this->newChoices !== null && $this->choices !== $this->newChoices) {
return true;
}
return parent::hasBeenModified();
}
public function getMembers()
{
return $this->enumChoices();
}
public function setMembers($members)
{
if (empty($members)) {
$this->newChoices = array();
return $this;
}
$db = $this->getDb();
$query = $db->select()->from(
['o' => $this->getObjectTableName()],
['o.id', 'o.object_name']
)->where("o.object_type = 'template'")
->where('o.object_name IN (?)', $members)
->order('o.object_name');
$this->newChoices = $db->fetchPairs($query);
return $this;
}
public function getChoices()
{
if ($this->newChoices !== null) {
return $this->newChoices;
}
if ($this->choices === null) {
$this->choices = $this->fetchChoices();
}
return $this->choices;
}
public function fetchChoices()
{
if ($this->hasBeenLoadedFromDb()) {
$db = $this->getDb();
$query = $db->select()->from(
['o' => $this->getObjectTableName()],
['o.id', 'o.object_name']
)->where("o.object_type = 'template'")
->where('o.template_choice_id = ?', $this->get('id'))
->order('o.object_name');
return $db->fetchPairs($query);
} else {
return [];
}
}
public function enumChoices()
{
$choices = $this->getChoices();
return array_combine($choices, $choices);
}
/**
* @throws \Zend_Db_Adapter_Exception
*/
public function onStore()
{
parent::onStore();
if ($this->newChoices !== $this->choices) {
$this->storeChoices();
}
}
/**
* @throws \Zend_Db_Adapter_Exception
*/
protected function storeChoices()
{
$id = $this->getProperty('id');
$db = $this->getDb();
$ids = array_keys($this->newChoices);
$table = $this->getObjectTableName();
if (empty($ids)) {
$db->update(
$table,
['template_choice_id' => null],
$db->quoteInto(
sprintf('template_choice_id = %d', $id),
$ids
)
);
} else {
$db->update(
$table,
['template_choice_id' => null],
$db->quoteInto(
sprintf('template_choice_id = %d AND id NOT IN (?)', $id),
$ids
)
);
$db->update(
$table,
['template_choice_id' => $id],
$db->quoteInto('id IN (?)', $ids)
);
}
}
/**
* @param $roles
* @throws ProgrammingError
* @codingStandardsIgnoreStart
*/
public function setAllowed_roles($roles)
{
// @codingStandardsIgnoreEnd
$key = 'allowed_roles';
if (is_array($roles)) {
$this->reallySet($key, json_encode($roles));
} elseif (null === $roles) {
$this->reallySet($key, null);
} else {
throw new ProgrammingError(
'Expected array or null for allowed_roles, got %s',
var_export($roles, 1)
);
}
}
/**
* @return array|null
* @codingStandardsIgnoreStart
*/
public function getAllowed_roles()
{
// @codingStandardsIgnoreEnd
// Might be removed once all choice types have allowed_roles
if (! array_key_exists('allowed_roles', $this->properties)) {
return null;
}
$roles = $this->getProperty('allowed_roles');
if (is_string($roles)) {
return json_decode($roles);
} else {
return $roles;
}
}
/**
* @param $type
* @codingStandardsIgnoreStart
*/
public function setObject_type($type)
{
// @codingStandardsIgnoreEnd
}
}