From 4f3855737449bf565b47c4720d58c7e6b9f5d14c Mon Sep 17 00:00:00 2001 From: raviks789 <33730024+raviks789@users.noreply.github.com> Date: Tue, 1 Feb 2022 18:27:28 +0100 Subject: [PATCH] Prevent deletion of data lists that are in use. Deletion of data lists which are used in icinga objects (through custom variables) or in sync rules is prevented. --- library/Director/Objects/DirectorDatalist.php | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/library/Director/Objects/DirectorDatalist.php b/library/Director/Objects/DirectorDatalist.php index a4120da5..8baf4b31 100644 --- a/library/Director/Objects/DirectorDatalist.php +++ b/library/Director/Objects/DirectorDatalist.php @@ -2,6 +2,7 @@ namespace Icinga\Module\Director\Objects; +use Exception; use Icinga\Module\Director\Data\Db\DbObject; use Icinga\Module\Director\Db; use Icinga\Module\Director\DirectorObject\Automation\ExportInterface; @@ -106,6 +107,55 @@ class DirectorDatalist extends DbObject implements ExportInterface return $this; } + protected function beforeDelete() + { + if ($this->hasBeenUsed()) { + throw new Exception( + sprintf( + "Cannot delete '%s', as the datalist '%s' is currently being used.", + $this->get('list_name'), + $this->get('list_name') + ) + ); + } + } + + protected function hasBeenUsed() + { + $datalistType = 'Icinga\\Module\\Director\\DataType\\DataTypeDatalist'; + $db = $this->getDb(); + + $dataFieldsCheck = $db->select() + ->from(['df' =>'director_datafield'], ['varname']) + ->join( + ['dfs' => 'director_datafield_setting'], + 'dfs.datafield_id = df.id AND dfs.setting_name = \'datalist_id\'', + [] + ) + ->join( + ['l' => 'director_datalist'], + 'l.id = dfs.setting_value', + [] + ) + ->where('datatype = ?', $datalistType) + ->where('setting_value = ?', $this->get('id')); + + if ($db->fetchOne($dataFieldsCheck)) { + return true; + } + + $syncCheck = $db->select() + ->from(['sp' =>'sync_property'], ['source_expression']) + ->where('sp.destination_field = ?', 'list_id') + ->where('sp.source_expression = ?', $this->get('id')); + + if ($db->fetchOne($syncCheck)) { + return true; + } + + return false; + } + /** * @throws DuplicateKeyException */