diff --git a/application/controllers/DatafieldController.php b/application/controllers/DatafieldController.php index d0c8c69c..dade3d2b 100644 --- a/application/controllers/DatafieldController.php +++ b/application/controllers/DatafieldController.php @@ -2,6 +2,7 @@ namespace Icinga\Module\Director\Controllers; +use Icinga\Module\Director\Forms\DirectorDatafieldForm; use Icinga\Module\Director\Web\Controller\ActionController; class DatafieldController extends ActionController @@ -24,23 +25,23 @@ class DatafieldController extends ActionController $edit = true; } - $form = $this->view->form = $this->loadForm('directorDatafield') + $form = DirectorDatafieldForm::load() ->setSuccessUrl('director/data/fields') ->setDb($this->db()); if ($edit) { $form->loadObject($id); - $this->view->title = sprintf( + $this->addTitle( $this->translate('Modify %s'), $form->getObject()->varname ); - $this->singleTab($this->translate('Edit a field')); + $this->addSingleTab($this->translate('Edit a field')); } else { - $this->view->title = $this->translate('Add a new Data Field'); - $this->singleTab($this->translate('New field')); + $this->addTitle($this->translate('Add a new Data Field')); + $this->addSingleTab($this->translate('New field')); } $form->handleRequest(); - $this->render('object/form', null, true); + $this->content()->add($form); } } diff --git a/application/forms/DirectorDatafieldForm.php b/application/forms/DirectorDatafieldForm.php index ba4446be..d0ddb2f8 100644 --- a/application/forms/DirectorDatafieldForm.php +++ b/application/forms/DirectorDatafieldForm.php @@ -21,6 +21,15 @@ class DirectorDatafieldForm extends DirectorObjectForm if ($cnt = CustomVariables::countAll($varname, $this->getDb())) { $this->askForVariableDeletion($varname, $cnt); } + } elseif ($this->shouldBeRenamed()) { + $varname = $this->object()->getOriginalProperty('varname'); + if ($cnt = CustomVariables::countAll($varname, $this->getDb())) { + $this->askForVariableRename( + $varname, + $this->getSentValue('varname'), + $cnt + ); + } } } @@ -70,6 +79,51 @@ class DirectorDatafieldForm extends DirectorObjectForm } } + protected function askForVariableRename($oldname, $newname, $cnt) + { + $msg = $this->translate( + 'Leaving custom variables in place while renaming the related field is' + . ' perfectly legal and might be a desired operation. This way you can' + . ' no longer modify related custom variables in the Director GUI, but' + . ' the variables themselves will stay there and continue to be deployed.' + . ' When you re-add a field for the same variable later on, everything' + . ' will continue to work as before' + ); + + $this->addBoolean('rename_vars', array( + 'label' => $this->translate('Rename related vars'), + 'description' => sprintf($msg, $this->getSentValue('varname')), + 'required' => true, + )); + + if ($wipe = $this->getSentValue('rename_vars')) { + if ($wipe === 'y') { + CustomVariables::renameAll($oldname, $newname, $this->getDb()); + } + } else { + $this->abortDeletion(); + $this->addError( + sprintf( + $this->translate('Also rename all "%s" custom variables to "%s" on %d objects?'), + $oldname, + $newname, + $cnt + ) + ); + $this->getElement('rename_vars')->addError( + sprintf( + $this->translate( + 'There are %d objects with a related property. Should I also' + . ' rename the "%s" property to "%s" on them?' + ), + $cnt, + $oldname, + $newname + ) + ); + } + } + public function setup() { $this->addHtmlHint( @@ -128,11 +182,12 @@ class DirectorDatafieldForm extends DirectorObjectForm } try { + $object = $this->object(); if ($class = $this->getSentValue('datatype')) { if ($class && array_key_exists($class, $types)) { $this->addSettings($class); } - } elseif ($class = $this->object()->get('datatype')) { + } elseif ($class = $object->get('datatype')) { $this->addSettings($class); } @@ -142,7 +197,7 @@ class DirectorDatafieldForm extends DirectorObjectForm $this->getElement('datatype')->addError($e->getMessage()); } - foreach ($this->object()->getSettings() as $key => $val) { + foreach ($object->getSettings() as $key => $val) { if ($el = $this->getElement($key)) { $el->setValue($val); } @@ -151,6 +206,13 @@ class DirectorDatafieldForm extends DirectorObjectForm $this->setButtons(); } + public function shouldBeRenamed() + { + $object = $this->object(); + return $object->hasBeenLoadedFromDb() + && $object->getOriginalProperty('varname') !== $this->getSentValue('varname'); + } + protected function addSettings($class = null) { if ($class === null) { diff --git a/library/Director/CustomVariable/CustomVariables.php b/library/Director/CustomVariable/CustomVariables.php index 4275c50b..6d74f1a6 100644 --- a/library/Director/CustomVariable/CustomVariables.php +++ b/library/Director/CustomVariable/CustomVariables.php @@ -61,6 +61,15 @@ class CustomVariables implements Iterator, Countable, IcingaConfigRenderer } } + public static function renameAll($oldname, $newname, Db $connection) + { + $db = $connection->getDbAdapter(); + $where = $db->quoteInto('varname = ?', $oldname); + foreach (static::$allTables as $table) { + $db->update($table, ['varname' => $newname], $where); + } + } + public function count() { $count = 0; diff --git a/library/Director/Data/Db/DbObject.php b/library/Director/Data/Db/DbObject.php index f02cd538..e4e653c6 100644 --- a/library/Director/Data/Db/DbObject.php +++ b/library/Director/Data/Db/DbObject.php @@ -244,18 +244,23 @@ abstract class DbObject return $this->$func(); } - if (! array_key_exists($property, $this->properties)) { - throw new IE('Trying to get invalid property "%s"', $property); - } + $this->assertPropertyExists($property); return $this->properties[$property]; } public function getProperty($key) + { + $this->assertPropertyExists($key); + return $this->properties[$key]; + } + + protected function assertPropertyExists($key) { if (! array_key_exists($key, $this->properties)) { throw new IE('Trying to get invalid property "%s"', $key); } - return $this->properties[$key]; + + return $this; } public function hasProperty($key) @@ -650,6 +655,16 @@ abstract class DbObject return $this->loadedProperties; } + public function getOriginalProperty($key) + { + $this->assertPropertyExists($key); + if ($this->hasBeenLoadedFromDb()) { + return $this->loadedProperties[$key]; + } + + return null; + } + public function hasBeenLoadedFromDb() { return $this->loadedFromDb;