Datafield: on rename ask whether to also rename vars

fixes #818
This commit is contained in:
Thomas Gelf 2017-07-11 15:28:04 +02:00
parent 1e531bef1b
commit 180fc2ccfa
4 changed files with 99 additions and 12 deletions

View File

@ -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);
}
}

View File

@ -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) {

View File

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

View File

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