diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-14 13:17:31 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-14 13:17:31 +0000 |
commit | f66ab8dae2f3d0418759f81a3a64dc9517a62449 (patch) | |
tree | fbff2135e7013f196b891bbde54618eb050e4aaf /application/views/helpers | |
parent | Initial commit. (diff) | |
download | icingaweb2-module-director-f66ab8dae2f3d0418759f81a3a64dc9517a62449.tar.xz icingaweb2-module-director-f66ab8dae2f3d0418759f81a3a64dc9517a62449.zip |
Adding upstream version 1.10.2.upstream/1.10.2
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | application/views/helpers/FormDataFilter.php | 564 | ||||
-rw-r--r-- | application/views/helpers/FormIplExtensibleSet.php | 23 | ||||
-rw-r--r-- | application/views/helpers/FormSimpleNote.php | 15 | ||||
-rw-r--r-- | application/views/helpers/FormStoredPassword.php | 60 | ||||
-rw-r--r-- | application/views/helpers/RenderPlainObject.php | 14 |
5 files changed, 676 insertions, 0 deletions
diff --git a/application/views/helpers/FormDataFilter.php b/application/views/helpers/FormDataFilter.php new file mode 100644 index 0000000..d8bc508 --- /dev/null +++ b/application/views/helpers/FormDataFilter.php @@ -0,0 +1,564 @@ +<?php + +use Icinga\Data\Filter\Filter; +use Icinga\Data\Filter\FilterChain; +use Icinga\Data\Filter\FilterExpression; +use Icinga\Data\FilterColumns; +use Icinga\Module\Director\Objects\IcingaObject; +use Icinga\Module\Director\Web\Form\Element\Boolean; +use Icinga\Module\Director\Web\Form\IconHelper; + +/** + * View helper for extensible sets + * + * Avoid complaints about class names: + * @codingStandardsIgnoreStart + */ +class Zend_View_Helper_FormDataFilter extends Zend_View_Helper_FormElement +{ + private $fieldName; + + private $cachedColumnSelect; + + private $query; + + private $suggestionContext; + + /** + * Generates an 'extensible set' element. + * + * @codingStandardsIgnoreEnd + * + * @param string|array $name If a string, the element name. If an + * array, all other parameters are ignored, and the array elements + * are used in place of added parameters. + * + * @param mixed $value The element value. + * + * @param array $attribs Attributes for the element tag. + * + * @return string The element XHTML. + * @throws Zend_Form_Exception + */ + public function formDataFilter($name, $value = null, $attribs = null) + { + $info = $this->_getInfo($name, $value, $attribs); + extract($info); // id, name, value, attribs, options, listsep, disable + if (array_key_exists('columns', $attribs)) { + $this->setColumns($attribs['columns']); + unset($attribs['columns']); + } + + if (array_key_exists('suggestionContext', $attribs)) { + $this->setSuggestionContext($attribs['suggestionContext']); + unset($attribs['suggestionContext']); + } + + // TODO: check for columns in attribs, preserve & remove them from the + // array use attribs? class etc? disabled? + // override _getInfo? + $this->fieldName = $name; + + if ($value === null) { + $value = $this->emptyExpression(); + } elseif (is_string($value)) { + $value = Filter::fromQueryString($value); + } + + return $this->beginRoot() + . $this->renderFilter($value) + . $this->endRoot(); + } + + /** + * @param Filter $filter + * @return string + * @throws Zend_Form_Exception + */ + protected function renderFilter(Filter $filter) + { + if ($filter instanceof FilterChain) { + return $this->renderFilterChain($filter); + } elseif ($filter instanceof FilterExpression) { + return $this->renderFilterExpression($filter); + } else { + throw new InvalidArgumentException('Got a Filter being neither expression nor chain'); + } + } + + protected function beginRoot() + { + return '<ul class="filter-root">'; + } + + protected function endRoot() + { + return '</ul>'; + } + + /** + * @param FilterChain $filter + * @return string + * @throws Zend_Form_Exception + */ + protected function renderFilterChain(FilterChain $filter) + { + $parts = array(); + foreach ($filter->filters() as $f) { + $parts[] = $this->renderFilter($f); + } + + return $this->beginChain($filter) + . implode('', $parts) + . $this->endChain($filter); + } + + protected function beginChain(FilterChain $filter) + { + $list = $filter->isEmpty() ? '' : '<ul>' . "\n"; + + return '<li class="filter-chain"><span class="handle"> </span>' + . $this->selectOperator($filter) + . $this->removeLink($filter) + . $this->addLink($filter) + . ($filter->count() === 1 ? $this->stripLink($filter) : '') + . $list; + } + + protected function endChain(FilterChain $filter) + { + $list = $filter->isEmpty() ? '' : "</ul>\n"; + return $list . "</li>\n"; + } + + protected function beginExpression(FilterExpression $filter) + { + return '<div class="filter-expression">' . "\n"; + } + + protected function endExpression(FilterExpression $filter) + { + return "</div>\n"; + } + + protected function beginElement(FilterExpression $filter) + { + return '<div class="expression-wrapper">' . "\n"; + } + + protected function endElement(FilterExpression $filter) + { + return "</div>\n"; + } + + /** + * @param FilterExpression $filter + * @return string + * @throws Zend_Form_Exception + */ + protected function filterExpressionHtml(FilterExpression $filter) + { + return $this->selectColumn($filter) + . $this->selectSign($filter) + . $this->beginElement($filter) + . $this->element($filter) + . $this->endElement($filter) + . $this->removeLink($filter) + . $this->expandLink($filter); + } + + /** + * @param FilterExpression $filter + * @return string + * @throws Zend_Form_Exception + */ + protected function renderFilterExpression(FilterExpression $filter) + { + return $this->beginExpression($filter) + . $this->filterExpressionHtml($filter) + . $this->endExpression($filter); + } + + /** + * @param FilterExpression|null $filter + * @return Boolean|string + * @throws Zend_Form_Exception + */ + protected function element(FilterExpression $filter = null) + { + if ($filter) { + // TODO: Make this configurable + $type = 'host'; + $prefixLen = strlen($type) + 1; + $filter = clone($filter); + $col = $filter->getColumn(); + + if ($this->columnIsJson($filter)) { + $col = $filter->getExpression(); + $filter->setExpression(json_decode($filter->getColumn())); + } else { + $filter->setExpression(json_decode($filter->getExpression())); + } + + if (($filter->getExpression() === true) || ($filter->getExpression() === false)) { + return ''; + } + $dummy = IcingaObject::createByType($type); + if ($dummy->hasProperty($col)) { + if ($dummy->propertyIsBoolean($col)) { + return $this->boolean($filter); + } + } + + if (substr($col, -7) === '.groups' && $dummy->supportsGroups()) { + $type = substr($col, 0, -7); + + return $this->selectGroup($type, $filter); + } elseif (substr($col, $prefixLen, 5) === 'vars.') { + $var = substr($col, $prefixLen + 5); + + return $this->text($filter, "DataListValues!${var}"); + } + } + + return $this->text($filter); + } + + /** + * @param $type + * @param FilterExpression $filter + * @return Zend_Form_Element + */ + protected function selectGroup($type, FilterExpression $filter) + { + return $this->view->formText( + $this->elementId('value', $filter), + $filter->getExpression(), + [ + 'class' => 'director-suggest', + 'data-suggestion-context' => "${type}groupnames", + ] + ); + } + + /** + * @param FilterExpression|null $filter + * @return Boolean + * @throws Zend_Form_Exception + */ + protected function boolean(FilterExpression $filter = null) + { + $value = $filter === null ? '' : $filter->getExpression(); + + $el = new Boolean( + $this->elementId('value', $filter), + array( + 'value' => $value, + 'decorators' => array('ViewHelper'), + ) + ); + + return $el; + } + + protected function columnIsJson(FilterExpression $filter) + { + $col = $filter->getColumn(); + return strlen($col) && $col[0] === '"'; + } + + /** + * @param FilterExpression|null $filter + * @param string $suggestionContext + * + * @return mixed + */ + protected function text(FilterExpression $filter = null, $suggestionContext = null) + { + $attr = null; + if ($suggestionContext !== null) { + $attr = [ + 'class' => 'director-suggest', + 'data-suggestion-context' => $suggestionContext, + ]; + } + + $value = $filter === null ? '' : $filter->getExpression(); + if (is_array($value)) { + return $this->view->formIplExtensibleSet( + $this->elementId('value', $filter), + $value, + $attr + ); + } + + return $this->view->formText( + $this->elementId('value', $filter), + $value, + $attr + ); + } + + /** + * @return \Icinga\Data\Filter\FilterExpression + */ + protected function emptyExpression() + { + return Filter::expression('', '=', ''); + } + + protected function arrayForSelect($array, $flip = false) + { + $res = array(); + foreach ($array as $k => $v) { + if (is_int($k)) { + $res[$v] = ucwords(str_replace('_', ' ', $v)); + } elseif ($flip) { + $res[$v] = $k; + } else { + $res[$k] = $v; + } + } + + // sort($res); + return $res; + } + + protected function elementId($field, Filter $filter = null) + { + $prefix = $this->fieldName . '[id_'; + $suffix = '][' . $field . ']'; + + return $prefix . $filter->getId() . $suffix; + } + + /** + * @param FilterChain|null $filter + * @return mixed + */ + protected function selectOperator(FilterChain $filter = null) + { + $ops = [ + 'AND' => 'AND', + 'OR' => 'OR', + 'NOT' => 'NOT' + ]; + + return $this->select( + $this->elementId('operator', $filter), + $ops, + $filter === null ? null : $filter->getOperatorName(), + ['class' => 'operator autosubmit'] + ); + } + + protected function selectSign(FilterExpression $filter = null) + { + $signs = [ + '=' => '=', + '!=' => '!=', + '>' => '>', + '<' => '<', + '>=' => '>=', + '<=' => '<=', + 'in' => 'in', + 'contains' => 'contains', + 'true' => 'is true (or set)', + 'false' => 'is false (or not set)', + ]; + + if ($filter === null) { + $sign = null; + } else { + if ($this->columnIsJson($filter)) { + $sign = 'contains'; + } else { + $expression = json_decode($filter->getExpression()); + if ($expression === true) { + $sign = 'true'; + } elseif ($expression === false) { + $sign = 'false'; + } elseif (is_array($expression)) { + $sign = 'in'; + } else { + $sign = $filter->getSign(); + } + } + } + + $class = 'sign autosubmit'; + if (strlen($sign) > 3) { + $class .= ' wide'; + } + + return $this->select( + $this->elementId('sign', $filter), + $signs, + $sign, + array('class' => $class) + ); + } + + public function setColumns(array $columns = null) + { + $this->cachedColumnSelect = $columns ? $this->arrayForSelect($columns) : null; + return $this; + } + + protected function getSuggestionContext() + { + return $this->suggestionContext; + } + + protected function setSuggestionContext($context) + { + $this->suggestionContext = $context; + } + + protected function selectColumn(FilterExpression $filter = null) + { + $active = $filter === null ? null : $filter->getColumn(); + if ($filter && $this->columnIsJson($filter)) { + $active = $filter->getExpression(); + } + + if ($context = $this->getSuggestionContext()) { + return $this->view->formText( + $this->elementId('column', $filter), + $active, + [ + 'class' => 'column autosubmit director-suggest', + 'data-suggestion-context' => $context, + ] + ); + } + if ($this->hasColumnList()) { + $cols = $this->getColumnList(); + if ($active && !isset($cols[$active])) { + $cols[$active] = str_replace( + '_', + ' ', + ucfirst(ltrim($active, '_')) + ); // ?? + } + + $cols = $this->optionalEnum($cols); + + return $this->select( + $this->elementId('column', $filter), + $cols, + $active, + ['class' => 'column autosubmit'] + ); + } else { + return $this->view->formText( + $this->elementId('column', $filter), + $active, + ['class' => 'column autosubmit'] + ); + } + } + + protected function optionalEnum($enum) + { + return array_merge( + array(null => $this->view->translate('- please choose -')), + $enum + ); + } + + protected function hasColumnList() + { + return $this->cachedColumnSelect !== null || $this->query !== null; + } + + protected function getColumnList() + { + if ($this->cachedColumnSelect === null) { + $this->fetchColumnList(); + } + + return $this->cachedColumnSelect; + } + + protected function fetchColumnList() + { + if ($this->query instanceof FilterColumns) { + $this->cachedColumnSelect = $this->arrayForSelect( + $this->query->getFilterColumns(), + true + ); + asort($this->cachedColumnSelect); + } elseif ($this->cachedColumnSelect === null) { + throw new RuntimeException('No columns set nor does the query provide any'); + } + } + + protected function select($name, $list, $selected, $attributes = null) + { + return $this->view->formSelect($name, $selected, $attributes, $list); + } + + protected function removeLink(Filter $filter) + { + return $this->filterActionButton( + $filter, + 'cancel', + t('Remove this part of your filter') + ); + } + + protected function addLink(Filter $filter) + { + return $this->filterActionButton( + $filter, + 'plus', + t('Add another filter') + ); + } + + protected function expandLink(Filter $filter) + { + return $this->filterActionButton( + $filter, + 'angle-double-right', + t('Wrap this expression into an operator') + ); + } + + protected function stripLink(Filter $filter) + { + return $this->filterActionButton( + $filter, + 'minus', + t('Strip this operator, preserve child nodes') + ); + } + + protected function filterActionButton(Filter $filter, $action, $title) + { + return $this->iconButton( + $this->getActionButtonName($filter), + $action, + $title + ); + } + + protected function getActionButtonName(Filter $filter) + { + return sprintf( + '%s[id_%s][action]', + $this->fieldName, + $filter->getId() + ); + } + + protected function iconButton($name, $icon, $title) + { + return $this->view->formSubmit( + $name, + IconHelper::instance()->iconCharacter($icon), + array('class' => 'icon-button', 'title' => $title) + ); + } +} diff --git a/application/views/helpers/FormIplExtensibleSet.php b/application/views/helpers/FormIplExtensibleSet.php new file mode 100644 index 0000000..c782016 --- /dev/null +++ b/application/views/helpers/FormIplExtensibleSet.php @@ -0,0 +1,23 @@ +<?php + +use Icinga\Module\Director\Web\Form\IplElement\ExtensibleSetElement; + +/** + * View helper for extensible sets + * + * @codingStandardsIgnoreStart + */ +class Zend_View_Helper_FormIplExtensibleSet extends Zend_View_Helper_FormElement +{ + private $currentId; + + /** + * @codingStandardsIgnoreEnd + + * @return string The element HTML. + */ + public function formIplExtensibleSet($name, $value = null, $attribs = null) + { + return ExtensibleSetElement::fromZfDingens($name, $value, $attribs); + } +} diff --git a/application/views/helpers/FormSimpleNote.php b/application/views/helpers/FormSimpleNote.php new file mode 100644 index 0000000..d8315f4 --- /dev/null +++ b/application/views/helpers/FormSimpleNote.php @@ -0,0 +1,15 @@ +<?php + +// Avoid complaints about missing namespace and invalid class name +// @codingStandardsIgnoreStart +class Zend_View_Helper_FormSimpleNote extends Zend_View_Helper_FormElement +{ + // @codingStandardsIgnoreEnd + + public function formSimpleNote($name, $value = null) + { + $info = $this->_getInfo($name, $value); + extract($info); // name, value, attribs, options, listsep, disable + return $value; + } +} diff --git a/application/views/helpers/FormStoredPassword.php b/application/views/helpers/FormStoredPassword.php new file mode 100644 index 0000000..e25a1dc --- /dev/null +++ b/application/views/helpers/FormStoredPassword.php @@ -0,0 +1,60 @@ +<?php + +use ipl\Html\Html; +use ipl\Html\HtmlDocument; + +/** + * Please see StoredPassword (the Form Element) for related documentation + * + * We're rendering the following fields: + * + * - ${name}[_value]: + * - ${name}[_sent]: + * + * Avoid complaints about class names: + * @codingStandardsIgnoreStart + */ +class Zend_View_Helper_FormStoredPassword extends Zend_View_Helper_FormElement +{ + public function formStoredPassword($name, $value = null, $attribs = null) + { + // @codingStandardsIgnoreEnd + $info = $this->_getInfo($name, $value, $attribs); + \extract($info); // name, value, attribs, options, listsep, disable + $sentValue = $this->stripAttribute($attribs, 'sentValue'); + + $res = new HtmlDocument(); + $el = Html::tag('input', [ + 'type' => 'password', + 'name' => "${name}[_value]", + 'id' => $id, + ]); + $res->add($el); + + $res->add(Html::tag('input', [ + 'type' => 'hidden', + 'name' => "${name}[_sent]", + 'value' => 'y' + ])); + + if ($sentValue !== null && \strlen($sentValue)) { + $el->getAttributes()->set('value', $sentValue); + } elseif ($value !== null && \strlen($value) > 0) { + $el->getAttributes()->set('value', '__UNCHANGED_VALUE__'); + } + + return $res; + } + + protected function stripAttribute(&$attribs, $name, $default = null) + { + if (\array_key_exists($name, $attribs)) { + if (\strlen($attribs[$name])) { + return $attribs[$name]; + } + unset($attribs[$name]); + } + + return $default; + } +} diff --git a/application/views/helpers/RenderPlainObject.php b/application/views/helpers/RenderPlainObject.php new file mode 100644 index 0000000..8486611 --- /dev/null +++ b/application/views/helpers/RenderPlainObject.php @@ -0,0 +1,14 @@ +<?php +// Avoid complaints about missing namespace and invalid class name +// @codingStandardsIgnoreStart + +use Icinga\Module\Director\PlainObjectRenderer; + +class Zend_View_Helper_RenderPlainObject extends Zend_View_Helper_Abstract +// @codingStandardsIgnoreEnd +{ + public function renderPlainObject($object) + { + return PlainObjectRenderer::render($object); + } +} |