From 69237b8ae9609b4b0a778210d46465975866cfee Mon Sep 17 00:00:00 2001 From: Thomas Gelf Date: Thu, 13 Oct 2016 19:07:41 +0000 Subject: [PATCH] MultiEditForm: first shot, provides imports refs #12465 --- application/forms/IcingaMultiEditForm.php | 194 ++++++++++++++++++ application/tables/IcingaHostTable.php | 9 + .../Web/Controller/ObjectsController.php | 23 +++ 3 files changed, 226 insertions(+) create mode 100644 application/forms/IcingaMultiEditForm.php diff --git a/application/forms/IcingaMultiEditForm.php b/application/forms/IcingaMultiEditForm.php new file mode 100644 index 00000000..35d8638e --- /dev/null +++ b/application/forms/IcingaMultiEditForm.php @@ -0,0 +1,194 @@ +objects = $objects; + return $this; + } + + public function setup() + { + $this->addImportsElements();//->setButtons(); + } + + public function onSuccess() + { +/* +echo '
';
+print_r($this->getVariants('imports'));
+print_r($this->getValues());
+echo '
'; +*/ + foreach ($this->getValues() as $key => $value) { + $parts = preg_split('/_/', $key); + $objectsSum = array_pop($parts); + $valueSum = array_pop($parts); + $property = implode('_', $parts); +//printf("Got %s: %s -> %s
", $property, $valueSum, $objectsSum); + + $found = false; + foreach ($this->getVariants($property) as $json => $objects) { + if ($valueSum !== sha1($json)) { + continue; + } + + if ($objectsSum !== sha1(json_encode($objects))) { + continue; + } + + $found = true; + + foreach ($this->getObjects($objects) as $object) { + $object->$property = $value; + } + } + } + + $modified = 0; + foreach ($this->objects as $object) { + if ($object->hasBeenModified()) { + $modified++; + $object->store(); + } + } + + if ($modified === 0) { + $this->setSuccessMessage($this->translate('No object has been modified')); + } elseif ($modified === 1) { + $this->setSuccessMessage($this->translate('One object has been modified')); + } else { + $this->setSuccessMessage( + sprintf( + $this->translate('%d objects have been modified'), + $modified + ) + ); + } + + parent::onSuccess(); + } + + protected function getVariants($key) + { + $variants = array(); + 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 addImportsElements() + { + $enum = $this->enumTemplates(); + if (empty($enum)) { + return $this; + } + + foreach ($this->getVariants('imports') as $json => $objects) { + $value = json_decode($json); + $checksum = sha1($json) . '_' . sha1(json_encode($objects)); + $this->addElement('extensibleSet', 'imports_' . $checksum, array( + 'label' => $this->translate('Imports') . $this->labelCount($objects), + 'description' => $this->translate( + 'Importable templates, add as many as you want. Please note that order' + . ' matters when importing properties from multiple templates: last one' + . ' wins' + ) . '. ' . $this->descriptionForObjects($objects), + 'required' => !$this->object()->isTemplate(), + 'multiOptions' => $this->optionallyAddFromEnum($enum), + 'value' => $value, + 'sorted' => true, + 'class' => 'autosubmit' + )); + } + + return $this; + } + + public function optionallyAddFromEnum($enum) + { + return array( + null => $this->translate('- click to add more -') + ) + $enum; + } + + 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) { + $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; + } + + protected function object() + { + if ($this->object === null) { + $this->object = current($this->objects); + } + + return $this->object; + } +} diff --git a/application/tables/IcingaHostTable.php b/application/tables/IcingaHostTable.php index 799d4ddf..f6054358 100644 --- a/application/tables/IcingaHostTable.php +++ b/application/tables/IcingaHostTable.php @@ -34,6 +34,15 @@ class IcingaHostTable extends IcingaObjectTable 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() { $view = $this->view(); diff --git a/library/Director/Web/Controller/ObjectsController.php b/library/Director/Web/Controller/ObjectsController.php index 1941c576..edec93be 100644 --- a/library/Director/Web/Controller/ObjectsController.php +++ b/library/Director/Web/Controller/ObjectsController.php @@ -194,6 +194,29 @@ abstract class ObjectsController extends ActionController $this->setViewScript('objects/table'); } + public function editAction() + { + $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) + ->handleRequest(); + + $this->setViewScript('objects/form'); + } + public function templatesAction() { $this->indexAction();