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
{
protected $multiEdit = array(
'imports',
'groups'
);
}

View File

@ -2,8 +2,10 @@
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
@ -12,6 +14,10 @@ class IcingaMultiEditForm extends DirectorObjectForm
private $elementGroupMap;
private $relatedForm;
private $propertiesToPick;
public function setObjects($objects)
{
$this->objects = $objects;
@ -20,19 +26,36 @@ class IcingaMultiEditForm extends DirectorObjectForm
return $this;
}
public function pickElementsFrom(QuickForm $form, $properties)
{
$this->relatedForm = $form;
$this->propertiesToPick = $properties;
return $this;
}
public function setup()
{
$object = $this->object;
$this->addImportsElement();
// $this->addDisabledElement();
$loader = new IcingaObjectFieldLoader($object);
$loader->addFieldsToForm($this);
$this->makeVariants($this->getElement('imports'));
// $this->makeVariants($this->getElement('disabled'));
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();
$name = $el->getName();
if (substr($name, 0, 4) === 'var_') {
$this->makeVariants($el);
}
@ -41,50 +64,13 @@ class IcingaMultiEditForm extends DirectorObjectForm
$this->setButtons();
}
/**
* No default objects behaviour
*/
protected function onRequest()
{
}
public function onSuccess()
{
foreach ($this->getValues() as $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;
}
}
}
$modified = 0;
foreach ($this->objects as $object) {
if ($object->hasBeenModified()) {
$modified++;
$object->store();
}
$this->setSubmittedMultiValue($key, $value);
}
$modified = $this->storeModifiedObjects();
if ($modified === 0) {
$msg = $this->translate('No object has been modified');
} elseif ($modified === 1) {
@ -99,6 +85,54 @@ class IcingaMultiEditForm extends DirectorObjectForm
$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) {
@ -107,17 +141,46 @@ class IcingaMultiEditForm extends DirectorObjectForm
$name = $element->getName();
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 {
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);
}
foreach ($this->getDisplayGroups() as $group) {
$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;
@ -127,10 +190,6 @@ class IcingaMultiEditForm extends DirectorObjectForm
protected function makeVariants(ZfElement $element)
{
if (! $element) {
return $this;
}
$key = $element->getName();
$this->removeElement($key);
$label = $element->getLabel();
@ -190,22 +249,6 @@ class IcingaMultiEditForm extends DirectorObjectForm
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()
{
if ($this->db === null) {

View File

@ -2,6 +2,7 @@
namespace Icinga\Module\Director\Web\Controller;
use Icinga\Exception\NotFoundError;
use Icinga\Data\Filter\Filter;
use Icinga\Module\Director\Objects\IcingaObject;
use Icinga\Module\Director\Web\Table\IcingaObjectTable;
@ -12,6 +13,8 @@ abstract class ObjectsController extends ActionController
protected $isApified = true;
protected $multiEdit = array();
protected $globalTypes = array(
'ApiUser',
'Zone',
@ -196,6 +199,13 @@ abstract class ObjectsController extends ActionController
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();
@ -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')
->setObjects($objects)
->pickElementsFrom($this->loadForm($formName), $this->multiEdit)
->handleRequest();
$this->setViewScript('objects/form');

View File

@ -457,7 +457,7 @@ abstract class DirectorObjectForm extends QuickForm
{
$this->object = $object;
if ($this->db === null) {
$this->setDb($db);
$this->setDb($object->getConnection());
}
return $this;