BasketSnapshot: support datafield categories

fixes #2256
This commit is contained in:
Thomas Gelf 2022-02-16 23:14:38 +01:00
parent a50593c082
commit 984e931954
5 changed files with 79 additions and 3 deletions

View File

@ -22,6 +22,7 @@ next (will be 1.9.0)
* FIX: Restore now supports the set_if_format switch (#2291)
* FEATURE: it's now possible to purge objects of specific types (#2201)
* FEATURE: exporting Users, User-Templates and -Groups is now possible (#2328)
* FEATURE: Data Field Categories are now supported (#2256)
### Permissions and Restrictions
* FEATURE: allow using monitoring module permissions (#2304)

View File

@ -6,6 +6,7 @@ use Icinga\Module\Director\Core\Json;
use Icinga\Module\Director\Db;
use Icinga\Module\Director\Data\Db\DbObject;
use Icinga\Module\Director\Objects\DirectorDatafield;
use Icinga\Module\Director\Objects\DirectorDatafieldCategory;
use Icinga\Module\Director\Objects\DirectorDatalist;
use Icinga\Module\Director\Objects\DirectorJob;
use Icinga\Module\Director\Objects\IcingaCommand;
@ -30,6 +31,7 @@ use RuntimeException;
class BasketSnapshot extends DbObject
{
protected static $typeClasses = [
'DatafieldCategory' => DirectorDatafieldCategory::class,
'Datafield' => DirectorDatafield::class,
'TimePeriod' => IcingaTimePeriod::class,
'CommandTemplate' => [IcingaCommand::class, ['object_type' => 'template']],
@ -160,13 +162,20 @@ class BasketSnapshot extends DbObject
$fieldResolver = new BasketSnapshotFieldResolver($this->objects, $db);
/** @var DirectorDatafield[] $fields */
$fields = $fieldResolver->loadCurrentFields($db);
$categories = [];
if (! empty($fields)) {
$plain = [];
foreach ($fields as $id => $field) {
$plain[$id] = $field->export();
if ($category = $field->getCategory()) {
$categories[$category->get('category_name')] = $category->export();
}
}
$this->objects['Datafield'] = $plain;
}
if (! empty($categories)) {
$this->objects['DatafieldCategory'] = $categories;
}
}
protected function addObjectsChosenByBasket(Basket $basket)
@ -259,6 +268,7 @@ class BasketSnapshot extends DbObject
$db->beginTransaction();
$fieldResolver = new BasketSnapshotFieldResolver($all, $connection);
$this->restoreType($all, 'DataList', $fieldResolver, $connection, $replace);
$this->restoreType($all, 'DatafieldCategory', $fieldResolver, $connection, $replace);
$fieldResolver->storeNewFields();
foreach ($this->restoreOrder as $typeName) {
$this->restoreType($all, $typeName, $fieldResolver, $connection, $replace);

View File

@ -55,6 +55,7 @@ class BasketSnapshotFieldResolver
*/
public function storeNewFields()
{
$this->targetFields = null; // Clear Cache
foreach ($this->getTargetFields() as $id => $field) {
if ($field->hasBeenModified()) {
$field->store();
@ -171,7 +172,7 @@ class BasketSnapshotFieldResolver
protected function getObjectsByType($type)
{
if (isset($this->objects->$type)) {
return $this->objects->$type;
return (array) $this->objects->$type;
} else {
return [];
}
@ -210,6 +211,7 @@ class BasketSnapshotFieldResolver
$this->idMap = [];
$this->targetFields = [];
foreach ($this->getObjectsByType('Datafield') as $id => $object) {
unset($object->category_id); // Fix old baskets
// Hint: import() doesn't store!
$new = DirectorDatafield::import($object, $this->targetDb);
if ($new->hasBeenLoadedFromDb()) {

View File

@ -87,7 +87,7 @@ class DirectorDatafield extends DbObjectWithSettings
public function getCategoryName()
{
$category = $this->getCategory();
if ($this->category === null) {
if ($category === null) {
return null;
} else {
return $category->get('category_name');
@ -105,7 +105,13 @@ class DirectorDatafield extends DbObjectWithSettings
}
$this->category = $category;
} else {
$this->setCategory(DirectorDatafieldCategory::load($category, $this->getConnection()));
if (DirectorDatafieldCategory::exists($category, $this->getConnection())) {
$this->setCategory(DirectorDatafieldCategory::load($category, $this->getConnection()));
} else {
$this->setCategory(DirectorDatafieldCategory::create([
'category_name' => $category
], $this->getConnection()));
}
}
return $this;
@ -129,6 +135,10 @@ class DirectorDatafield extends DbObjectWithSettings
)->get('list_name');
unset($plain->settings->datalist_id);
}
if (property_exists($plain, 'category_id')) {
$plain->category = $this->getCategoryName();
unset($plain->category_id);
}
return $plain;
}
@ -193,6 +203,16 @@ class DirectorDatafield extends DbObjectWithSettings
return static::create($properties, $db);
}
protected function beforeStore()
{
if ($this->category) {
if (!$this->category->hasBeenLoadedFromDb()) {
throw new \RuntimeException('Trying to store a datafield with an unstored Category');
}
$this->set('category_id', $this->category->get('id'));
}
}
protected function setObject(IcingaObject $object)
{
$this->object = $object;

View File

@ -3,6 +3,8 @@
namespace Icinga\Module\Director\Objects;
use Icinga\Module\Director\Data\Db\DbObject;
use Icinga\Module\Director\Db;
use Icinga\Module\Director\Exception\DuplicateKeyException;
class DirectorDatafieldCategory extends DbObject
{
@ -17,4 +19,45 @@ class DirectorDatafieldCategory extends DbObject
'category_name' => null,
'description' => null,
];
/**
* @return object
*/
public function export()
{
$plain = (object) $this->getProperties();
$plain->originalId = $plain->id;
unset($plain->id);
return $plain;
}
/**
* @param $plain
* @param Db $db
* @param bool $replace
* @return static
* @throws DuplicateKeyException
* @throws \Icinga\Exception\NotFoundError
*/
public static function import($plain, Db $db, $replace = false)
{
$properties = (array) $plain;
unset($properties['originalId']);
$key = $properties['category_name'];
if ($replace && static::exists($key, $db)) {
$object = static::load($key, $db);
} elseif (static::exists($key, $db)) {
throw new DuplicateKeyException(
'Cannot import, DatafieldCategory "%s" already exists',
$key
);
} else {
$object = static::create([], $db);
}
$object->setProperties($properties);
return $object;
}
}