// SPDX-License-Identifier: GPL-3.0-or-later 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[] */ public 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): ?Filter\Rule { $remainingPath = $condition->metaData()->get('columnName', ''); if (strpos($remainingPath, '.') === false) { return null; } 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; } return null; } 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; } }