mirror of
https://github.com/Icinga/icingaweb2-module-director.git
synced 2025-07-29 08:44:11 +02:00
Merge branch 'feature/mass-edit-12033'
This commit is contained in:
commit
5a37ba8c68
@ -6,4 +6,8 @@ use Icinga\Module\Director\Web\Controller\ObjectsController;
|
|||||||
|
|
||||||
class HostsController extends ObjectsController
|
class HostsController extends ObjectsController
|
||||||
{
|
{
|
||||||
|
protected $multiEdit = array(
|
||||||
|
'imports',
|
||||||
|
'groups'
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
270
application/forms/IcingaMultiEditForm.php
Normal file
270
application/forms/IcingaMultiEditForm.php
Normal file
@ -0,0 +1,270 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Icinga\Module\Director\Forms;
|
||||||
|
|
||||||
|
use Icinga\Module\Director\Web\Form\FormLoader;
|
||||||
|
use Icinga\Module\Director\Web\Form\IcingaObjectFieldLoader;
|
||||||
|
use Icinga\Module\Director\Web\Form\DirectorObjectForm;
|
||||||
|
use Icinga\Module\Director\Web\Form\QuickForm;
|
||||||
|
use Zend_Form_Element as ZfElement;
|
||||||
|
|
||||||
|
class IcingaMultiEditForm extends DirectorObjectForm
|
||||||
|
{
|
||||||
|
private $objects;
|
||||||
|
|
||||||
|
private $elementGroupMap;
|
||||||
|
|
||||||
|
private $relatedForm;
|
||||||
|
|
||||||
|
private $propertiesToPick;
|
||||||
|
|
||||||
|
public function setObjects($objects)
|
||||||
|
{
|
||||||
|
$this->objects = $objects;
|
||||||
|
$this->object = current($this->objects);
|
||||||
|
$this->db = $this->object()->getConnection();
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function pickElementsFrom(QuickForm $form, $properties)
|
||||||
|
{
|
||||||
|
$this->relatedForm = $form;
|
||||||
|
$this->propertiesToPick = $properties;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setup()
|
||||||
|
{
|
||||||
|
$object = $this->object;
|
||||||
|
|
||||||
|
$loader = new IcingaObjectFieldLoader($object);
|
||||||
|
$loader->addFieldsToForm($this);
|
||||||
|
|
||||||
|
if ($form = $this->relatedForm) {
|
||||||
|
$form->setDb($object->getConnection())
|
||||||
|
->setObject($object)
|
||||||
|
->prepareElements();
|
||||||
|
} else {
|
||||||
|
$this->propertiesToPick = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($this->propertiesToPick as $property) {
|
||||||
|
if ($el = $form->getElement($property)) {
|
||||||
|
$this->makeVariants($el);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($this->getElements() as $el) {
|
||||||
|
$name = $el->getName();
|
||||||
|
if (substr($name, 0, 4) === 'var_') {
|
||||||
|
$this->makeVariants($el);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->setButtons();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onSuccess()
|
||||||
|
{
|
||||||
|
foreach ($this->getValues() as $key => $value) {
|
||||||
|
$this->setSubmittedMultiValue($key, $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
$modified = $this->storeModifiedObjects();
|
||||||
|
if ($modified === 0) {
|
||||||
|
$msg = $this->translate('No object has been modified');
|
||||||
|
} elseif ($modified === 1) {
|
||||||
|
$msg = $this->translate('One object has been modified');
|
||||||
|
} else {
|
||||||
|
$msg = sprintf(
|
||||||
|
$this->translate('%d objects have been modified'),
|
||||||
|
$modified
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->redirectOnSuccess($msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* No default objects behaviour
|
||||||
|
*/
|
||||||
|
protected function onRequest()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function setSubmittedMultiValue($key, $value)
|
||||||
|
{
|
||||||
|
$parts = preg_split('/_/', $key);
|
||||||
|
$objectsSum = array_pop($parts);
|
||||||
|
$valueSum = array_pop($parts);
|
||||||
|
$property = implode('_', $parts);
|
||||||
|
|
||||||
|
$found = false;
|
||||||
|
foreach ($this->getVariants($property) as $json => $objects) {
|
||||||
|
if ($valueSum !== sha1($json)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($objectsSum !== sha1(json_encode($objects))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$found = true;
|
||||||
|
if (substr($property, 0, 4) === 'var_') {
|
||||||
|
$property = 'vars.' . substr($property, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($this->getObjects($objects) as $object) {
|
||||||
|
$object->$property = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function storeModifiedObjects()
|
||||||
|
{
|
||||||
|
$modified = 0;
|
||||||
|
foreach ($this->objects as $object) {
|
||||||
|
if ($object->hasBeenModified()) {
|
||||||
|
$modified++;
|
||||||
|
$object->store();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $modified;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getDisplayGroupForElement(ZfElement $element)
|
||||||
|
{
|
||||||
|
if ($this->elementGroupMap === null) {
|
||||||
|
$this->resolveDisplayGroups();
|
||||||
|
}
|
||||||
|
|
||||||
|
$name = $element->getName();
|
||||||
|
if (array_key_exists($name, $this->elementGroupMap)) {
|
||||||
|
$groupName = $this->elementGroupMap[$name];
|
||||||
|
|
||||||
|
if ($group = $this->getDisplayGroup($groupName)) {
|
||||||
|
return $group;
|
||||||
|
} elseif ($this->relatedForm) {
|
||||||
|
return $this->stealDisplayGroup($groupName, $this->relatedForm);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function stealDisplayGroup($name, $form)
|
||||||
|
{
|
||||||
|
if ($group = $this->relatedForm->getDisplayGroup($name)) {
|
||||||
|
$group = clone($group);
|
||||||
|
$group->setElements(array());
|
||||||
|
$this->_displayGroups[$name] = $group;
|
||||||
|
$this->_order[$name] = $this->_displayGroups[$name]->getOrder();
|
||||||
|
$this->_orderUpdated = true;
|
||||||
|
|
||||||
|
return $group;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function resolveDisplayGroups()
|
||||||
|
{
|
||||||
|
$this->elementGroupMap = array();
|
||||||
|
if ($form = $this->relatedForm) {
|
||||||
|
$this->extractFormDisplayGroups($form, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->extractFormDisplayGroups($this);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function extractFormDisplayGroups($form, $clone = false)
|
||||||
|
{
|
||||||
|
foreach ($form->getDisplayGroups() as $group) {
|
||||||
|
$groupName = $group->getName();
|
||||||
|
foreach ($group->getElements() as $name => $e) {
|
||||||
|
$this->elementGroupMap[$name] = $groupName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function makeVariants(ZfElement $element)
|
||||||
|
{
|
||||||
|
$key = $element->getName();
|
||||||
|
$this->removeElement($key);
|
||||||
|
$label = $element->getLabel();
|
||||||
|
$group = $this->getDisplayGroupForElement($element);
|
||||||
|
$description = $element->getDescription();
|
||||||
|
|
||||||
|
foreach ($this->getVariants($key) as $json => $objects) {
|
||||||
|
$value = json_decode($json);
|
||||||
|
$checksum = sha1($json) . '_' . sha1(json_encode($objects));
|
||||||
|
|
||||||
|
$v = clone($element);
|
||||||
|
$v->setName($key . '_' . $checksum);
|
||||||
|
$v->setDescription($description . '. ' . $this->descriptionForObjects($objects));
|
||||||
|
$v->setLabel($label . $this->labelCount($objects));
|
||||||
|
$v->setValue($value);
|
||||||
|
if ($group) {
|
||||||
|
$group->addElement($v);
|
||||||
|
}
|
||||||
|
$this->addElement($v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getVariants($key)
|
||||||
|
{
|
||||||
|
$variants = array();
|
||||||
|
if (substr($key, 0, 4) === 'var_') {
|
||||||
|
$key = 'vars.' . substr($key, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($this->objects as $name => $object) {
|
||||||
|
$value = json_encode($object->$key);
|
||||||
|
if (! array_key_exists($value, $variants)) {
|
||||||
|
$variants[$value] = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
$variants[$value][] = $name;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($variants as & $objects) {
|
||||||
|
natsort($objects);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $variants;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function descriptionForObjects($list)
|
||||||
|
{
|
||||||
|
return sprintf(
|
||||||
|
$this->translate('Changing this value affects %d object(s): %s'),
|
||||||
|
count($list),
|
||||||
|
implode(', ', $list)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function labelCount($list)
|
||||||
|
{
|
||||||
|
return ' (' . count($list) . ')';
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function db()
|
||||||
|
{
|
||||||
|
if ($this->db === null) {
|
||||||
|
$this->db = $this->object()->getConnection();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->db;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getObjects($names)
|
||||||
|
{
|
||||||
|
$res = array();
|
||||||
|
foreach ($names as $name) {
|
||||||
|
$res[$name] = $this->objects[$name];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $res;
|
||||||
|
}
|
||||||
|
}
|
@ -34,6 +34,15 @@ class IcingaHostTable extends IcingaObjectTable
|
|||||||
return $this->url('director/host', array('name' => $row->host));
|
return $this->url('director/host', array('name' => $row->host));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function getMultiselectProperties()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
'url' => 'director/hosts/edit',
|
||||||
|
'sourceUrl' => 'director/hosts',
|
||||||
|
'keys' => array('name'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public function getTitles()
|
public function getTitles()
|
||||||
{
|
{
|
||||||
$view = $this->view();
|
$view = $this->view();
|
||||||
|
@ -90,6 +90,17 @@ abstract class ActionController extends Controller
|
|||||||
$this->sendJson((object) array('error' => $message));
|
$this->sendJson((object) array('error' => $message));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function singleTab($label)
|
||||||
|
{
|
||||||
|
return $this->view->tabs = Widget::create('tabs')->add(
|
||||||
|
'tab',
|
||||||
|
array(
|
||||||
|
'label' => $label,
|
||||||
|
'url' => $this->getRequest()->getUrl()
|
||||||
|
)
|
||||||
|
)->activate('tab');
|
||||||
|
}
|
||||||
|
|
||||||
protected function setConfigTabs()
|
protected function setConfigTabs()
|
||||||
{
|
{
|
||||||
$this->view->tabs = Widget::create('tabs')->add(
|
$this->view->tabs = Widget::create('tabs')->add(
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace Icinga\Module\Director\Web\Controller;
|
namespace Icinga\Module\Director\Web\Controller;
|
||||||
|
|
||||||
|
use Icinga\Exception\NotFoundError;
|
||||||
use Icinga\Data\Filter\Filter;
|
use Icinga\Data\Filter\Filter;
|
||||||
use Icinga\Module\Director\Objects\IcingaObject;
|
use Icinga\Module\Director\Objects\IcingaObject;
|
||||||
use Icinga\Module\Director\Web\Table\IcingaObjectTable;
|
use Icinga\Module\Director\Web\Table\IcingaObjectTable;
|
||||||
@ -12,6 +13,8 @@ abstract class ObjectsController extends ActionController
|
|||||||
|
|
||||||
protected $isApified = true;
|
protected $isApified = true;
|
||||||
|
|
||||||
|
protected $multiEdit = array();
|
||||||
|
|
||||||
protected $globalTypes = array(
|
protected $globalTypes = array(
|
||||||
'ApiUser',
|
'ApiUser',
|
||||||
'Zone',
|
'Zone',
|
||||||
@ -194,6 +197,41 @@ abstract class ObjectsController extends ActionController
|
|||||||
$this->setViewScript('objects/table');
|
$this->setViewScript('objects/table');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function editAction()
|
||||||
|
{
|
||||||
|
$type = ucfirst($this->getType());
|
||||||
|
|
||||||
|
if (empty($this->multiEdit)) {
|
||||||
|
throw new NotFoundError('Cannot edit multiple "%s" instances', $type);
|
||||||
|
}
|
||||||
|
$formName = 'icinga' . $type;
|
||||||
|
|
||||||
|
$this->singleTab($this->translate('Multiple objects'));
|
||||||
|
$filter = Filter::fromQueryString($this->params->toString());
|
||||||
|
$dummy = $this->dummyObject();
|
||||||
|
$objects = array();
|
||||||
|
$db = $this->db();
|
||||||
|
foreach ($filter->filters() as $sub) {
|
||||||
|
foreach ($sub->filters() as $ex) {
|
||||||
|
if ($ex->isExpression() && $ex->getColumn() === 'name') {
|
||||||
|
$name = $ex->getExpression();
|
||||||
|
$objects[$name] = $dummy::load($name, $db);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$this->view->title = sprintf(
|
||||||
|
$this->translate('Modify %d objects'),
|
||||||
|
count($objects)
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->view->form = $this->loadForm('IcingaMultiEdit')
|
||||||
|
->setObjects($objects)
|
||||||
|
->pickElementsFrom($this->loadForm($formName), $this->multiEdit)
|
||||||
|
->handleRequest();
|
||||||
|
|
||||||
|
$this->setViewScript('objects/form');
|
||||||
|
}
|
||||||
|
|
||||||
public function templatesAction()
|
public function templatesAction()
|
||||||
{
|
{
|
||||||
$this->indexAction();
|
$this->indexAction();
|
||||||
|
@ -257,7 +257,11 @@ abstract class DirectorObjectForm extends QuickForm
|
|||||||
protected function handleCustomVars($object, & $values)
|
protected function handleCustomVars($object, & $values)
|
||||||
{
|
{
|
||||||
if ($this->assertResolvedImports()) {
|
if ($this->assertResolvedImports()) {
|
||||||
IcingaObjectFieldLoader::addFieldsToForm($this, $object, $values);
|
$loader = new IcingaObjectFieldLoader($object);
|
||||||
|
$loader->addFieldsToForm($this);
|
||||||
|
if ($values) {
|
||||||
|
$loader->setValues($values, 'var_');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -453,7 +457,7 @@ abstract class DirectorObjectForm extends QuickForm
|
|||||||
{
|
{
|
||||||
$this->object = $object;
|
$this->object = $object;
|
||||||
if ($this->db === null) {
|
if ($this->db === null) {
|
||||||
$this->setDb($db);
|
$this->setDb($object->getConnection());
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
|
@ -2,10 +2,11 @@
|
|||||||
|
|
||||||
namespace Icinga\Module\Director\Web\Form;
|
namespace Icinga\Module\Director\Web\Form;
|
||||||
|
|
||||||
|
use stdClass;
|
||||||
use Icinga\Module\Director\Objects\IcingaObject;
|
use Icinga\Module\Director\Objects\IcingaObject;
|
||||||
use Icinga\Module\Director\Objects\IcingaServiceSet;
|
use Icinga\Module\Director\Objects\IcingaServiceSet;
|
||||||
use Icinga\Module\Director\Objects\DirectorDatafield;
|
use Icinga\Module\Director\Objects\DirectorDatafield;
|
||||||
use stdClass;
|
use Zend_Form_Element as ZfElement;
|
||||||
|
|
||||||
class IcingaObjectFieldLoader
|
class IcingaObjectFieldLoader
|
||||||
{
|
{
|
||||||
@ -13,95 +14,172 @@ class IcingaObjectFieldLoader
|
|||||||
|
|
||||||
protected $object;
|
protected $object;
|
||||||
|
|
||||||
protected function __construct(DirectorObjectForm $form, IcingaObject $object)
|
protected $fields;
|
||||||
|
|
||||||
|
protected $elements;
|
||||||
|
|
||||||
|
public function __construct(IcingaObject $object)
|
||||||
{
|
{
|
||||||
$this->form = $form;
|
|
||||||
$this->object = $object;
|
$this->object = $object;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function addFieldsToForm(DirectorObjectForm $form, IcingaObject $object, & $values)
|
public function addFieldsToForm(QuickForm $form)
|
||||||
{
|
{
|
||||||
if (! $object->supportsCustomVars()) {
|
if ($this->object->supportsCustomVars()) {
|
||||||
return $form;
|
$this->attachFieldsToForm($form);
|
||||||
}
|
}
|
||||||
|
|
||||||
$loader = new static($form, $object);
|
return $this;
|
||||||
$loader->addFields();
|
|
||||||
if ($values !== null) {
|
|
||||||
$loader->setValues($loader->stripKeyPrefix($values, 'var_'));
|
|
||||||
}
|
|
||||||
|
|
||||||
return $form;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function stripKeyPrefix($array, $prefix)
|
/**
|
||||||
|
* Set a list of values
|
||||||
|
*
|
||||||
|
* Works in a failsafe way, when a field does not exist the value will be
|
||||||
|
* silently ignored
|
||||||
|
*
|
||||||
|
* @param Array $values key/value pairs with variable names and their value
|
||||||
|
* @param String $prefix An optional prefix that would be stripped from keys
|
||||||
|
*
|
||||||
|
* @return self
|
||||||
|
*/
|
||||||
|
public function setValues($values, $prefix = null)
|
||||||
{
|
{
|
||||||
$new = array();
|
if ($prefix !== null) {
|
||||||
$len = strlen($prefix);
|
$len = strlen($prefix);
|
||||||
foreach ($array as $key => $value) {
|
|
||||||
if (substr($key, 0, $len) === $prefix) {
|
|
||||||
$new[substr($key, $len)] = $value;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $new;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function setValues($values)
|
|
||||||
{
|
|
||||||
$vars = $this->object->vars();
|
$vars = $this->object->vars();
|
||||||
$form = $this->form;
|
|
||||||
|
|
||||||
foreach ($values as $key => $value) {
|
foreach ($values as $key => $value) {
|
||||||
if ($el = $form->getElement('var_' . $key)) {
|
if ($prefix) {
|
||||||
if ($value === '' || $value === null) {
|
if (substr($key, 0, $len) === $prefix) {
|
||||||
|
$key = substr($key, $len);
|
||||||
|
} else {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($el = $this->getElement($key)) {
|
||||||
$el->setValue($value);
|
$el->setValue($value);
|
||||||
$vars->set($key, $el->getValue());
|
$value = $el->getValue();
|
||||||
|
|
||||||
|
if ($value === '') {
|
||||||
|
$value = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$vars->set($key, $value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the fields for our object
|
||||||
|
*
|
||||||
|
* @return DirectorDatafield[]
|
||||||
|
*/
|
||||||
|
public function getFields()
|
||||||
|
{
|
||||||
|
if ($this->fields === null) {
|
||||||
|
$this->fields = $this->prepareObjectFields($this->object);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->fields;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the form elements for our fields
|
||||||
|
*
|
||||||
|
* @param QuickForm $form Optional
|
||||||
|
*
|
||||||
|
* @return ZfElement[]
|
||||||
|
*/
|
||||||
|
public function getElements(QuickForm $form = null)
|
||||||
|
{
|
||||||
|
if ($this->elements === null) {
|
||||||
|
$this->elements = $this->createElements($form);
|
||||||
|
$this->setValuesFromObject($this->object);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->elements;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attach our form fields to the given form
|
||||||
|
*
|
||||||
|
* This will also create a 'Custom properties' display group
|
||||||
|
*/
|
||||||
|
protected function attachFieldsToForm(QuickForm $form)
|
||||||
|
{
|
||||||
|
$elements = $this->getElements($form);
|
||||||
|
|
||||||
|
if (! empty($elements)) {
|
||||||
|
$form->addElementsToGroup(
|
||||||
|
$elements,
|
||||||
|
'custom_fields',
|
||||||
|
50,
|
||||||
|
$form->translate('Custom properties')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the form element for a specific field by it's variable name
|
||||||
|
*
|
||||||
|
* @return ZfElement|null
|
||||||
|
*/
|
||||||
|
protected function getElement($name)
|
||||||
|
{
|
||||||
|
$elements = $this->getElements();
|
||||||
|
if (array_key_exists($name, $elements)) {
|
||||||
|
return $this->elements[$name];
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the form elements based on the given form
|
||||||
|
*
|
||||||
|
* @return ZfElement[]
|
||||||
|
*/
|
||||||
|
protected function createElements(QuickForm $form)
|
||||||
|
{
|
||||||
|
$elements = array();
|
||||||
|
|
||||||
|
foreach ($this->getFields() as $name => $field) {
|
||||||
|
$elements[$name] = $field->getFormElement($form);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $elements;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function setValuesFromObject(IcingaObject $object)
|
||||||
|
{
|
||||||
|
foreach ($object->getVars() as $k => $v) {
|
||||||
|
if ($v !== null && $el = $this->getElement($k)) {
|
||||||
|
$el->setValue($v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function addFields()
|
protected function mergeFields($listOfFields)
|
||||||
{
|
{
|
||||||
$object = $this->object;
|
// TODO: Merge field for different object, mostly sets
|
||||||
if ($object instanceof IcingaServiceSet) {
|
|
||||||
} else {
|
|
||||||
$this->attachFields(
|
|
||||||
$this->prepareObjectFields($object)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->setValues($object->getVars());
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function attachFields($fields)
|
|
||||||
{
|
|
||||||
$form = $this->form;
|
|
||||||
$elements = array();
|
|
||||||
foreach ($fields as $field) {
|
|
||||||
$elements[] = $field->getFormElement($form);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (empty($elements)) {
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $form->addElementsToGroup(
|
|
||||||
$elements,
|
|
||||||
'custom_fields',
|
|
||||||
50,
|
|
||||||
$form->translate('Custom properties')
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the fields for our object
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @return DirectorDatafield[]
|
||||||
|
*/
|
||||||
protected function prepareObjectFields($object)
|
protected function prepareObjectFields($object)
|
||||||
{
|
{
|
||||||
$fields = $this->loadResolvedFieldsForObject($object);
|
$fields = $this->loadResolvedFieldsForObject($object);
|
||||||
|
if ($object->hasRelation('check_command')) {
|
||||||
if ($object->hasProperty('command_id')) {
|
$command = $object->getResolvedRelated('check_command');
|
||||||
$command = $object->getResolvedRelated('command');
|
|
||||||
if ($command) {
|
if ($command) {
|
||||||
$cmdFields = $this->loadResolvedFieldsForObject($command);
|
$cmdFields = $this->loadResolvedFieldsForObject($command);
|
||||||
foreach ($cmdFields as $varname => $field) {
|
foreach ($cmdFields as $varname => $field) {
|
||||||
@ -115,11 +193,14 @@ class IcingaObjectFieldLoader
|
|||||||
return $fields;
|
return $fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function mergeFields($listOfFields)
|
/**
|
||||||
{
|
* Create the fields for our object
|
||||||
// TODO: Merge field for different object, mostly sets
|
*
|
||||||
}
|
* Follows the inheritance logic, resolves all fields and keeps the most
|
||||||
|
* specific ones. Returns a list of fields indexed by variable name
|
||||||
|
*
|
||||||
|
* @return DirectorDatafield[]
|
||||||
|
*/
|
||||||
protected function loadResolvedFieldsForObject($object)
|
protected function loadResolvedFieldsForObject($object)
|
||||||
{
|
{
|
||||||
$result = $this->loadDataFieldsForObjects(
|
$result = $this->loadDataFieldsForObjects(
|
||||||
@ -139,11 +220,16 @@ class IcingaObjectFieldLoader
|
|||||||
return $fields;
|
return $fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getDb()
|
/**
|
||||||
{
|
* Fetches fields for a given List of objects from the database
|
||||||
return $this->form->getDb();
|
*
|
||||||
}
|
* Gives a list indexed by object id, with each entry being a list of that
|
||||||
|
* objects DirectorDatafield instances indexed by variable name
|
||||||
|
*
|
||||||
|
* @param IcingaObject[] $objectList List of objects
|
||||||
|
*
|
||||||
|
* @return Array
|
||||||
|
*/
|
||||||
protected function loadDataFieldsForObjects($objectList)
|
protected function loadDataFieldsForObjects($objectList)
|
||||||
{
|
{
|
||||||
$ids = array();
|
$ids = array();
|
||||||
|
@ -67,6 +67,41 @@ abstract class QuickTable implements Paginatable
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function getMultiselectProperties()
|
||||||
|
{
|
||||||
|
/* array(
|
||||||
|
* 'url' => 'director/hosts/edit',
|
||||||
|
* 'sourceUrl' => 'director/hosts',
|
||||||
|
* 'keys' => 'name'
|
||||||
|
* ) */
|
||||||
|
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function renderMultiselectAttributes()
|
||||||
|
{
|
||||||
|
$props = $this->getMultiselectProperties();
|
||||||
|
|
||||||
|
if (empty($props)) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
$prefix = 'data-icinga-multiselect-';
|
||||||
|
$view = $this->view();
|
||||||
|
$parts = array();
|
||||||
|
$multi = array(
|
||||||
|
'url' => $view->href($props['url']),
|
||||||
|
'controllers' => $view->href($props['sourceUrl']),
|
||||||
|
'data' => implode(',', $props['keys']),
|
||||||
|
);
|
||||||
|
|
||||||
|
foreach ($multi as $k => $v) {
|
||||||
|
$parts[] = $prefix . $k . '="' . $v . '"';
|
||||||
|
}
|
||||||
|
|
||||||
|
return ' ' . implode(' ', $parts);
|
||||||
|
}
|
||||||
|
|
||||||
protected function renderRow($row)
|
protected function renderRow($row)
|
||||||
{
|
{
|
||||||
$htm = " <tr" . $this->getRowClassesString($row) . ">\n";
|
$htm = " <tr" . $this->getRowClassesString($row) . ">\n";
|
||||||
@ -245,14 +280,22 @@ abstract class QuickTable implements Paginatable
|
|||||||
|
|
||||||
protected function listTableClasses()
|
protected function listTableClasses()
|
||||||
{
|
{
|
||||||
return array('simple', 'common-table', 'table-row-selectable');
|
$classes = array('simple', 'common-table', 'table-row-selectable');
|
||||||
|
if (! empty($this->getMultiselectProperties())) {
|
||||||
|
$classes[] = 'multiselect';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $classes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function render()
|
public function render()
|
||||||
{
|
{
|
||||||
$data = $this->fetchData();
|
$data = $this->fetchData();
|
||||||
|
|
||||||
$htm = '<table' . $this->createClassAttribute($this->listTableClasses()) . '>' . "\n"
|
$htm = '<table'
|
||||||
|
. $this->createClassAttribute($this->listTableClasses())
|
||||||
|
. $this->renderMultiselectAttributes()
|
||||||
|
. '>' . "\n"
|
||||||
. $this->renderTitles($this->getTitles())
|
. $this->renderTitles($this->getTitles())
|
||||||
. "<tbody>\n";
|
. "<tbody>\n";
|
||||||
foreach ($data as $row) {
|
foreach ($data as $row) {
|
||||||
|
@ -99,15 +99,16 @@
|
|||||||
extensibleSetAction: function(ev)
|
extensibleSetAction: function(ev)
|
||||||
{
|
{
|
||||||
var el = ev.currentTarget;
|
var el = ev.currentTarget;
|
||||||
|
|
||||||
if (el.name.match(/__MOVE_UP$/)) {
|
if (el.name.match(/__MOVE_UP$/)) {
|
||||||
var $li = $(el).closest('li');
|
var $li = $(el).closest('li');
|
||||||
var $prev = $li.prev()
|
var $prev = $li.prev();
|
||||||
|
// TODO: document what's going on here.
|
||||||
if ($li.find('input[type=text].autosubmit')) {
|
if ($li.find('input[type=text].autosubmit')) {
|
||||||
if (iid = $prev.find('input[type=text]').attr('id')) {
|
if (iid = $prev.find('input[type=text]').attr('id')) {
|
||||||
$li.closest('.container').data('activeExtensibleEntry', iid);
|
$li.closest('.container').data('activeExtensibleEntry', iid);
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
if ($prev.length) {
|
if ($prev.length) {
|
||||||
$prev.before($li.detach());
|
$prev.before($li.detach());
|
||||||
@ -118,12 +119,14 @@
|
|||||||
return false;
|
return false;
|
||||||
} else if (el.name.match(/__MOVE_DOWN$/)) {
|
} else if (el.name.match(/__MOVE_DOWN$/)) {
|
||||||
var $li = $(el).closest('li');
|
var $li = $(el).closest('li');
|
||||||
var $next = $li.next()
|
var $next = $li.next();
|
||||||
|
// TODO: document what's going on here.
|
||||||
if ($li.find('input[type=text].autosubmit')) {
|
if ($li.find('input[type=text].autosubmit')) {
|
||||||
if (iid = $next.find('input[type=text]').attr('id')) {
|
if (iid = $next.find('input[type=text]').attr('id')) {
|
||||||
$li.closest('.container').data('activeExtensibleEntry', iid);
|
$li.closest('.container').data('activeExtensibleEntry', iid);
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
if ($next.length && ! $next.find('.extend-set').length) {
|
if ($next.length && ! $next.find('.extend-set').length) {
|
||||||
$next.after($li.detach());
|
$next.after($li.detach());
|
||||||
|
Loading…
x
Reference in New Issue
Block a user