[icinga-checkins] icinga.org: icingaweb2-module-director/feature/mass-edit-12033: MultiEditForm: first shot, provides imports

git at icinga.org git at icinga.org
Thu Oct 13 21:09:18 CEST 2016


Module: icingaweb2-module-director
Branch: feature/mass-edit-12033
Commit: 8fc746254b8051bbc0f7a4552291d75facf7d08d
URL:    https://git.icinga.org/?p=icingaweb2-module-director.git;a=commit;h=8fc746254b8051bbc0f7a4552291d75facf7d08d

Author: Thomas Gelf <thomas at gelf.net>
Date:   Thu Oct 13 19:07:41 2016 +0000

MultiEditForm: first shot, provides imports

refs #12465

---

 application/forms/IcingaMultiEditForm.php          |  194 ++++++++++++++++++++
 application/tables/IcingaHostTable.php             |    9 +
 .../Director/Web/Controller/ObjectsController.php  |   23 +++
 3 files changed, 226 insertions(+)

diff --git a/application/forms/IcingaMultiEditForm.php b/application/forms/IcingaMultiEditForm.php
new file mode 100644
index 0000000..35d8638
--- /dev/null
+++ b/application/forms/IcingaMultiEditForm.php
@@ -0,0 +1,194 @@
+<?php
+
+namespace Icinga\Module\Director\Forms;
+
+use Icinga\Module\Director\Web\Form\QuickForm;
+
+class IcingaMultiEditForm extends QuickForm
+{
+    private $objects;
+
+    private $object;
+
+    private $db;
+
+    public function setObjects($objects)
+    {
+        $this->objects = $objects;
+        return $this;
+    }
+
+    public function setup()
+    {
+        $this->addImportsElements();//->setButtons();
+    }
+
+    public function onSuccess()
+    {
+/*
+echo '<pre>';
+print_r($this->getVariants('imports'));
+print_r($this->getValues());
+echo '</pre>';
+*/
+        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<br>", $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 799d4dd..f605435 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 1941c57..edec93b 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();



More information about the icinga-checkins mailing list