MultiEdit: make it independent of an object type

This commit is contained in:
Thomas Gelf 2016-10-14 18:32:34 +00:00
parent 6a54e00402
commit 23ef9a707c
4 changed files with 130 additions and 68 deletions

View File

@ -6,4 +6,8 @@ use Icinga\Module\Director\Web\Controller\ObjectsController;
class HostsController extends ObjectsController class HostsController extends ObjectsController
{ {
protected $multiEdit = array(
'imports',
'groups'
);
} }

View File

@ -2,8 +2,10 @@
namespace Icinga\Module\Director\Forms; 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\IcingaObjectFieldLoader;
use Icinga\Module\Director\Web\Form\DirectorObjectForm; use Icinga\Module\Director\Web\Form\DirectorObjectForm;
use Icinga\Module\Director\Web\Form\QuickForm;
use Zend_Form_Element as ZfElement; use Zend_Form_Element as ZfElement;
class IcingaMultiEditForm extends DirectorObjectForm class IcingaMultiEditForm extends DirectorObjectForm
@ -12,6 +14,10 @@ class IcingaMultiEditForm extends DirectorObjectForm
private $elementGroupMap; private $elementGroupMap;
private $relatedForm;
private $propertiesToPick;
public function setObjects($objects) public function setObjects($objects)
{ {
$this->objects = $objects; $this->objects = $objects;
@ -20,19 +26,36 @@ class IcingaMultiEditForm extends DirectorObjectForm
return $this; return $this;
} }
public function pickElementsFrom(QuickForm $form, $properties)
{
$this->relatedForm = $form;
$this->propertiesToPick = $properties;
return $this;
}
public function setup() public function setup()
{ {
$object = $this->object; $object = $this->object;
$this->addImportsElement();
// $this->addDisabledElement();
$loader = new IcingaObjectFieldLoader($object); $loader = new IcingaObjectFieldLoader($object);
$loader->addFieldsToForm($this); $loader->addFieldsToForm($this);
$this->makeVariants($this->getElement('imports')); if ($form = $this->relatedForm) {
// $this->makeVariants($this->getElement('disabled')); $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) { foreach ($this->getElements() as $el) {
$name =$el->getName(); $name = $el->getName();
if (substr($name, 0, 4) === 'var_') { if (substr($name, 0, 4) === 'var_') {
$this->makeVariants($el); $this->makeVariants($el);
} }
@ -41,50 +64,13 @@ class IcingaMultiEditForm extends DirectorObjectForm
$this->setButtons(); $this->setButtons();
} }
/**
* No default objects behaviour
*/
protected function onRequest()
{
}
public function onSuccess() public function onSuccess()
{ {
foreach ($this->getValues() as $key => $value) { foreach ($this->getValues() as $key => $value) {
$parts = preg_split('/_/', $key); $this->setSubmittedMultiValue($key, $value);
$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;
}
}
}
$modified = 0;
foreach ($this->objects as $object) {
if ($object->hasBeenModified()) {
$modified++;
$object->store();
}
} }
$modified = $this->storeModifiedObjects();
if ($modified === 0) { if ($modified === 0) {
$msg = $this->translate('No object has been modified'); $msg = $this->translate('No object has been modified');
} elseif ($modified === 1) { } elseif ($modified === 1) {
@ -99,6 +85,54 @@ class IcingaMultiEditForm extends DirectorObjectForm
$this->redirectOnSuccess($msg); $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) protected function getDisplayGroupForElement(ZfElement $element)
{ {
if ($this->elementGroupMap === null) { if ($this->elementGroupMap === null) {
@ -107,17 +141,46 @@ class IcingaMultiEditForm extends DirectorObjectForm
$name = $element->getName(); $name = $element->getName();
if (array_key_exists($name, $this->elementGroupMap)) { if (array_key_exists($name, $this->elementGroupMap)) {
return $this->getDisplayGroup($this->elementGroupMap[$name]); $groupName = $this->elementGroupMap[$name];
if ($group = $this->getDisplayGroup($groupName)) {
return $group;
} elseif ($this->relatedForm) {
return $this->stealDisplayGroup($groupName, $this->relatedForm);
}
} else { } else {
return null; 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() protected function resolveDisplayGroups()
{ {
$this->elementGroupMap = array(); $this->elementGroupMap = array();
if ($form = $this->relatedForm) {
$this->extractFormDisplayGroups($form, true);
}
foreach ($this->getDisplayGroups() as $group) { $this->extractFormDisplayGroups($this);
}
protected function extractFormDisplayGroups($form, $clone = false)
{
foreach ($form->getDisplayGroups() as $group) {
$groupName = $group->getName(); $groupName = $group->getName();
foreach ($group->getElements() as $name => $e) { foreach ($group->getElements() as $name => $e) {
$this->elementGroupMap[$name] = $groupName; $this->elementGroupMap[$name] = $groupName;
@ -127,10 +190,6 @@ class IcingaMultiEditForm extends DirectorObjectForm
protected function makeVariants(ZfElement $element) protected function makeVariants(ZfElement $element)
{ {
if (! $element) {
return $this;
}
$key = $element->getName(); $key = $element->getName();
$this->removeElement($key); $this->removeElement($key);
$label = $element->getLabel(); $label = $element->getLabel();
@ -190,22 +249,6 @@ class IcingaMultiEditForm extends DirectorObjectForm
return ' (' . count($list) . ')'; return ' (' . count($list) . ')';
} }
protected function enumTemplates()
{
$object = $this->object();
$tpl = $this->db()->enumIcingaTemplates($object->getShortTableName());
if (empty($tpl)) {
return array();
}
if (empty($tpl)) {
return array();
}
$tpl = array_combine($tpl, $tpl);
return $tpl;
}
protected function db() protected function db()
{ {
if ($this->db === null) { if ($this->db === null) {

View File

@ -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',
@ -196,6 +199,13 @@ abstract class ObjectsController extends ActionController
public function editAction() 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')); $this->singleTab($this->translate('Multiple objects'));
$filter = Filter::fromQueryString($this->params->toString()); $filter = Filter::fromQueryString($this->params->toString());
$dummy = $this->dummyObject(); $dummy = $this->dummyObject();
@ -209,9 +219,14 @@ abstract class ObjectsController extends ActionController
} }
} }
} }
$this->view->title = sprintf($this->translate('Modify %d objects'), count($objects)); $this->view->title = sprintf(
$this->translate('Modify %d objects'),
count($objects)
);
$this->view->form = $this->loadForm('IcingaMultiEdit') $this->view->form = $this->loadForm('IcingaMultiEdit')
->setObjects($objects) ->setObjects($objects)
->pickElementsFrom($this->loadForm($formName), $this->multiEdit)
->handleRequest(); ->handleRequest();
$this->setViewScript('objects/form'); $this->setViewScript('objects/form');

View File

@ -457,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;