summaryrefslogtreecommitdiffstats
path: root/library/Icingadb/Model/Behavior/ReRoute.php
diff options
context:
space:
mode:
Diffstat (limited to 'library/Icingadb/Model/Behavior/ReRoute.php')
-rw-r--r--library/Icingadb/Model/Behavior/ReRoute.php83
1 files changed, 83 insertions, 0 deletions
diff --git a/library/Icingadb/Model/Behavior/ReRoute.php b/library/Icingadb/Model/Behavior/ReRoute.php
new file mode 100644
index 0000000..d054f00
--- /dev/null
+++ b/library/Icingadb/Model/Behavior/ReRoute.php
@@ -0,0 +1,83 @@
+<?php
+
+/* Icinga DB Web | (c) 2020 Icinga GmbH | GPLv2 */
+
+namespace Icinga\Module\Icingadb\Model\Behavior;
+
+use ipl\Orm\Contract\RewriteFilterBehavior;
+use ipl\Orm\Contract\RewritePathBehavior;
+use ipl\Stdlib\Filter;
+
+class ReRoute implements RewriteFilterBehavior, RewritePathBehavior
+{
+ protected $routes;
+
+ /**
+ * Tables with mixed object type entries for which servicegroup filters need to be resolved in multiple steps
+ *
+ * @var string[]
+ */
+ const MIXED_TYPE_RELATIONS = ['downtime', 'comment', 'history', 'notification_history'];
+
+ public function __construct(array $routes)
+ {
+ $this->routes = $routes;
+ }
+
+ public function getRoutes(): array
+ {
+ return $this->routes;
+ }
+
+ public function rewriteCondition(Filter\Condition $condition, $relation = null)
+ {
+ $remainingPath = $condition->metaData()->get('columnName', '');
+ if (strpos($remainingPath, '.') === false) {
+ return;
+ }
+
+ if (($path = $this->rewritePath($remainingPath, $relation)) !== null) {
+ $class = get_class($condition);
+ $filter = new $class($relation . $path, $condition->getValue());
+ if ($condition->metaData()->has('forceOptimization')) {
+ $filter->metaData()->set(
+ 'forceOptimization',
+ $condition->metaData()->get('forceOptimization')
+ );
+ }
+
+ if (
+ in_array(substr($relation, 0, -1), self::MIXED_TYPE_RELATIONS)
+ && substr($remainingPath, 0, 13) === 'servicegroup.'
+ ) {
+ $applyAll = Filter::all();
+ $applyAll->add(Filter::equal($relation . 'object_type', 'host'));
+
+ $orgFilter = clone $filter;
+ $orgFilter->setColumn($relation . 'host.' . $path);
+
+ $applyAll->add($orgFilter);
+
+ $filter = Filter::any($filter, $applyAll);
+ }
+
+ return $filter;
+ }
+ }
+
+ public function rewritePath(string $path, ?string $relation = null): ?string
+ {
+ $dot = strpos($path, '.');
+ if ($dot !== false) {
+ $routeName = substr($path, 0, $dot);
+ } else {
+ $routeName = $path;
+ }
+
+ if (isset($this->routes[$routeName])) {
+ return $this->routes[$routeName] . ($dot !== false ? substr($path, $dot) : '');
+ }
+
+ return null;
+ }
+}