diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 12:39:39 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 12:39:39 +0000 |
commit | 8ca6cc32b2c789a3149861159ad258f2cb9491e3 (patch) | |
tree | 2492de6f1528dd44eaa169a5c1555026d9cb75ec /library/Icinga/Data/Filter/FilterChain.php | |
parent | Initial commit. (diff) | |
download | icingaweb2-8ca6cc32b2c789a3149861159ad258f2cb9491e3.tar.xz icingaweb2-8ca6cc32b2c789a3149861159ad258f2cb9491e3.zip |
Adding upstream version 2.11.4.upstream/2.11.4upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | library/Icinga/Data/Filter/FilterChain.php | 286 |
1 files changed, 286 insertions, 0 deletions
diff --git a/library/Icinga/Data/Filter/FilterChain.php b/library/Icinga/Data/Filter/FilterChain.php new file mode 100644 index 0000000..0f1e071 --- /dev/null +++ b/library/Icinga/Data/Filter/FilterChain.php @@ -0,0 +1,286 @@ +<?php +/* Icinga Web 2 | (c) 2014 Icinga Development Team | GPLv2+ */ + +namespace Icinga\Data\Filter; + +use Icinga\Exception\ProgrammingError; +use Icinga\Exception\QueryException; + +/** + * FilterChain + * + * A FilterChain contains a list ... + */ +abstract class FilterChain extends Filter +{ + protected $filters = array(); + + protected $operatorName; + + protected $operatorSymbol; + + protected $allowedColumns; + + /** + * Set the filters + * + * @param array $filters + * + * @return $this + */ + public function setFilters(array $filters) + { + $this->filters = $filters; + + $this->refreshChildIds(); + + return $this; + } + + public function hasId($id) + { + foreach ($this->filters() as $filter) { + if ($filter->hasId($id)) { + return true; + } + } + return parent::hasId($id); + } + + public function getById($id) + { + foreach ($this->filters() as $filter) { + if ($filter->hasId($id)) { + return $filter->getById($id); + } + } + return parent::getById($id); + } + + public function removeId($id) + { + if ($id === $this->getId()) { + $this->filters = array(); + return $this; + } + $remove = null; + foreach ($this->filters as $key => $filter) { + if ($filter->getId() === $id) { + $remove = $key; + } elseif ($filter instanceof FilterChain) { + $filter->removeId($id); + } + } + if ($remove !== null) { + unset($this->filters[$remove]); + $this->filters = array_values($this->filters); + } + $this->refreshChildIds(); + return $this; + } + + public function replaceById($id, $filter) + { + $found = false; + foreach ($this->filters as $k => $child) { + if ($child->getId() == $id) { + $this->filters[$k] = $filter; + $found = true; + break; + } + if ($child->hasId($id)) { + $child->replaceById($id, $filter); + $found = true; + break; + } + } + if (! $found) { + throw new ProgrammingError('You tried to replace an unexistant child filter'); + } + $this->refreshChildIds(); + return $this; + } + + protected function refreshChildIds() + { + $i = 0; + $id = $this->getId(); + foreach ($this->filters as $filter) { + $i++; + $filter->setId($id . '-' . $i); + } + return $this; + } + + public function setId($id) + { + return parent::setId($id)->refreshChildIds(); + } + + public function getOperatorName() + { + return $this->operatorName; + } + + public function setOperatorName($name) + { + if ($name !== $this->operatorName) { + return Filter::chain($name, $this->filters); + } + return $this; + } + + public function getOperatorSymbol() + { + return $this->operatorSymbol; + } + + public function setAllowedFilterColumns(array $columns) + { + $this->allowedColumns = $columns; + return $this; + } + + /** + * List and return all column names referenced in this filter + * + * @param array $columns The columns listed so far + * + * @return array + */ + public function listFilteredColumns(array $columns = array()) + { + foreach ($this->filters as $filter) { + if ($filter instanceof FilterExpression) { + $column= $filter->getColumn(); + if (! in_array($column, $columns, true)) { + $columns[] = $column; + } + } else { + $columns = $filter->listFilteredColumns($columns); + } + } + + return $columns; + } + + public function toQueryString() + { + $parts = array(); + if (empty($this->filters)) { + return ''; + } + foreach ($this->filters() as $filter) { + if (! $filter->isEmpty()) { + $parts[] = $filter->toQueryString(); + } + } + + // TODO: getLevel?? + if (strpos($this->getId(), '-')) { + return '(' . implode($this->getOperatorSymbol(), $parts) . ')'; + } else { + return implode($this->getOperatorSymbol(), $parts); + } + } + + /** + * Get simple string representation + * + * Useful for debugging only + * + * @return string + */ + public function __toString() + { + if (empty($this->filters)) { + return ''; + } + $parts = array(); + foreach ($this->filters as $filter) { + if ($filter instanceof FilterChain) { + $parts[] = '(' . $filter . ')'; + } else { + $parts[] = (string) $filter; + } + } + $op = ' ' . $this->getOperatorSymbol() . ' '; + return implode($op, $parts); + } + + public function __construct($filters = array()) + { + foreach ($filters as $filter) { + $this->addFilter($filter); + } + } + + public function isExpression() + { + return false; + } + + public function isChain() + { + return true; + } + + public function isEmpty() + { + return empty($this->filters); + } + + public function addFilter(Filter $filter) + { + if (! empty($this->allowedColumns)) { + $this->validateFilterColumns($filter); + } + + $this->filters[] = $filter; + $filter->setId($this->getId() . '-' . $this->count()); + return $this; + } + + protected function validateFilterColumns(Filter $filter) + { + if ($filter->isExpression()) { + $valid = false; + foreach ($this->allowedColumns as $column) { + if (is_callable($column)) { + if (call_user_func($column, $filter->getColumn())) { + $valid = true; + break; + } + } elseif ($filter->getColumn() === $column) { + $valid = true; + break; + } + } + + if (! $valid) { + throw new QueryException('Invalid filter column provided: %s', $filter->getColumn()); + } + } else { + foreach ($filter->filters() as $subFilter) { + $this->validateFilterColumns($subFilter); + } + } + } + + public function &filters() + { + return $this->filters; + } + + public function count() + { + return count($this->filters); + } + + public function __clone() + { + foreach ($this->filters as & $filter) { + $filter = clone $filter; + } + } +} |