hasBeenSent()) { if ($this->shouldBeDeleted()) { $varname = $this->getSentValue('varname'); 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 ); } } } parent::onRequest(); } protected function askForVariableDeletion($varname, $cnt) { $msg = $this->translate( 'Leaving custom variables in place while removing 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('wipe_vars', array( 'label' => $this->translate('Wipe related vars'), 'description' => sprintf($msg, $this->getSentValue('varname')), 'required' => true, )); if ($wipe = $this->getSentValue('wipe_vars')) { if ($wipe === 'y') { CustomVariables::deleteAll($varname, $this->getDb()); } } else { $this->abortDeletion(); $this->addError( sprintf( $this->translate('Also wipe all "%s" custom variables from %d objects?'), $varname, $cnt ) ); $this->getElement('wipe_vars')->addError( sprintf( $this->translate( 'There are %d objects with a related property. Should I also' . ' remove the "%s" property from them?' ), $cnt, $varname ) ); } } 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( $this->translate( 'Data fields allow you to customize input controls for Icinga custom' . ' variables. Once you defined them here, you can provide them through' . ' your defined templates. This gives you a granular control over what' . ' properties your users should be allowed to configure in which way.' ) ); $this->addElement('text', 'varname', array( 'label' => $this->translate('Field name'), 'description' => $this->translate( 'This will be the name of the custom variable in the rendered Icinga configuration.' ), 'required' => true, )); $this->addElement('text', 'caption', array( 'label' => $this->translate('Caption'), 'required' => true, 'description' => $this->translate( 'The caption which should be displayed to your users when this field' . ' is shown' ) )); $this->addElement('textarea', 'description', array( 'label' => $this->translate('Description'), 'description' => $this->translate( 'An extended description for this field. Will be shown as soon as a' . ' user puts the focus on this field' ), 'rows' => '3', )); $this->addElement('select', 'category_id', [ 'label' => $this->translate('Data Field Category'), 'multiOptions' => $this->optionalEnum($this->enumCategories()), ]); $error = false; try { $types = $this->enumDataTypes(); } catch (Exception $e) { $error = $e->getMessage(); $types = $this->optionalEnum(array()); } $this->addElement('select', 'datatype', array( 'label' => $this->translate('Data type'), 'description' => $this->translate('Field type'), 'required' => true, 'multiOptions' => $types, 'class' => 'autosubmit', )); if ($error) { $this->getElement('datatype')->addError($error); } $object = $this->object(); try { if ($class = $this->getSentValue('datatype')) { if ($class && array_key_exists($class, $types)) { $this->addSettings($class); } } elseif ($class = $object->get('datatype')) { $this->addSettings($class); } // TODO: next line looks like obsolete duplicate code to me $this->addSettings(); } catch (Exception $e) { $this->getElement('datatype')->addError($e->getMessage()); } foreach ($object->getSettings() as $key => $val) { if ($el = $this->getElement($key)) { $el->setValue($val); } } $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) { $class = $this->getValue('datatype'); } if ($class !== null) { if (! class_exists($class)) { throw new ConfigurationError( 'The hooked class "%s" for this data field does no longer exist', $class ); } $class::addSettingsFormFields($this); } } protected function clearOutdatedSettings() { $names = array(); $object = $this->object(); $global = array('varname', 'description', 'caption', 'datatype'); /** @var \Zend_Form_Element $el */ foreach ($this->getElements() as $el) { if ($el->getIgnore()) { continue; } $name = $el->getName(); if (in_array($name, $global)) { continue; } $names[$name] = $name; } foreach ($object->getSettings() as $setting => $value) { if (! array_key_exists($setting, $names)) { unset($object->$setting); } } } public function onSuccess() { $this->clearOutdatedSettings(); if ($class = $this->getValue('datatype')) { if (array_key_exists($class, $this->enumDataTypes())) { $this->addHidden('format', $class::getFormat()); } } parent::onSuccess(); } protected function enumDataTypes() { $hooks = Hook::all('Director\\DataType'); $enum = [null => $this->translate('- please choose -')]; /** @var DataTypeHook $hook */ foreach ($hooks as $hook) { $enum[get_class($hook)] = $hook->getName(); } return $enum; } protected function enumCategories() { $db = $this->getDb()->getDbAdapter(); return $db->fetchPairs( $db->select()->from('director_datafield_category', ['id', 'category_name']) ); } }