diff options
Diffstat (limited to 'modules-available/eventlog/pages/rules.inc.php')
-rw-r--r-- | modules-available/eventlog/pages/rules.inc.php | 187 |
1 files changed, 187 insertions, 0 deletions
diff --git a/modules-available/eventlog/pages/rules.inc.php b/modules-available/eventlog/pages/rules.inc.php new file mode 100644 index 00000000..7b43cfdb --- /dev/null +++ b/modules-available/eventlog/pages/rules.inc.php @@ -0,0 +1,187 @@ +<?php + +class SubPage +{ + + const OP_LIST = ['*', '=', '!=', '<', '<=', '>', '>=', 'regex']; + + public static function doPreprocess() + { + if (Request::isPost()) { + User::assertPermission('filter.rules.edit'); + $action = Request::post('action'); + if ($action === 'save-filter') { + self::saveRule(); + } elseif ($action === 'delete-filter') { + self::deleteRule(); + } else { + Message::addError('main.invalid-action', $action); + } + Util::redirect('?do=eventlog&show=rules'); + } + } + + private static function saveRule() + { + User::assertPermission('filter.rules.edit'); + $id = Request::post('id', Request::REQUIRED, 'int'); + $type = Request::post('type', Request::REQUIRED, 'string'); + $title = Request::post('title', Request::REQUIRED, 'string'); + $message = Request::post('message', Request::REQUIRED, 'string'); + $transports = Request::post('transports', [], 'array'); + $filters = Request::post('filter', Request::REQUIRED, 'array'); + $filters = array_filter($filters, function ($item) { + return is_array($item) && !empty($item['path']) && !empty($item['op']); + }); + foreach ($filters as $index => &$item) { + $item['index'] = $index; + } + unset($item); + if (empty($filters)) { + Message::addError('no-valid-filters'); + Util::redirect('?do=eventlog&show=rules'); + } + if ($id === 0) { + $id = null; + } + $data = [ + 'id' => $id, + 'type' => $type, + 'title' => $title, + 'description' => Request::post('description', '', 'string'), + 'data' => json_encode(['list' => array_values($filters)]), + 'subject' => Request::post('subject', '', 'string'), + 'message' => $message, + ]; + if ($id === null) { + // NEW + Database::exec("INSERT INTO notification_rule (ruleid, title, description, type, datafilter, subject, message) + VALUES (:id, :title, :description, :type, :data, :subject, :message)", $data); + $id = Database::lastInsertId(); + } else { + Database::exec("UPDATE notification_rule SET type = :type, title = :title, description = :description, datafilter = :data, + subject = :subject, message = :message + WHERE ruleid = :id", $data); + } + if (empty($transports)) { + Database::exec("DELETE FROM notification_rule_x_transport WHERE ruleid = :id", ['id' => $id]); + } else { + Database::exec("DELETE FROM notification_rule_x_transport + WHERE ruleid = :id AND transportid NOT IN (:transports)", + ['id' => $id, 'transports' => $transports]); + Database::exec("INSERT IGNORE INTO notification_rule_x_transport (ruleid, transportid) + VALUES :list", ['list' => array_map(function ($i) use ($id) { return [$id, $i]; }, $transports)]); + } + Message::addSuccess("event-rule-saved", $id); + Util::redirect('?do=eventlog&show=rules'); + } + + private static function deleteRule() + { + User::assertPermission('filter.rules.edit'); + $id = Request::post('id', Request::REQUIRED, 'int'); + Database::exec("DELETE FROM notification_rule WHERE ruleid = :id", ['id' => $id]); + } + + /* + * + */ + + public static function doRender() + { + User::assertPermission('filter.rules.view'); + $id = Request::get('id', null, 'int'); + if ($id !== null) { + self::showRuleEditor($id); + } else { + // LIST + $data = []; + $data['filters'] = Database::queryAll('SELECT ruleid, type, title, datafilter, + Count(transportid) AS useCount + FROM notification_rule + LEFT JOIN notification_rule_x_transport sfxb USING (ruleid) + GROUP BY ruleid, title + ORDER BY title, ruleid'); + Permission::addGlobalTags($data['perms'], null, ['filter.rules.edit']); + Render::addTemplate('page-filters-rules', $data); + } + } + + /** + * @param int $id Rule to edit. If id is 0, a new rule will be created. + */ + private static function showRuleEditor(int $id) + { + // EDIT + User::assertPermission('filter.rules.edit'); + $filterIdx = 0; + $knownIdxList = []; + if ($id !== 0) { + $data = Database::queryFirst('SELECT ruleid, title, description, type, datafilter, subject, message + FROM notification_rule WHERE ruleid = :id', ['id' => $id]); + if ($data === false) { + Message::addError('invalid-rule-id', $id); + Util::redirect('?do=eventlog&show=rules'); + } + if (Request::get('copy', false, 'bool')) { + $data['ruleid'] = 0; + $data['title'] = ''; + } + $list = json_decode($data['datafilter'], true); + if (!is_array($list['list'])) { + $list['list'] = []; + } + foreach ($list['list'] as $item) { + if (isset($item['index'])) { + $knownIdxList[] = $item['index']; + } + } + foreach ($list['list'] as &$item) { + if (!isset($item['index'])) { + while (in_array($filterIdx, $knownIdxList)) { + $filterIdx++; + } + $item['index'] = $filterIdx++; + } + $item['operators'] = []; + foreach (self::OP_LIST as $op) { + $item['operators'][] = [ + 'name' => $op, + 'selected' => ($op === $item['op']) ? 'selected' : '', + ]; + } + } + $data['filter'] = $list['list']; + } else { + // New entry + $data = ['filter' => [], 'ruleid' => 0]; + } + // Add suggestions for type + $data['types'] = Database::queryColumnArray("SELECT DISTINCT type + FROM notification_sample + ORDER BY type"); + // + Module::isAvailable('bootstrap_multiselect'); + $data['transports'] = Database::queryAll("SELECT nb.transportid, nb.title, + IF(sfxb.ruleid IS NULL, '', 'selected') AS selected + FROM notification_backend nb + LEFT JOIN notification_rule_x_transport sfxb ON (sfxb.transportid = nb.transportid AND sfxb.ruleid = :id)", + ['id' => $id]); + if (Module::isAvailable('statistics')) { + // Filter keys to suggest for events with machineuuid in data + $data['machine_keys'] = array_keys(FilterRuleProcessor::HW_QUERIES); + } + // Add a few empty rows at the bottom + for ($i = 0; $i < 8; ++$i) { + while (in_array($filterIdx, $knownIdxList)) { + $filterIdx++; + } + $data['filter'][] = [ + 'index' => $filterIdx++, + 'operators' => array_map(function ($item) { return ['name' => $item]; }, self::OP_LIST), + ]; + } + Render::addTemplate('page-filters-edit-rule', $data); + } + +}
\ No newline at end of file |