ipl: add a clone and a conservative loader

This commit is contained in:
Thomas Gelf 2017-06-22 02:03:54 +02:00
parent 7199af7504
commit e883ed70b3
46 changed files with 4111 additions and 0 deletions

View File

@ -0,0 +1,22 @@
<?php
namespace ipl\Compat;
use Icinga\Util\Translator as WebTranslator;
use ipl\Translation\TranslatorInterface;
class Translator implements TranslatorInterface
{
/** @var string */
private $domain;
public function __construct($domain)
{
$this->domain = $domain;
}
public function translate($string)
{
return WebTranslator::translate($string, $this->domain);
}
}

64
library/vendor/ipl/Data/Paginatable.php vendored Normal file
View File

@ -0,0 +1,64 @@
<?php
namespace ipl\Data;
use Countable;
interface Paginatable extends Countable
{
/**
* Set a limit count and offset
*
* @param int $count Number of rows to return
* @param int $offset Skip that many rows
*
* @return self
*/
public function limit($count = null, $offset = null);
/**
* Whether a limit is set
*
* @return bool
*/
public function hasLimit();
/**
* Get the limit if any
*
* @return int|null
*/
public function getLimit();
/**
* Set limit
*
* @param int $count Number of rows to return
*
* @return int|null
*/
public function setLimit($limit);
/**
* Whether an offset is set
*
* @return bool
*/
public function hasOffset();
/**
* Get the offset if any
*
* @return int|null
*/
public function getOffset();
/**
* Set offset
*
* @param int $offset Skip that many rows
*
* @return int|null
*/
public function setOffset($offset);
}

View File

@ -0,0 +1,86 @@
<?php
namespace ipl\Db\Zf1;
use Zend_Db_Select as ZfSelect;
class CountQuery
{
/** @var ZfSelect */
private $query;
private $maxRows;
/**
* ZfCountQuery constructor.
* @param ZfSelect $query
*/
public function __construct(ZfSelect $query)
{
$this->query = $query;
}
public function setMaxRows($max)
{
$this->maxRows = $max;
return $this;
}
public function getQuery()
{
if ($this->needsSubQuery()) {
return $this->buildSubQuery();
} else {
return $this->buildSimpleQuery();
}
}
protected function hasOneOf($parts)
{
foreach ($parts as $part) {
if ($this->hasPart($part)) {
return true;
}
}
return false;
}
protected function hasPart($part)
{
$values = $this->query->getPart($part);
return ! empty($values);
}
protected function needsSubQuery()
{
return null !== $this->maxRows || $this->hasOneOf([
ZfSelect::GROUP,
ZfSelect::UNION
]);
}
protected function buildSubQuery()
{
$sub = clone($this->query);
$sub->limit(null, null);
$query = new ZfSelect($this->query->getAdapter());
$query->from($sub, ['cnt' => 'COUNT(*)']);
if (null !== $this->maxRows) {
$sub->limit($this->maxRows + 1);
}
return $query;
}
protected function buildSimpleQuery()
{
$query = clone($this->query);
$query->reset(ZfSelect::COLUMNS);
$query->reset(ZfSelect::ORDER);
$query->reset(ZfSelect::LIMIT_COUNT);
$query->reset(ZfSelect::LIMIT_OFFSET);
$query->columns(['cnt' => 'COUNT(*)']);
return $query;
}
}

View File

@ -0,0 +1,239 @@
<?php
namespace ipl\Db\Zf1;
use Icinga\Data\Filter\Filter;
use Icinga\Data\Filter\FilterAnd;
use Icinga\Data\Filter\FilterChain;
use Icinga\Data\Filter\FilterExpression;
use Icinga\Data\Filter\FilterNot;
use Icinga\Data\Filter\FilterOr;
use Icinga\Exception\ProgrammingError;
use Icinga\Exception\QueryException;
use Zend_Db_Adapter_Abstract as DbAdapter;
use Zend_Db_Expr as DbExpr;
use Zend_Db_Select as DbSelect;
class FilterRenderer
{
private $db;
/** @var Filter */
private $filter;
/**
* FilterRenderer constructor.
* @param Filter $filter
* @param DbAdapter $db
*/
public function __construct(Filter $filter, DbAdapter $db)
{
$this->filter = $filter;
$this->db = $db;
}
/**
* @return DbExpr
*/
public function toDbExpression()
{
return new DbExpr($this->render());
}
public static function applyToQuery(Filter $filter, DbSelect $query)
{
$renderer = new static($filter, $query->getAdapter());
$query->where($renderer->toDbExpression());
return $query;
}
/**
* @return string
*/
public function render()
{
return $this->renderFilter($this->filter);
}
protected function renderFilterChain(FilterChain $filter, $level = 0)
{
$prefix = '';
if ($filter instanceof FilterAnd) {
$op = ' AND ';
} elseif ($filter instanceof FilterOr) {
$op = ' OR ';
} elseif ($filter instanceof FilterNot) {
$op = ' AND ';
$prefix = 'NOT ';
} else {
throw new ProgrammingError(
'Cannot render a %s filter chain for Zf Db',
get_class($filter)
);
}
$parts = array();
if (! $filter->isEmpty()) {
foreach ($filter->filters() as $f) {
$part = $this->renderFilter($f, $level + 1);
if ($part !== '') {
$parts[] = $part;
}
}
if (! empty($parts)) {
if ($level > 0) {
return "$prefix (" . implode($op, $parts) . ')';
} else {
return $prefix . implode($op, $parts);
}
}
}
}
protected function renderFilterExpression(FilterExpression $filter)
{
$col = $filter->getColumn();
$sign = $filter->getSign();
$expression = $filter->getExpression();
if (is_array($expression)) {
return $this->renderArrayExpression($col, $sign, $expression);
}
if ($sign === '=') {
if (strpos($expression, '*') === false) {
return $this->renderAny($col, $sign, $expression);
} else {
return $this->renderLike($col, $expression);
}
}
if ($sign === '!=') {
if (strpos($expression, '*') === false) {
return $this->renderAny($col, $sign, $expression);
} else {
return $this->renderNotLike($col, $expression);
}
}
return $this->renderAny($col, $sign, $expression);
}
protected function renderLike($col, $expression)
{
if ($expression === '*') {
return new DbExpr('TRUE');
}
return $col . ' LIKE ' . $this->escape($this->escapeWildcards($expression));
}
protected function renderNotLike($col, $expression)
{
if ($expression === '*') {
return new DbExpr('FALSE');
}
return sprintf(
'(%1$s NOT LIKE %2$s OR %1$s IS NULL)',
$col,
$this->escape($this->escapeWildcards($expression))
);
}
protected function renderNotEqual($col, $expression)
{
return sprintf('(%1$s != %2$s OR %1$s IS NULL)', $col, $this->escape($expression));
}
protected function renderAny($col, $sign, $expression)
{
return sprintf('%s %s %s', $col, $sign, $this->escape($expression));
}
protected function renderArrayExpression($col, $sign, $expression)
{
if ($sign === '=') {
return $col . ' IN (' . $this->escape($expression) . ')';
} elseif ($sign === '!=') {
return sprintf(
'(%1$s NOT IN (%2$s) OR %1$s IS NULL)',
$col,
$this->escape($expression)
);
}
throw new ProgrammingError(
'Array expressions can only be rendered for = and !=, got %s',
$sign
);
}
/**
* @param Filter $filter
* @param int $level
* @return string|DbExpr
*/
protected function renderFilter(Filter $filter, $level = 0)
{
if ($filter instanceof FilterChain) {
return $this->renderFilterChain($filter, $level);
} else {
return $this->renderFilterExpression($filter);
}
}
protected function escape($value)
{
// bindParam? bindValue?
if (is_array($value)) {
$ret = array();
foreach ($value as $val) {
$ret[] = $this->escape($val);
}
return implode(', ', $ret);
} else {
return $this->db->quote($value);
}
}
protected function escapeWildcards($value)
{
return preg_replace('/\*/', '%', $value);
}
public function whereToSql($col, $sign, $expression)
{
if (is_array($expression)) {
if ($sign === '=') {
return $col . ' IN (' . $this->escape($expression) . ')';
} elseif ($sign === '!=') {
return sprintf('(%1$s NOT IN (%2$s) OR %1$s IS NULL)', $col, $this->escape($expression));
}
throw new QueryException('Unable to render array expressions with operators other than equal or not equal');
} elseif ($sign === '=' && strpos($expression, '*') !== false) {
if ($expression === '*') {
return new DbExpr('TRUE');
}
return $col . ' LIKE ' . $this->escape($this->escapeWildcards($expression));
} elseif ($sign === '!=' && strpos($expression, '*') !== false) {
if ($expression === '*') {
return new DbExpr('FALSE');
}
return sprintf(
'(%1$s NOT LIKE %2$s OR %1$s IS NULL)',
$col,
$this->escape($this->escapeWildcards($expression))
);
} elseif ($sign === '!=') {
return sprintf('(%1$s %2$s %3$s OR %1$s IS NULL)', $col, $sign, $this->escape($expression));
} else {
return sprintf('%s %s %s', $col, $sign, $this->escape($expression));
}
}
}

View File

@ -0,0 +1,75 @@
<?php
namespace ipl\Db\Zf1;
use ipl\Data\Paginatable;
use Zend_Db_Select as ZfSelect;
class SelectPaginationAdapter implements Paginatable
{
private $query;
private $countQuery;
public function __construct(ZfSelect $query)
{
$this->query = $query;
}
public function getCountQuery()
{
if ($this->countQuery === null) {
$this->countQuery = (new CountQuery($this->query))->getQuery();
}
return $this->countQuery;
}
public function count()
{
return $this->query->getAdapter()->fetchOne(
$this->getCountQuery()
);
}
public function limit($count = null, $offset = null)
{
$this->query->limit($count, $offset);
}
public function hasLimit()
{
return $this->getLimit() !== null;
}
public function getLimit()
{
return $this->query->getPart(ZfSelect::LIMIT_COUNT);
}
public function setLimit($limit)
{
$this->query->limit(
$limit,
$this->getOffset()
);
}
public function hasOffset()
{
return $this->getOffset() !== null;
}
public function getOffset()
{
return $this->query->getPart(ZfSelect::LIMIT_OFFSET);
}
public function setOffset($offset)
{
$this->query->limit(
$this->getLimit(),
$offset
);
}
}

176
library/vendor/ipl/Html/Attribute.php vendored Normal file
View File

@ -0,0 +1,176 @@
<?php
namespace ipl\Html;
use Icinga\Exception\ProgrammingError;
/**
* HTML Attribute
*
* Every single HTML attribute is (or should be) an instance of this class.
* This guarantees that every attribute is safe and escaped correctly.
*
* Usually attributes are not instantiated directly, but created through an HTML
* element's exposed methods.
*
*/
class Attribute
{
/** @var string */
protected $name;
/** @var string|array */
protected $value;
/**
* Attribute constructor.
*
* @param $name
* @param $value
*/
public function __construct($name, $value)
{
$this->setName($name)->setValue($value);
}
/**
* @param $name
* @param $value
* @return static
*/
public static function create($name, $value)
{
return new static($name, $value);
}
/**
* @param $name
* @return $this
* @throws ProgrammingError
*/
public function setName($name)
{
if (! preg_match('/^[a-z][a-z-]*$/i', $name)) {
throw new ProgrammingError(
'Attribute names with special characters are not yet allowed: %s',
$name
);
}
$this->name = $name;
return $this;
}
/**
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* @return string
*/
public function getValue()
{
return $this->value;
}
/**
* @param string|array $value
* @return $this
*/
public function setValue($value)
{
$this->value = $value;
return $this;
}
/**
* @param string $value
* @return $this
*/
public function addValue($value)
{
if (! is_array($this->value)) {
$this->value = array($this->value);
}
if (is_array($value)) {
$this->value = array_merge($this->value, $value);
} else {
$this->value[] = $value;
}
return $this;
}
/**
* @return string
*/
public function render()
{
return sprintf(
'%s="%s"',
$this->renderName(),
$this->renderValue()
);
}
/**
* @return string
*/
public function renderName()
{
return static::escapeName($this->name);
}
/**
* @return string
*/
public function renderValue()
{
return static::escapeValue($this->value);
}
/**
* @return bool
*/
public function isEmpty()
{
return null === $this->value || $this->value === [];
}
/**
* @param $name
* @return static
*/
public static function createEmpty($name)
{
return new static($name, null);
}
/**
* @param $name
* @return string
*/
public static function escapeName($name)
{
// TODO: escape
return (string) $name;
}
/**
* @param $value
* @return string
*/
public static function escapeValue($value)
{
// TODO: escape differently
if (is_array($value)) {
return Util::escapeForHtml(implode(' ', $value));
} else {
return Util::escapeForHtml((string) $value);
}
}
}

244
library/vendor/ipl/Html/Attributes.php vendored Normal file
View File

@ -0,0 +1,244 @@
<?php
namespace ipl\Html;
use Icinga\Exception\IcingaException;
use Icinga\Exception\ProgrammingError;
class Attributes
{
/** @var Attribute[] */
protected $attributes = array();
/** @var callable */
protected $callbacks = array();
/**
* Attributes constructor.
* @param Attribute[] $attributes
*/
public function __construct(array $attributes = null)
{
if (empty($attributes)) {
return;
}
foreach ($attributes as $key => $value) {
if ($value instanceof Attribute) {
$this->addAttribute($value);
} elseif (is_string($key)) {
$this->add($key, $value);
} elseif (is_array($value) && count($value) === 2) {
$this->add(array_shift($value), array_shift($value));
}
}
}
/**
* @param Attribute[] $attributes
* @return static
*/
public static function create(array $attributes = null)
{
return new static($attributes);
}
/**
* @param Attributes|array|null $attributes
* @return Attributes
* @throws IcingaException
*/
public static function wantAttributes($attributes)
{
if ($attributes instanceof Attributes) {
return $attributes;
} else {
$self = new static();
if (is_array($attributes)) {
foreach ($attributes as $k => $v) {
$self->add($k, $v);
}
return $self;
} elseif ($attributes !== null) {
throw new IcingaException(
'Attributes, Array or Null expected, got %s',
Util::getPhpTypeName($attributes)
);
}
return $self;
}
}
/**
* @return Attribute[]
*/
public function getAttributes()
{
return $this->attributes;
}
/**
* @param Attribute|string $attribute
* @param string|array $value
* @return $this
*/
public function add($attribute, $value = null)
{
if ($attribute instanceof static) {
foreach ($attribute->getAttributes() as $a) {
$this->add($a);
}
} elseif ($attribute instanceof Attribute) {
$this->addAttribute($attribute);
} elseif (is_array($attribute)) {
foreach ($attribute as $name => $value) {
$this->add($name, $value);
}
} else {
$this->addAttribute(Attribute::create($attribute, $value));
}
return $this;
}
/**
* @param Attribute|string $attribute
* @param string|array $value
* @return $this
*/
public function set($attribute, $value = null)
{
if ($attribute instanceof static) {
foreach ($attribute as $a) {
$this->setAttribute($a);
}
return $this;
} elseif ($attribute instanceof Attribute) {
return $this->setAttribute($attribute);
} elseif (is_array($attribute)) {
foreach ($attribute as $name => $value) {
$this->set($name, $value);
}
} else {
return $this->setAttribute(new Attribute($attribute, $value));
}
}
/**
* @param $name
* @return Attribute
*/
public function get($name)
{
if ($this->has($name)) {
return $this->attributes[$name];
} else {
return Attribute::createEmpty($name);
}
}
/**
* @param $name
* @return bool
*/
public function delete($name)
{
if ($this->has($name)) {
unset($this->attributes[$name]);
return true;
} else {
return false;
}
}
/**
* @param $name
* @return bool
*/
public function has($name)
{
return array_key_exists($name, $this->attributes);
}
/**
* @param Attribute $attribute
* @return $this
*/
public function addAttribute(Attribute $attribute)
{
$name = $attribute->getName();
if (array_key_exists($name, $this->attributes)) {
$this->attributes[$name]->addValue($attribute->getValue());
} else {
$this->attributes[$name] = $attribute;
}
return $this;
}
/**
* @param Attribute $attribute
* @return $this
*/
public function setAttribute(Attribute $attribute)
{
$name = $attribute->getName();
$this->attributes[$name] = $attribute;
return $this;
}
/**
* Callback must return an instance of Attribute
*
* @param string $name
* @param callable $callback
* @return $this
* @throws ProgrammingError
*/
public function registerCallbackFor($name, $callback)
{
if (! is_callable($callback)) {
throw new ProgrammingError('registerCallBack expects a callable callback');
}
$this->callbacks[$name] = $callback;
return $this;
}
/**
* @inheritdoc
*/
public function render()
{
if (empty($this->attributes) && empty($this->callbacks)) {
return '';
}
$parts = array();
foreach ($this->callbacks as $name => $callback) {
$attribute = call_user_func($callback);
if ($attribute instanceof Attribute) {
$parts[] = $attribute->render();
} elseif (is_string($attribute)) {
$parts[] = Attribute::create($name, $attribute)->render();
} elseif (null === $attribute) {
continue;
} else {
throw new ProgrammingError(
'A registered attribute callback must return string, null'
. ' or an Attribute'
);
}
}
foreach ($this->attributes as $attribute) {
if ($attribute->isEmpty()) {
continue;
}
$parts[] = $attribute->render();
}
return ' ' . implode(' ', $parts);
}
}

133
library/vendor/ipl/Html/BaseElement.php vendored Normal file
View File

@ -0,0 +1,133 @@
<?php
namespace ipl\Html;
abstract class BaseElement extends Html
{
/** @var array You may want to set default attributes when extending this class */
protected $defaultAttributes;
/** @var Attributes */
protected $attributes;
/** @var string */
protected $tag;
/**
* @return Attributes
*/
public function attributes()
{
if ($this->attributes === null) {
$default = $this->getDefaultAttributes();
if (empty($default)) {
$this->attributes = new Attributes();
} else {
$this->attributes = Attributes::wantAttributes($default);
}
}
return $this->attributes;
}
/**
* @param Attributes|array|null $attributes
* @return $this
*/
public function setAttributes($attributes)
{
$this->attributes = Attributes::wantAttributes($attributes);
return $this;
}
/**
* @param Attributes|array|null $attributes
* @return $this
*/
public function addAttributes($attributes)
{
$this->attributes()->add($attributes);
return $this;
}
public function getDefaultAttributes()
{
return $this->defaultAttributes;
}
public function setTag($tag)
{
$this->tag = $tag;
return $this;
}
public function getTag()
{
return $this->tag;
}
/**
* Container constructor.
*
* @param string $tag
* @param Attributes|array $attributes
*
* @return Element
*/
public function addElement($tag, $attributes = null)
{
$element = Element::create($tag, $attributes);
$this->add($element);
return $element;
}
public function renderContent()
{
return parent::render();
}
protected function assemble()
{
}
/**
* @return string
*/
public function render()
{
$tag = $this->getTag();
$this->assemble();
$content = $this->renderContent();
if (strlen($content) || $this->forcesClosingTag()) {
return sprintf(
'<%s%s>%s</%s>',
$tag,
$this->attributes()->render(),
$content,
$tag
);
} else {
return sprintf(
'<%s%s />',
$tag,
$this->attributes()->render()
);
}
}
public function forcesClosingTag()
{
return false;
}
/**
* Whether the given something can be rendered
*
* @param mixed $any
* @return bool
*/
protected function canBeRendered($any)
{
return is_string($any) || is_int($any) || is_null($any);
}
}

40
library/vendor/ipl/Html/Container.php vendored Normal file
View File

@ -0,0 +1,40 @@
<?php
namespace ipl\Html;
class Container extends BaseElement
{
/** @var string */
protected $contentSeparator = "\n";
/** @var string */
protected $tag = 'div';
protected function __construct()
{
}
/**
* @param Html|array|string $content
* @param Attributes|array $attributes
* @param string $tag
*
* @return static
*/
public static function create($attributes = null, $content = null, $tag = null)
{
$container = new static();
if ($content !== null) {
$container->setContent($content);
}
if ($attributes !== null) {
$container->setAttributes($attributes);
}
if ($tag !== null) {
$container->setTag($tag);
}
return $container;
}
}

View File

@ -0,0 +1,86 @@
<?php
namespace ipl\Html;
use Exception;
/**
* This class allows to have plain text passed in as a callback. That way it
* would not be called and stringified unless it is going to be rendered and
* escaped to HTML
*
* Usage
* -----
* <code>
* $myVar = 'Some value';
* $text = new DeferredText(function () use ($myVar) {
* return $myVar;
* });
* $myVar = 'Changed idea';
* echo $text;
* </code>
*/
class DeferredText implements ValidHtml
{
/** @var callable will return the text that should be rendered */
protected $callback;
/** @var bool */
protected $escaped = false;
/**
* DeferredText constructor.
* @param callable $callback Must return the text that should be rendered
*/
public function __construct(callable $callback)
{
$this->callback = $callback;
}
/**
* Static factory
*
* @param callable $callback Must return the text that should be rendered
* @return static
*/
public static function create(callable $callback)
{
return new static($callback);
}
public function render()
{
$callback = $this->callback;
if ($this->escaped) {
return $callback();
} else {
return Util::escapeForHtml($callback());
}
}
/**
* @param bool $escaped
* @return $this
*/
public function setEscaped($escaped = true)
{
$this->escaped = $escaped;
return $this;
}
/**
* Calls the render function, but is failsafe. In case an Exception occurs,
* an error is rendered instead of the expected HTML
*
* @return string
*/
public function __toString()
{
try {
return $this->render();
} catch (Exception $e) {
return Util::renderError($e);
}
}
}

40
library/vendor/ipl/Html/Element.php vendored Normal file
View File

@ -0,0 +1,40 @@
<?php
namespace ipl\Html;
class Element extends BaseElement
{
/**
* Container constructor.
*
* @param string $tag
* @param Attributes|array $attributes
* @param ValidHtml|array|string $content
*/
public function __construct($tag, $attributes = null, $content = null)
{
$this->tag = $tag;
if ($attributes !== null) {
$this->attributes = $this->attributes()->add($attributes);
}
if ($content !== null) {
$this->setContent($content);
}
}
/**
* Container constructor.
*
* @param string $tag
* @param Attributes|array $attributes
* @param ValidHtml|array|string $content
*
* @return static
*/
public static function create($tag, $attributes = null, $content = null)
{
return new static($tag, $attributes, $content);
}
}

View File

@ -0,0 +1,37 @@
<?php
namespace ipl\Html;
class FormattedString implements ValidHtml
{
protected $escaped = true;
/** @var ValidHtml[] */
protected $arguments = [];
/** @var ValidHtml */
protected $string;
public function __construct($string, array $arguments = [])
{
$this->string = Util::wantHtml($string);
foreach ($arguments as $key => $val) {
$this->arguments[$key] = Util::wantHtml($val);
}
}
public static function create($string)
{
$args = func_get_args();
return new static(array_shift($args), $args);
}
public function render()
{
return vsprintf(
$this->string->render(),
$this->arguments
);
}
}

226
library/vendor/ipl/Html/Html.php vendored Normal file
View File

@ -0,0 +1,226 @@
<?php
namespace ipl\Html;
use Exception;
use Icinga\Exception\ProgrammingError;
class Html implements ValidHtml
{
protected $contentSeparator = '';
/** @var ValidHtml[] */
private $content = [];
/** @var array */
private $contentIndex = [];
/**
* @param ValidHtml|array|string $content
* @return $this
*/
public function add($content)
{
if (is_array($content)) {
foreach ($content as $c) {
$this->addContent($c);
}
} else {
$this->addIndexedContent(Util::wantHtml($content));
}
return $this;
}
/**
* @param $content
* @return $this
*/
public function prepend($content)
{
if (is_array($content)) {
foreach (array_reverse($content) as $c) {
$this->prepend($c);
}
} else {
$pos = 0;
$html = Util::wantHtml($content);
array_unshift($this->content, $html);
$this->incrementIndexKeys();
$this->addObjectPosition($html, $pos);
}
return $this;
}
public function remove(Html $html)
{
$key = spl_object_hash($html);
if (array_key_exists($key, $this->contentIndex)) {
foreach ($this->contentIndex[$key] as $pos) {
unset($this->content[$pos]);
}
}
$this->reIndexContent();
}
/**
* @param $string
* @return Html
*/
public function addPrintf($string)
{
$args = func_get_args();
array_shift($args);
return $this->add(
new FormattedString($string, $args)
);
}
/**
* @param Html|array|string $content
* @return self
*/
public function setContent($content)
{
$this->content = array();
static::addContent($content);
return $this;
}
/**
* @see Html::add()
*/
public function addContent($content)
{
return $this->add($content);
}
/**
* return ValidHtml[]
*/
public function getContent()
{
return $this->content;
}
/**
* @return bool
*/
public function hasContent()
{
return ! empty($this->content);
}
/**
* @param $separator
* @return self
*/
public function setSeparator($separator)
{
$this->contentSeparator = $separator;
return $this;
}
/**
* @inheritdoc
*/
public function render()
{
$html = array();
foreach ($this->content as $element) {
if (is_string($element)) {
var_dump($this->content);
}
$html[] = $element->render();
}
return implode($this->contentSeparator, $html);
}
/**
* @param $tag
* @param null $attributes
* @param null $content
* @return Element
*/
public static function tag($tag, $attributes = null, $content = null)
{
return Element::create($tag, $attributes, $content);
}
public static function element($name, $attributes = null)
{
// TODO: This might be anything here, add a better check
if (! ctype_alnum($name)) {
throw new ProgrammingError('Invalid element requested');
}
$class = __NAMESPACE__ . '\\' . $name;
/** @var Element $element */
$element = new $class();
if ($attributes !== null) {
$element->setAttributes($attributes);
}
return $element;
}
/**
* @param Exception|string $error
* @return string
*/
protected function renderError($error)
{
return Util::renderError($error);
}
/**
* @return string
*/
public function __toString()
{
try {
return $this->render();
} catch (Exception $e) {
return $this->renderError($e);
}
}
private function reIndexContent()
{
$this->contentIndex = [];
foreach ($this->content as $pos => $html) {
$this->addObjectPosition($html, $pos);
}
}
private function addObjectPosition(ValidHtml $html, $pos)
{
$key = spl_object_hash($html);
if (array_key_exists($key, $this->contentIndex)) {
$this->contentIndex[$key][] = $pos;
} else {
$this->contentIndex[$key] = [$pos];
}
}
private function addIndexedContent(ValidHtml $html)
{
$pos = count($this->content);
$this->content[$pos] = $html;
$this->addObjectPosition($html, $pos);
}
private function incrementIndexKeys()
{
foreach ($this->contentIndex as & $index) {
foreach ($index as & $pos) {
$pos++;
}
}
}
}

View File

@ -0,0 +1,8 @@
<?php
namespace ipl\Html;
class HtmlString extends Text
{
protected $escaped = true;
}

31
library/vendor/ipl/Html/HtmlTag.php vendored Normal file
View File

@ -0,0 +1,31 @@
<?php
namespace ipl\Html;
/**
* @deprecated
*/
abstract class HtmlTag
{
/**
* @param $content
* @param Attributes|array $attributes
*
* @return Element
*/
public static function h1($content, $attributes = null)
{
return Element::create('h1', $attributes)->setContent($content);
}
/**
* @param $content
* @param Attributes|array $attributes
*
* @return Element
*/
public static function p($content, $attributes = null)
{
return Element::create('p', $attributes)->setContent($content);
}
}

30
library/vendor/ipl/Html/Icon.php vendored Normal file
View File

@ -0,0 +1,30 @@
<?php
namespace ipl\Html;
class Icon extends BaseElement
{
protected $tag = 'i';
public function __construct($name, $attributes = null)
{
$this->setAttributes($attributes);
$this->attributes()->add('class', array('icon', 'icon-' . $name));
}
/**
* @param string $name
* @param array $attributes
*
* @return static
*/
public static function create($name, array $attributes = null)
{
return new static($name, $attributes);
}
public function forcesClosingTag()
{
return true;
}
}

73
library/vendor/ipl/Html/Img.php vendored Normal file
View File

@ -0,0 +1,73 @@
<?php
namespace ipl\Html;
use ipl\Web\Url;
use Icinga\Web\Url as WebUrl;
class Img extends BaseElement
{
protected $tag = 'img';
/** @var Url */
protected $url;
protected $defaultAttributes = array('alt' => '');
protected function __construct()
{
}
/**
* @param Url|string $url
* @param array $urlParams
* @param array $attributes
*
* @return static
*/
public static function create($url, $urlParams = null, array $attributes = null)
{
/** @var Img $img */
$img = new static();
$img->setAttributes($attributes);
$img->attributes()->registerCallbackFor('src', array($img, 'getSrcAttribute'));
$img->setUrl($url, $urlParams);
return $img;
}
public function setUrl($url, $urlParams)
{
if ($url instanceof WebUrl) { // Hint: Url is also a WebUrl
if ($urlParams !== null) {
$url->addParams($urlParams);
}
$this->url = $url;
} else {
if ($urlParams === null) {
$this->url = Url::fromPath($url);
} else {
$this->url = Url::fromPath($url, $urlParams);
}
}
$this->url->getParams();
}
/**
* @return Attribute
*/
public function getSrcAttribute()
{
return new Attribute('src', $this->getUrl()->getAbsoluteUrl('&'));
}
/**
* @return Url
*/
public function getUrl()
{
// TODO: What if null? #?
return $this->url;
}
}

83
library/vendor/ipl/Html/Link.php vendored Normal file
View File

@ -0,0 +1,83 @@
<?php
namespace ipl\Html;
use ipl\Web\Url;
use Icinga\Web\Url as WebUrl;
class Link extends BaseElement
{
protected $tag = 'a';
/** @var Url */
protected $url;
/**
* Link constructor.
* @param $content
* @param $url
* @param null $urlParams
* @param array|null $attributes
*/
public function __construct($content, $url, $urlParams = null, array $attributes = null)
{
$this->setContent($content);
$this->setAttributes($attributes);
$this->attributes()->registerCallbackFor('href', array($this, 'getHrefAttribute'));
$this->setUrl($url, $urlParams);
}
/**
* @param ValidHtml|array|string $content
* @param Url|string $url
* @param array $urlParams
* @param mixed $attributes
*
* @return static
*/
public static function create($content, $url, $urlParams = null, array $attributes = null)
{
$link = new static($content, $url, $urlParams, $attributes);
return $link;
}
/**
* @param $url
* @param $urlParams
*/
public function setUrl($url, $urlParams)
{
if ($url instanceof WebUrl) { // Hint: Url is also a WebUrl
if ($urlParams !== null) {
$url->addParams($urlParams);
}
$this->url = $url;
} else {
if ($urlParams === null) {
$this->url = Url::fromPath($url);
} else {
$this->url = Url::fromPath($url, $urlParams);
}
}
$this->url->getParams();
}
/**
* @return Attribute
*/
public function getHrefAttribute()
{
return new Attribute('href', $this->getUrl()->getAbsoluteUrl('&'));
}
/**
* @return Url
*/
public function getUrl()
{
// TODO: What if null? #?
return $this->url;
}
}

223
library/vendor/ipl/Html/Table.php vendored Normal file
View File

@ -0,0 +1,223 @@
<?php
namespace ipl\Html;
use Traversable;
class Table extends BaseElement
{
protected $contentSeparator = ' ';
/** @var string */
protected $tag = 'table';
/** @var Element */
private $caption;
/** @var Element */
private $header;
/** @var Element */
private $body;
/** @var Element */
private $footer;
/** @var array */
private $columnsToBeRendered;
/**
* Return additional class names for a given row
*
* Extend this method in case you want to add classes to the table row
* element (tr) based on a row's properties
*
* @return null|string|array
*/
public function getRowClasses($row)
{
return null;
}
/**
* Set the table title
*
* Will be rendered as a "caption" HTML element
*
* @param $content
* @return $this
*/
public function setCaption($content)
{
$this->caption = Element::create('caption')->addContent(
$content
);
return $this;
}
/**
* Static helper creating a tr element
*
* @param Attributes|array $attributes
* @param Html|array|string $content
* @return Element
*/
public static function tr($content = null, $attributes = null)
{
return Element::create('tr', $attributes, $content);
}
/**
* Static helper creating a th element
*
* @param Attributes|array $attributes
* @param Html|array|string $content
* @return Element
*/
public static function th($content = null, $attributes = null)
{
return Element::create('th', $attributes, $content);
}
/**
* Static helper creating a td element
*
* @param Attributes|array $attributes
* @param Html|array|string $content
* @return Element
*/
public static function td($content = null, $attributes = null)
{
return Element::create('td', $attributes, $content);
}
public function generateHeader()
{
return Element::create('thead')->add(
$this->addHeaderColumnsTo(static::tr())
);
}
public function generateFooter()
{
return Element::create('tfoot')->add(
$this->addHeaderColumnsTo(static::tr())
);
}
protected function addHeaderColumnsTo(Element $parent)
{
foreach ($this->getColumnsToBeRendered() as $column) {
$parent->add(
Element::create('th')->setContent($column)
);
}
return $parent;
}
/**
* @return null|array
*/
public function getColumnsToBeRendered()
{
return $this->columnsToBeRendered;
}
public function setColumnsToBeRendered(array $columns)
{
$this->columnsToBeRendered = $columns;
return $this;
}
public function renderRow($row)
{
$tr = $this->addRowClasses(Element::create('tr'), $row);
$columns = $this->getColumnsToBeRendered();
if ($columns === null) {
$this->setColumnsToBeRendered(array_keys((array) $row));
$columns = $this->getColumnsToBeRendered();
}
foreach ($columns as $column) {
$td = static::td();
if (property_exists($row, $column)) {
$td->setContent($row->$column);
}
$tr->add($td);
}
return $tr;
}
public function addRowClasses(Element $tr, $row)
{
$classes = $this->getRowClasses($row);
if (! empty($classes)) {
$tr->attributes()->add('class', $classes);
}
return $tr;
}
public function renderRows(Traversable $rows)
{
$body = $this->body();
foreach ($rows as $row) {
$body->add($this->renderRow($row));
}
return $body;
}
public function body()
{
if ($this->body === null) {
$this->body = Element::create('tbody')->setSeparator("\n");
}
return $this->body;
}
public function header()
{
if ($this->header === null) {
$this->header = $this->generateHeader();
}
return $this->header;
}
public function footer()
{
if ($this->footer === null) {
$this->footer = $this->generateFooter();
}
return $this->footer;
}
public function renderContent()
{
if (null !== $this->caption) {
$this->add($this->caption);
}
if (null !== $this->header) {
$this->add($this->header);
}
if (null !== $this->body) {
$this->add($this->body());
}
if (null !== $this->footer) {
$this->add($this->footer);
}
return parent::renderContent();
}
}

87
library/vendor/ipl/Html/Text.php vendored Normal file
View File

@ -0,0 +1,87 @@
<?php
namespace ipl\Html;
use Exception;
class Text implements ValidHtml
{
/** @var string */
protected $string;
protected $escaped = false;
/**
* Text constructor.
*
* @param $text
*/
public function __construct($string)
{
$this->string = (string) $string;
}
/**
* @return string
*/
public function getText()
{
return $this->string;
}
/**
* @param bool $escaped
* @return $this
*/
public function setEscaped($escaped = true)
{
$this->escaped = $escaped;
return $this;
}
/**
* @param $text
*
* @return static
*/
public static function create($text)
{
return new static($text);
}
/**
* @return string
*/
public function render()
{
if ($this->escaped) {
return $this->string;
} else {
return Util::escapeForHtml($this->string);
}
}
/**
* TODO: Allow to (statically) inject an error renderer. This will allow
* us to satisfy "Show exceptions" settings and/or preferences
*
* @param Exception|string $error
* @return string
*/
protected function renderError($error)
{
return Util::renderError($error);
}
/**
* @return string
*/
public function __toString()
{
try {
return $this->render();
} catch (Exception $e) {
return $this->renderError($e);
}
}
}

153
library/vendor/ipl/Html/Util.php vendored Normal file
View File

@ -0,0 +1,153 @@
<?php
namespace ipl\Html;
use Exception;
use Icinga\Exception\IcingaException;
class Util
{
/**
* Charset to be used - we only support UTF-8
*/
const CHARSET = 'UTF-8';
/**
* The flags we use for htmlspecialchars depend on our PHP version
*/
protected static $htmlEscapeFlags;
/** @var bool */
protected static $showTraces = true;
/**
* Escape the given value top be safely used in view scripts
*
* @param string $value The output to be escaped
* @return string
*/
public static function escapeForHtml($value)
{
return htmlspecialchars(
$value,
static::htmlEscapeFlags(),
self::CHARSET,
true
);
}
/**
* @param Exception|string $error
* @return string
*/
public static function renderError($error)
{
if ($error instanceof Exception) {
$file = preg_split('/[\/\\\]/', $error->getFile(), -1, PREG_SPLIT_NO_EMPTY);
$file = array_pop($file);
$msg = sprintf(
'%s (%s:%d)',
$error->getMessage(),
$file,
$error->getLine()
);
} elseif (is_string($error)) {
$msg = $error;
} else {
$msg = 'Got an invalid error'; // TODO: translate?
}
$output = sprintf(
// TODO: translate? Be careful when doing so, it must be failsafe!
"<div class=\"exception\">\n<h1><i class=\"icon-bug\">"
. "</i>Oops, an error occurred!</h1>\n<pre>%s</pre>\n",
static::escapeForHtml($msg)
);
if (static::showTraces()) {
$output .= sprintf(
"<pre>%s</pre>\n",
static::escapeForHtml($error->getTraceAsString())
);
}
$output .= "</div>\n";
return $output;
}
public static function showTraces($show = null)
{
if ($show !== null) {
self::$showTraces = $show;
}
return self::$showTraces;
}
/**
* @param $any
* @return ValidHtml
* @throws IcingaException
*/
public static function wantHtml($any)
{
if ($any instanceof ValidHtml) {
return $any;
} elseif (static::canBeRenderedAsString($any)) {
return new Text($any);
} elseif (is_array($any)) {
$html = new Html();
foreach ($any as $el) {
$html->add(static::wantHtml($el));
}
return $html;
} else {
// TODO: Should we add a dedicated Exception class?
throw new IcingaException(
'String, Html Element or Array of such expected, got "%s"',
Util::getPhpTypeName($any)
);
}
}
public static function canBeRenderedAsString($any)
{
return is_string($any) || is_int($any) || is_null($any);
}
/**
* @param $any
* @return string
*/
public static function getPhpTypeName($any)
{
if (is_object($any)) {
return get_class($any);
} else {
return gettype($any);
}
}
/**
* This defines the flags used when escaping for HTML
*
* - Single quotes are not escaped (ENT_COMPAT)
* - With PHP >= 5.4, invalid characters are replaced with <EFBFBD> (ENT_SUBSTITUTE)
* - With PHP 5.3 they are ignored (ENT_IGNORE, less secure)
* - Uses HTML5 entities for PHP >= 5.4, disallowing &#013;
*
* @return int
*/
protected static function htmlEscapeFlags()
{
if (self::$htmlEscapeFlags === null) {
if (version_compare(PHP_VERSION, '5.4.0') >= 0) {
self::$htmlEscapeFlags = ENT_COMPAT | ENT_SUBSTITUTE | ENT_HTML5;
} else {
self::$htmlEscapeFlags = ENT_COMPAT | ENT_IGNORE;
}
}
return self::$htmlEscapeFlags;
}
}

21
library/vendor/ipl/Html/ValidHtml.php vendored Normal file
View File

@ -0,0 +1,21 @@
<?php
namespace ipl\Html;
/**
* Interface ValidHtml
*
* Implementations of this interface MUST guarantee, that the result of the
* render() method gives valid UTF-8 encoded HTML5.
*/
interface ValidHtml
{
/**
* Renders to HTML
*
* The result of this method is a valid UTF8-encoded HTML5 string.
*
* @return string
*/
public function render();
}

View File

@ -0,0 +1,16 @@
<?php
namespace ipl\Loader;
use Icinga\Application\ApplicationBootstrap;
class CompatLoader
{
public static function delegateLoadingToIcingaWeb(ApplicationBootstrap $app)
{
$app->getLoader()->registerNamespace(
'ipl',
dirname(__DIR__)
);
}
}

View File

@ -0,0 +1,56 @@
<?php
namespace ipl\Test;
use ipl\Loader\CompatLoader;
use Icinga\Application\Icinga;
use PHPUnit_Framework_TestCase;
use ReflectionClass;
abstract class BaseTestCase extends PHPUnit_Framework_TestCase
{
private static $app;
public function setUp()
{
// $this->setupCompatLoader();
}
/**
* @param $obj
* @param $name
* @return \ReflectionMethod
*/
public function getProtectedMethod($obj, $name)
{
$class = new ReflectionClass($obj);
$method = $class->getMethod($name);
$method->setAccessible(true);
return $method;
}
/**
* @param $obj
* @param $name
* @return \ReflectionMethod
*/
public function getPrivateMethod($obj, $name)
{
return $this->getProtectedMethod($obj, $name);
}
protected function setupCompatLoader()
{
require_once dirname(__DIR__) . '/Loader/CompatLoader.php';
CompatLoader::delegateLoadingToIcingaWeb($this->app());
}
protected function app()
{
if (self::$app === null) {
self::$app = Icinga::app();
}
return self::$app;
}
}

31
library/vendor/ipl/Test/Bootstrap.php vendored Normal file
View File

@ -0,0 +1,31 @@
<?php
namespace ipl\Test;
use Icinga\Application\Cli;
use ipl\Loader\CompatLoader;
class Bootstrap
{
public static function cli($basedir = null)
{
error_reporting(E_ALL | E_STRICT);
if ($basedir === null) {
$basedir = dirname(dirname(dirname(__DIR__)));
}
$testsDir = $basedir . '/test';
require_once 'Icinga/Application/Cli.php';
if (array_key_exists('ICINGAWEB_CONFIGDIR', $_SERVER)) {
$configDir = $_SERVER['ICINGAWEB_CONFIGDIR'];
} else {
$configDir = $testsDir . '/compat-icingaweb2/config';
}
$app = Cli::start($testsDir, $configDir);
require_once "$basedir/lib/ipl/Loader/CompatLoader.php";
CompatLoader::delegateLoadingToIcingaWeb($app);
}
}

View File

@ -0,0 +1,11 @@
<?php
namespace ipl\Translation;
class NoTranslator implements TranslatorInterface
{
public function translate($string)
{
return $string;
}
}

View File

@ -0,0 +1,31 @@
<?php
namespace ipl\Translation;
class StaticTranslator
{
/** @var TranslatorInterface */
private static $translator;
public static function get()
{
if (self::$translator === null) {
static::setNoTranslator();
}
return static::$translator;
}
public static function setNoTranslator()
{
static::set(new NoTranslator());
}
/**
* @param TranslatorInterface $translator
*/
public static function set(TranslatorInterface $translator)
{
self::$translator = $translator;
}
}

View File

@ -0,0 +1,37 @@
<?php
namespace ipl\Translation;
trait TranslationHelper
{
/** @var TranslatorInterface */
private static $translator;
/**
* @param $string
* @param string|null $context
* @return string
*/
public function translate($string, $context = null)
{
return self::getTranslator()->translate($string);
}
public static function getTranslator()
{
return StaticTranslator::get();
}
public static function setNoTranslator()
{
StaticTranslator::set(new NoTranslator());
}
/**
* @param TranslatorInterface $translator
*/
public static function setTranslator(TranslatorInterface $translator)
{
StaticTranslator::set($translator);
}
}

View File

@ -0,0 +1,8 @@
<?php
namespace ipl\Translation;
interface TranslatorInterface
{
public function translate($string);
}

View File

@ -0,0 +1,26 @@
<?php
namespace ipl\Translation;
class WrapTranslator implements TranslatorInterface
{
/** @var callable */
private $callback;
/** @var TranslatorInterface */
private $wrapped;
public function __construct(TranslatorInterface $wrapped, callable $callback)
{
$this->wrapped = $wrapped;
$this->callback = $callback;
}
public function translate($string)
{
return call_user_func_array(
$this->callback,
[$this->wrapped->translate($string)]
);
}
}

View File

@ -0,0 +1,569 @@
<?php
namespace ipl\Web;
use Icinga\Application\Benchmark;
use Icinga\Application\Config;
use Icinga\Application\Icinga;
use Icinga\Application\Modules\Manager;
use Icinga\Application\Modules\Module;
use Icinga\Authentication\Auth;
use Icinga\Exception\IcingaException;
use Icinga\Exception\ProgrammingError;
use Icinga\Forms\AutoRefreshForm;
use Icinga\Security\SecurityException;
use Icinga\User;
use Icinga\Web\Notification;
use Icinga\Web\Session;
use Icinga\Web\UrlParams;
use Icinga\Web\Url as WebUrl;
use Icinga\Web\Window;
use ipl\Compat\Translator;
use ipl\Translation\TranslationHelper;
use ipl\Web\Component\ControlsAndContent;
use ipl\Web\Controller\Extension\ControlsAndContentHelper;
use ipl\Zf1\SimpleViewRenderer;
use Zend_Controller_Action;
use Zend_Controller_Action_HelperBroker as ZfHelperBroker;
use Zend_Controller_Request_Abstract as ZfRequest;
use Zend_Controller_Response_Abstract as ZfResponse;
class CompatController extends Zend_Controller_Action implements ControlsAndContent
{
use TranslationHelper;
use ControlsAndContentHelper;
/** @var bool Whether the controller requires the user to be authenticated */
protected $requiresAuthentication = true;
/** @var string The current module's name */
private $moduleName;
private $config;
private $configs = [];
private $module;
private $window;
// https://github.com/joshbuchea/HEAD
/** @var SimpleViewRenderer */
protected $viewRenderer;
/** @var int|null */
private $autorefreshInterval;
/** @var bool */
private $reloadCss = false;
/** @var bool */
private $rerenderLayout = false;
/** @var string */
private $xhrLayout = 'inline';
/** @var \Zend_Layout */
private $layout;
/** @var string The inner layout (inside the body) to use */
private $innerLayout = 'body';
/**
* Authentication manager
*
* @var Auth|null
*/
private $auth;
/** @var UrlParams */
protected $params;
/**
* The constructor starts benchmarking, loads the configuration and sets
* other useful controller properties
*
* @param ZfRequest $request
* @param ZfResponse $response
* @param array $invokeArgs Any additional invocation arguments
*/
public function __construct(
ZfRequest $request,
ZfResponse $response,
array $invokeArgs = array()
) {
/** @var \Icinga\Web\Request $request */
/** @var \Icinga\Web\Response $response */
$this->params = UrlParams::fromQueryString();
$this->setRequest($request)
->setResponse($response)
->_setInvokeArgs($invokeArgs);
$this->prepareViewRenderer();
$this->_helper = new ZfHelperBroker($this);
$this->handlerBrowserWindows();
$moduleName = $this->getModuleName();
$this->initializeTranslator();
$layout = $this->layout = $this->_helper->layout();
$layout->isIframe = $request->getUrl()->shift('isIframe');
$layout->showFullscreen = $request->getUrl()->shift('showFullscreen');
$layout->moduleName = $moduleName;
$this->view->compact = $request->getParam('view') === 'compact';
$url = $this->url();
$this->params = $url->getParams();
if ($url->shift('showCompact')) {
$this->view->compact = true;
}
if ($this->rerenderLayout = $url->shift('renderLayout')) {
$this->xhrLayout = $this->innerLayout;
}
if ($url->shift('_disableLayout')) {
$this->layout->disableLayout();
}
// $auth->authenticate($request, $response, $this->requiresLogin());
if ($this->requiresLogin()) {
if (! $request->isXmlHttpRequest() && $request->isApiRequest()) {
Auth::getInstance()->challengeHttp();
}
$this->redirectToLogin(Url::fromRequest());
}
if (($this->Auth()->isAuthenticated() || $this->requiresLogin())
&& $this->getFrontController()->getDefaultModule() !== $this->getModuleName()) {
$this->assertPermission(Manager::MODULE_PERMISSION_NS . $this->getModuleName());
}
Benchmark::measure('Ready to initialize the controller');
$this->prepareInit();
$this->init();
}
/**
* Prepare controller initialization
*
* As it should not be required for controllers to call the parent's init() method,
* base controllers should use prepareInit() in order to prepare the controller
* initialization.
*
* @see \Zend_Controller_Action::init() For the controller initialization method.
*/
protected function prepareInit()
{
}
/**
* Return the current module's name
*
* @return string
*/
public function getModuleName()
{
if ($this->moduleName === null) {
$this->moduleName = $this->getRequest()->getModuleName();
}
return $this->moduleName;
}
public function Config($file = null)
{
if ($this->moduleName === null) {
if ($file === null) {
return Config::app();
} else {
return Config::app($file);
}
} else {
return $this->getModuleConfig($file);
}
}
public function getModuleConfig($file = null)
{
if ($file === null) {
if ($this->config === null) {
$this->config = Config::module($this->getModuleName());
}
return $this->config;
} else {
if (! array_key_exists($file, $this->configs)) {
$this->configs[$file] = Config::module($this->getModuleName(), $file);
}
return $this->configs[$file];
}
}
/**
* Return this controller's module
*
* @return Module
*/
public function Module()
{
if ($this->module === null) {
$this->module = Icinga::app()->getModuleManager()->getModule($this->getModuleName());
}
return $this->module;
}
public function Window()
{
if ($this->window === null) {
$this->window = new Window(
$this->_request->getHeader('X-Icinga-WindowId', Window::UNDEFINED)
);
}
return $this->window;
}
protected function handlerBrowserWindows()
{
if ($this->isXhr()) {
$id = $this->_request->getHeader('X-Icinga-WindowId', null);
if ($id === Window::UNDEFINED) {
$this->window = new Window($id);
$this->_response->setHeader('X-Icinga-WindowId', Window::generateId());
}
}
}
protected function initializeTranslator()
{
$moduleName = $this->getModuleName();
$domain = $moduleName !== 'default' ? $moduleName : 'icinga';
$this->view->translationDomain = $domain;
TranslationHelper::setTranslator(new Translator($domain));
}
public function init()
{
// Hint: we intentionally do not call our parent's init() method
}
/**
* Get the authentication manager
*
* @return Auth
*/
public function Auth()
{
if ($this->auth === null) {
$this->auth = Auth::getInstance();
}
return $this->auth;
}
/**
* Whether the current user has the given permission
*
* @param string $permission Name of the permission
*
* @return bool
*/
public function hasPermission($permission)
{
return $this->Auth()->hasPermission($permission);
}
/**
* Assert that the current user has the given permission
*
* @param string $permission Name of the permission
*
* @throws SecurityException If the current user lacks the given permission
*/
public function assertPermission($permission)
{
if (! $this->Auth()->hasPermission($permission)) {
throw new SecurityException('No permission for %s', $permission);
}
}
/**
* Return restriction information for an eventually authenticated user
*
* @param string $name Restriction name
*
* @return array
*/
public function getRestrictions($name)
{
return $this->Auth()->getRestrictions($name);
}
/**
* Check whether the controller requires a login. That is when the controller requires authentication and the
* user is currently not authenticated
*
* @return bool
*/
protected function requiresLogin()
{
if (! $this->requiresAuthentication) {
return false;
}
return ! $this->Auth()->isAuthenticated();
}
public function prepareViewRenderer()
{
$this->viewRenderer = new SimpleViewRenderer();
$this->viewRenderer->replaceZendViewRenderer();
$this->view = $this->viewRenderer->view;
}
/**
* @return SimpleViewRenderer
*/
public function getViewRenderer()
{
return $this->viewRenderer;
}
public function setAutorefreshInterval($interval)
{
if (! is_int($interval) || $interval < 1) {
throw new ProgrammingError(
'Setting autorefresh interval smaller than 1 second is not allowed'
);
}
$this->autorefreshInterval = $interval;
$this->layout->autorefreshInterval = $interval;
return $this;
}
public function disableAutoRefresh()
{
$this->autorefreshInterval = null;
$this->layout->autorefreshInterval = null;
return $this;
}
protected function redirectXhr($url)
{
if (! $url instanceof WebUrl) {
$url = Url::fromPath($url);
}
if ($this->rerenderLayout) {
$this->getResponse()->setHeader('X-Icinga-Rerender-Layout', 'yes');
}
if ($this->reloadCss) {
$this->getResponse()->setHeader('X-Icinga-Reload-Css', 'now');
}
$this->shutdownSession();
$this->getResponse()
->setHeader('X-Icinga-Redirect', rawurlencode($url->getAbsoluteUrl()))
->sendHeaders();
exit;
}
/**
* @see Zend_Controller_Action::preDispatch()
*/
public function preDispatch()
{
$form = new AutoRefreshForm();
$form->handleRequest();
$this->_helper->layout()->autoRefreshForm = $form;
}
/**
* Detect whether the current request requires changes in the layout and apply them before rendering
*
* @see Zend_Controller_Action::postDispatch()
*/
public function postDispatch()
{
Benchmark::measure('Action::postDispatch()');
$layout = $this->layout;
$req = $this->getRequest();
$layout->innerLayout = $this->innerLayout;
/** @var User $user */
if ($user = $req->getUser()) {
if ((bool) $user->getPreferences()->getValue('icingaweb', 'show_benchmark', false)) {
if ($layout->isEnabled()) {
$layout->benchmark = $this->renderBenchmark();
}
}
if (! (bool) $user->getPreferences()->getValue('icingaweb', 'auto_refresh', true)) {
$this->disableAutoRefresh();
}
}
if ($req->getParam('format') === 'pdf') {
$this->shutdownSession();
$this->sendAsPdf();
return;
}
if ($this->isXhr()) {
$this->postDispatchXhr();
}
$this->shutdownSession();
}
public function postDispatchXhr()
{
$this->layout->setLayout($this->xhrLayout);
$resp = $this->getResponse();
$notifications = Notification::getInstance();
if ($notifications->hasMessages()) {
$notificationList = array();
foreach ($notifications->popMessages() as $m) {
$notificationList[] = rawurlencode($m->type . ' ' . $m->message);
}
$resp->setHeader('X-Icinga-Notification', implode('&', $notificationList), true);
}
if ($this->reloadCss) {
$resp->setHeader('X-Icinga-CssReload', 'now', true);
}
if ($this->title) {
if (preg_match('~[\r\n]~', $this->title)) {
// TODO: Innocent exception and error log for hack attempts
throw new IcingaException('No newlines allowed in page title');
}
$resp->setHeader(
'X-Icinga-Title',
rawurlencode($this->title . ' :: Icinga Web'),
true
);
} else {
$resp->setHeader('X-Icinga-Title', rawurlencode('Icinga Web'), true);
}
if ($this->rerenderLayout) {
$this->getResponse()->setHeader('X-Icinga-Container', 'layout', true);
}
if ($this->autorefreshInterval !== null) {
$resp->setHeader('X-Icinga-Refresh', $this->autorefreshInterval, true);
}
if ($name = $this->getModuleName()) {
$this->getResponse()->setHeader('X-Icinga-Module', $name, true);
}
}
/**
* Redirect to login
*
* XHR will always redirect to __SELF__ if an URL to redirect to after successful login is set. __SELF__ instructs
* JavaScript to redirect to the current window's URL if it's an auto-refresh request or to redirect to the URL
* which required login if it's not an auto-refreshing one.
*
* XHR will respond with HTTP status code 403 Forbidden.
*
* @param Url|string $redirect URL to redirect to after successful login
*/
protected function redirectToLogin($redirect = null)
{
$login = Url::fromPath('authentication/login');
if ($this->isXhr()) {
if ($redirect !== null) {
$login->setParam('redirect', '__SELF__');
}
$this->_response->setHttpResponseCode(403);
} elseif ($redirect !== null) {
if (! $redirect instanceof Url) {
$redirect = Url::fromPath($redirect);
}
if (($relativeUrl = $redirect->getRelativeUrl())) {
$login->setParam('redirect', $relativeUrl);
}
}
$this->rerenderLayout()->redirectNow($login);
}
protected function sendAsPdf()
{
$pdf = new Pdf();
$pdf->renderControllerAction($this);
}
/**
* Render the benchmark
*
* @return string Benchmark HTML
*/
protected function renderBenchmark()
{
$this->viewRenderer->postDispatch();
Benchmark::measure('Response ready');
return Benchmark::renderToHtml()/*
. '<pre style="height: 16em; vertical-overflow: scroll">'
. print_r(get_included_files(), 1)
. '</pre>'*/;
}
public function isXhr()
{
return $this->getRequest()->isXmlHttpRequest();
}
protected function redirectHttp($url)
{
if (! $url instanceof Url) {
$url = Url::fromPath($url);
}
$this->shutdownSession();
$this->_helper->Redirector->gotoUrlAndExit($url->getRelativeUrl());
}
/**
* Redirect to a specific url, updating the browsers URL field
*
* @param Url|string $url The target to redirect to
**/
public function redirectNow($url)
{
if ($this->isXhr()) {
$this->redirectXhr($url);
} else {
$this->redirectHttp($url);
}
}
protected function shutdownSession()
{
$session = Session::getSession();
if ($session->hasChanged()) {
$session->write();
}
}
protected function rerenderLayout()
{
$this->rerenderLayout = true;
$this->xhrLayout = 'layout';
return $this;
}
protected function reloadCss()
{
$this->reloadCss = true;
return $this;
}
}

View File

@ -0,0 +1,40 @@
<?php
namespace ipl\Web\Component;
use ipl\Html\Attributes;
use ipl\Html\BaseElement;
use ipl\Html\Element;
use ipl\Html\Html;
class AbstractList extends BaseElement
{
protected $contentSeparator = "\n";
/**
* AbstractList constructor.
* @param array $items
* @param null $attributes
*/
public function __construct(array $items = [], $attributes = null)
{
foreach ($items as $item) {
$this->addItem($item);
}
if ($attributes !== null) {
$this->addAttributes($attributes);
}
}
/**
* @param Html|array|string $content
* @param Attributes|array $attributes
*
* @return $this
*/
public function addItem($content, $attributes = null)
{
return $this->add(Element::create('li', $attributes, $content));
}
}

View File

@ -0,0 +1,15 @@
<?php
namespace ipl\Web\Component;
use ipl\Html\BaseElement;
class ActionBar extends BaseElement
{
protected $contentSeparator = ' ';
/** @var string */
protected $tag = 'div';
protected $defaultAttributes = array('class' => 'action-bar');
}

View File

@ -0,0 +1,12 @@
<?php
namespace ipl\Web\Component;
use ipl\Html\Container;
class Content extends Container
{
protected $contentSeparator = "\n";
protected $defaultAttributes = array('class' => 'content');
}

View File

@ -0,0 +1,107 @@
<?php
namespace ipl\Web\Component;
use ipl\Html\Container;
use ipl\Html\Html;
class Controls extends Container
{
protected $contentSeparator = "\n";
protected $defaultAttributes = array('class' => 'controls');
/** @var Tabs */
private $tabs;
/** @var ActionBar */
private $actions;
/** @var string */
private $title;
/** @var string */
private $subTitle;
/**
* @param $title
* @param null $subTitle
* @return $this
*/
public function addTitle($title, $subTitle = null)
{
$this->title = $title;
if ($subTitle !== null) {
$this->subTitle = $subTitle;
}
return $this->add($this->renderTitleElement());
}
/**
* @return Tabs
*/
public function getTabs()
{
if ($this->tabs === null) {
$this->tabs = new Tabs();
}
return $this->tabs;
}
/**
* @param Tabs $tabs
* @return $this
*/
public function setTabs(Tabs $tabs)
{
$this->tabs = $tabs;
return $this;
}
/**
* @return Html
*/
public function getActionBar()
{
if ($this->actions === null) {
$this->setActionBar(new ActionBar());
}
return $this->actions;
}
public function setActionBar(Html $actionBar)
{
if ($this->actions !== null) {
$this->remove($this->actions);
}
$this->actions = $actionBar;
$this->add($actionBar);
return $this;
}
protected function renderTitleElement()
{
$h1 = Html::tag('h1')->setContent($this->title);
if ($this->subTitle) {
$h1->setSeparator(' ')->add(
Html::tag('small', null, $this->subTitle)
);
}
return $h1;
}
public function renderContent()
{
if (null !== $this->tabs) {
$this->prepend($this->tabs);
}
return parent::renderContent();
}
}

View File

@ -0,0 +1,59 @@
<?php
namespace ipl\Web\Component;
use ipl\Html\Html;
use ipl\Web\Url;
interface ControlsAndContent
{
/**
* @return Controls
*/
public function controls();
/**
* @return Tabs
*/
public function tabs();
/**
* @return Html
*/
public function actions(Html $actionBar = null);
/**
* @return Content
*/
public function content();
/**
* @param $title
* @return $this
*/
public function setTitle($title);
/**
* @param $title
* @return $this
*/
public function addTitle($title);
/**
* @param $title
* @param null $url
* @param string $name
* @return $this
*/
public function addSingleTab($title, $url = null, $name = 'main');
/**
* @return Url
*/
public function url();
/**
* @return Url
*/
public function getOriginalUrl();
}

View File

@ -0,0 +1,26 @@
<?php
namespace ipl\Web\Component;
use ipl\Html\Attributes;
use ipl\Html\BaseElement;
use ipl\Html\Element;
use ipl\Html\Html;
class ListItem extends BaseElement
{
protected $contentSeparator = "\n";
/**
* @param Html|array|string $content
* @param Attributes|array $attributes
*
* @return $this
*/
public function addItem($content, $attributes = null)
{
return $this->add(
Element::create('li', $content, $attributes)
);
}
}

View File

@ -0,0 +1,8 @@
<?php
namespace ipl\Web\Component;
class OrderedList extends AbstractList
{
protected $tag = 'ol';
}

View File

@ -0,0 +1,464 @@
<?php
namespace ipl\Web\Component;
use Icinga\Exception\ProgrammingError;
use ipl\Data\Paginatable;
use ipl\Html\BaseElement;
use ipl\Html\Html;
use ipl\Html\Icon;
use ipl\Html\Link;
use ipl\Translation\TranslationHelper;
use ipl\Web\Url;
class Paginator extends BaseElement
{
use TranslationHelper;
protected $tag = 'div';
protected $defaultAttributes = [
'class' => 'pagination-control',
'role' => 'navigation',
];
/** @var Paginatable The query the paginator widget is created for */
protected $query;
/** @var int */
protected $pageCount;
/** @var int */
protected $currentCount;
/** @var Url */
protected $url;
/** @var string */
protected $pageParam;
/** @var string */
protected $perPageParam;
/** @var int */
protected $totalCount;
/** @var int */
protected $defaultItemCountPerPage = 25;
public function __construct(
Paginatable $query,
Url $url,
$pageParameter = 'page',
$perPageParameter = 'limit'
) {
$this->query = $query;
$this->setPageParam($pageParameter);
$this->setPerPageParam($perPageParameter);
$this->setUrl($url);
}
public function setItemsPerPage($count)
{
// TODO: this should become setOffset once available
$query = $this->getQuery();
$query->setLimit($count);
return $this;
}
protected function setPageParam($pageParam)
{
$this->pageParam = $pageParam;
return $this;
}
protected function setPerPageParam($perPageParam)
{
$this->perPageParam = $perPageParam;
return $this;
}
public function getPageParam()
{
return $this->pageParam;
}
public function getPerPageParam()
{
return $this->perPageParam;
}
public function getCurrentPage()
{
$query = $this->getQuery();
if ($query->hasOffset()) {
return ($query->getOffset() / $this->getItemsPerPage()) + 1;
} else {
return 1;
}
}
protected function setCurrentPage($page)
{
$page = (int) $page;
$this->currentPage = $page;
$offset = $this->firstRowOnPage($page) - 1;
if ($page > 1) {
$query = $this->getQuery();
$query->setOffset($offset);
}
}
public function getPageCount()
{
if ($this->pageCount === null) {
$this->pageCount = (int) ceil($this->getTotalItemCount() / $this->getItemsPerPage());
}
return $this->pageCount;
}
protected function getItemsPerPage()
{
$limit = $this->getQuery()->getLimit();
if ($limit === null) {
throw new ProgrammingError('Something went wrong, got no limit when there should be one');
} else {
return $limit;
}
}
public function getTotalItemCount()
{
if ($this->totalCount === null) {
$this->totalCount = count($this->getQuery());
}
return $this->totalCount;
}
public function getPrevious()
{
if ($this->hasPrevious()) {
return $this->getCurrentPage() - 1;
} else {
return null;
}
}
public function hasPrevious()
{
return $this->getCurrentPage() > 1;
}
public function getNext()
{
if ($this->hasNext()) {
return $this->getCurrentPage() + 1;
} else {
return null;
}
}
public function hasNext()
{
return $this->getCurrentPage() < $this->getPageCount();
}
public function getQuery()
{
return $this->query;
}
/**
* Returns an array of "local" pages given the page count and current page number
*
* @return array
*/
protected function getPages()
{
$page = $this->getPageCount();
$current = $this->getCurrentPage();
$range = [];
if ($page < 10) {
// Show all pages if we have less than 10
for ($i = 1; $i < 10; $i++) {
if ($i > $page) {
break;
}
$range[$i] = $i;
}
} else {
// More than 10 pages:
foreach ([1, 2] as $i) {
$range[$i] = $i;
}
if ($current < 6) {
// We are on page 1-5 from
for ($i = 1; $i <= 7; $i++) {
$range[$i] = $i;
}
} else {
// Current page > 5
$range[] = '…';
if (($page - $current) < 5) {
// Less than 5 pages left
$start = 5 - ($page - $current);
} else {
$start = 1;
}
for ($i = $current - $start; $i < ($current + (4 - $start)); $i++) {
if ($i > $page) {
break;
}
$range[$i] = $i;
}
}
if ($current < ($page - 2)) {
$range[] = '…';
}
foreach ([$page - 1, $page] as $i) {
$range[$i] = $i;
}
}
if (empty($range)) {
$range[] = 1;
}
return $range;
}
public function getDefaultItemCountPerPage()
{
return $this->defaultItemCountPerPage;
}
public function setDefaultItemCountPerPage($count)
{
$this->defaultItemCountPerPage = (int) $count;
return $this;
}
public function setUrl(Url $url)
{
$page = (int) $url->shift($this->getPageParam());
$perPage = (int) $url->getParam($this->getPerPageParam());
if ($perPage > 0) {
$this->setItemsPerPage($perPage);
} else {
$this->setItemsPerPage($this->getDefaultItemCountPerPage());
}
if ($page > 0) {
$this->setCurrentPage($page);
}
$this->url = $url;
return $this;
}
public function getUrl()
{
if ($this->url === null) {
$this->setUrl(Url::fromRequest());
}
return $this->url;
}
public function getPreviousLabel()
{
return $this->getLabel($this->getCurrentPage() - 1);
}
protected function getNextLabel()
{
return $this->getLabel($this->getCurrentPage() + 1);
}
protected function getLabel($page)
{
return sprintf(
$this->translate('Show rows %u to %u of %u'),
$this->firstRowOnPage($page),
$this->lastRowOnPage($page),
$this->getTotalItemCount()
);
}
protected function renderPrevious()
{
return Html::tag('li', [
'class' => 'nav-item'
], Link::create(
Icon::create('angle-double-left'),
$this->makeUrl($this->getPrevious()),
null,
[
'title' => $this->getPreviousLabel(),
'class' => 'previous-page'
]
));
}
protected function renderNoPrevious()
{
return $this->renderDisabled(Html::tag('span', [
'class' => 'previous-page'
], [
$this->srOnly($this->translate('Previous page')),
Icon::create('angle-double-left')
]));
}
protected function renderNext()
{
return Html::tag('li', [
'class' => 'nav-item'
], Link::create(
Icon::create('angle-double-right'),
$this->makeUrl($this->getNext()),
null,
[
'title' => $this->getNextLabel(),
'class' => 'next-page'
]
));
}
protected function renderNoNext()
{
return $this->renderDisabled(Html::tag('span', [
'class' => 'previous-page'
], [
$this->srOnly($this->translate('Next page')),
Icon::create('angle-double-right')
]));
}
protected function renderDots()
{
return $this->renderDisabled(Html::tag('span', null, '…'));
}
protected function renderInnerPages()
{
$pages = [];
$current = $this->getCurrentPage();
foreach ($this->getPages() as $page) {
if ($page === '…') {
$pages[] = $this->renderDots();
} else {
$pages[] = Html::tag(
'li',
$page === $current ? ['class' => 'active'] : null,
$this->makeLink($page)
);
}
}
return $pages;
}
protected function lastRowOnPage($page)
{
$perPage = $this->getItemsPerPage();
$total = $this->getTotalItemCount();
$last = $page * $perPage;
if ($last > $total) {
$last = $total;
}
return $last;
}
protected function firstRowOnPage($page)
{
return ($page - 1) * $this->getItemsPerPage() + 1;
}
protected function makeLink($page)
{
return Link::create(
$page,
$this->makeUrl($page),
null,
['title' => $this->getLabel($page)]
);
}
protected function makeUrl($page)
{
if ($page) {
return $this->getUrl()->with('page', $page);
} else {
return $this->getUrl();
}
}
protected function srOnly($content)
{
return Html::tag('span', ['class' => 'sr-only'], $content);
}
protected function renderDisabled($content)
{
return Html::tag('li', [
'class' => ['nav-item', 'disabled'],
'aria-hidden' => 'true'
], $content);
}
protected function renderList()
{
return Html::tag(
'ul',
['class' => ['nav', 'tab-nav']],
[
$this->hasPrevious() ? $this->renderPrevious() : $this->renderNoPrevious(),
$this->renderInnerPages(),
$this->hasNext() ? $this->renderNext() : $this->renderNoNext()
]
);
}
public function renderContent()
{
$this->add([
$this->renderScreenReaderHeader(),
$this->renderList()
]);
return parent::renderContent();
}
protected function renderScreenReaderHeader()
{
return Html::tag('h2', [
// 'id' => $this->protectId('pagination') -> why?
'class' => 'sr-only',
'tab-index' => '-1'
], $this->translate('Pagination'));
}
public function render()
{
if ($this->getPageCount() < 2) {
return '';
} else {
return parent::render();
}
}
}

View File

@ -0,0 +1,10 @@
<?php
namespace ipl\Web\Component;
use Icinga\Web\Widget\Tabs as WebTabs;
use ipl\Html\ValidHtml;
class Tabs extends WebTabs implements ValidHtml
{
}

View File

@ -0,0 +1,8 @@
<?php
namespace ipl\Web\Component;
class UnorderedList extends AbstractList
{
protected $tag = 'ul';
}

View File

@ -0,0 +1,170 @@
<?php
namespace ipl\Web\Controller\Extension;
use ipl\Html\Html;
use ipl\Web\Component\Content;
use ipl\Web\Component\Controls;
use ipl\Web\Component\Tabs;
use ipl\Web\Url;
trait ControlsAndContentHelper
{
/** @var Controls */
private $controls;
/** @var Content */
private $content;
protected $title;
/** @var Url */
private $url;
/** @var Url */
private $originalUrl;
/**
* TODO: Not sure whether we need dedicated Content/Controls classes,
* a simple Container with a class name might suffice here
*
* @return Controls
*/
public function controls()
{
if ($this->controls === null) {
$this->view->controls = $this->controls = Controls::create();
}
return $this->controls;
}
/**
* @return Tabs
*/
public function tabs(Tabs $tabs = null)
{
if ($tabs === null) {
return $this->controls()->getTabs();
} else {
$this->controls()->setTabs($tabs);
return $tabs;
}
}
/**
* @param Html|null $actionBar
* @return Html
*/
public function actions(Html $actionBar = null)
{
if ($actionBar === null) {
return $this->controls()->getActionBar();
} else {
$this->controls()->setActionBar($actionBar);
return $actionBar;
}
}
/**
* @return Content
*/
public function content()
{
if ($this->content === null) {
$this->view->content = $this->content = Content::create();
}
return $this->content;
}
/**
* @param $title
* @return $this
*/
public function setTitle($title)
{
$this->title = $this->makeTitle(func_get_args());
return $this;
}
/**
* @param $title
* @return $this
*/
public function addTitle($title)
{
$title = $this->makeTitle(func_get_args());
$this->title = $title;
$this->controls()->addTitle($title);
return $this;
}
private function makeTitle($args)
{
$title = array_shift($args);
if (empty($args)) {
return $title;
} else {
return vsprintf($title, $args);
}
}
/**
* @param $title
* @param null $url
* @param string $name
* @return $this
*/
public function addSingleTab($title, $url = null, $name = 'main')
{
if ($url === null) {
$url = $this->url();
}
$this->tabs()->add($name, [
'label' => $title,
'url' => $url,
])->activate($name);
return $this;
}
/**
* @return Url
*/
public function url()
{
if ($this->url === null) {
$this->url = $this->getOriginalUrl();
}
return $this->url;
}
/**
* @return Url
*/
public function getOriginalUrl()
{
if ($this->originalUrl === null) {
$this->originalUrl = clone($this->getUrlFromRequest());
}
return clone($this->originalUrl);
}
/**
* @return Url
*/
protected function getUrlFromRequest()
{
$webUrl = $this->getRequest()->getUrl();
return Url::fromPath(
$webUrl->getPath()
)->setParams($webUrl->getParams());
}
}

32
library/vendor/ipl/Web/FakeRequest.php vendored Normal file
View File

@ -0,0 +1,32 @@
<?php
namespace ipl\Web;
use Icinga\Exception\ProgrammingError;
use Icinga\Web\Request;
class FakeRequest extends Request
{
/** @var string */
private static $baseUrl;
public static function setConfiguredBaseUrl($url)
{
self::$baseUrl = $url;
}
public function setUrl(Url $url)
{
$this->url = $url;
return $this;
}
public function getBaseUrl($raw = false)
{
if (self::$baseUrl === null) {
throw new ProgrammingError('Cannot determine base URL on CLI if not configured');
} else {
return self::$baseUrl;
}
}
}

117
library/vendor/ipl/Web/Url.php vendored Normal file
View File

@ -0,0 +1,117 @@
<?php
namespace ipl\Web;
use Icinga\Application\Icinga;
use Icinga\Exception\ProgrammingError;
use Icinga\Web\Url as WebUrl;
use Icinga\Web\UrlParams;
/**
* Class Url
*
* The main purpose of this class is to get unit tests running on CLI
* Little code from Icinga\Web\Url has been duplicated, as neither fromPath()
* nor getRequest() can be extended in a meaningful way at the time of this
* writing
*
* @package ipl\Web
*/
class Url extends WebUrl
{
public static function fromPath($url, array $params = array(), $request = null)
{
if ($request === null) {
$request = static::getRequest();
}
if (! is_string($url)) {
throw new ProgrammingError(
'url "%s" is not a string',
$url
);
}
$self = new static;
if ($url === '#') {
return $self->setPath($url);
}
$parts = parse_url($url);
$self->setBasePath($request->getBaseUrl());
if (isset($parts['path'])) {
$self->setPath($parts['path']);
}
if (isset($parts['query'])) {
$params = UrlParams::fromQueryString($parts['query'])->mergeValues($params);
}
if (isset($parts['fragment'])) {
$self->setAnchor($parts['fragment']);
}
$self->setParams($params);
return $self;
}
/**
* Create a new Url class representing the current request
*
* If $params are given, those will be added to the request's parameters
* and overwrite any existing parameters
*
* @param UrlParams|array $params Parameters that should additionally be considered for the url
* @param \Icinga\Web\Request $request A request to use instead of the default one
*
* @return Url
*/
public static function fromRequest($params = array(), $request = null)
{
if ($request === null) {
$request = static::getRequest();
}
$url = new Url();
$url->setPath(ltrim($request->getPathInfo(), '/'));
$request->getQuery();
// $urlParams = UrlParams::fromQueryString($request->getQuery());
if (isset($_SERVER['QUERY_STRING'])) {
$urlParams = UrlParams::fromQueryString($_SERVER['QUERY_STRING']);
} else {
$urlParams = UrlParams::fromQueryString('');
foreach ($request->getQuery() as $k => $v) {
$urlParams->set($k, $v);
}
}
foreach ($params as $k => $v) {
$urlParams->set($k, $v);
}
$url->setParams($urlParams);
$url->setBasePath($request->getBaseUrl());
return $url;
}
public function setBasePath($basePath)
{
if (property_exists($this, 'basePath')) {
parent::setBasePath($basePath);
} else {
return $this->setBaseUrl($basePath);
}
}
protected static function getRequest()
{
$app = Icinga::app();
if ($app->isCli()) {
return new FakeRequest();
} else {
return $app->getRequest();
}
}
}

View File

@ -0,0 +1,67 @@
<?php
namespace ipl\Zf1;
use Icinga\Application\Icinga;
use ipl\Html\ValidHtml;
use Zend_Controller_Action_Helper_Abstract as Helper;
use Zend_Controller_Action_HelperBroker as HelperBroker;
class SimpleViewRenderer extends Helper implements ValidHtml
{
private $disabled = false;
private $rendered = false;
public $view;
public function disable($disabled = true)
{
$this->disabled = $disabled;
return $this;
}
public function replaceZendViewRenderer()
{
/** @var \Zend_Controller_Action_Helper_ViewRenderer $viewRenderer */
$viewRenderer = Icinga::app()->getViewRenderer();
$viewRenderer->setNeverRender();
$viewRenderer->setNeverController();
HelperBroker::removeHelper('viewRenderer');
HelperBroker::addHelper($this);
$this->view = $viewRenderer->view;
return $this;
}
public function render($action = null, $name = null, $noController = null)
{
if (null === $name) {
$name = null; // $this->getResponseSegment();
}
$this->getResponse()->appendBody(
$this->view->controls . $this->view->content,
$name
);
// $this->setNoRender();
$this->rendered = true;
}
public function shouldRender()
{
return ! $this->disabled && ! $this->rendered;
}
public function postDispatch()
{
if ($this->shouldRender()) {
$this->render();
}
}
public function getName()
{
return 'ViewRenderer';
}
}

14
run.php
View File

@ -1,6 +1,7 @@
<?php
use Icinga\Application\Icinga;
use ipl\Loader\CompatLoader;
$prefix = '\\Icinga\\Module\\Director\\';
@ -48,3 +49,16 @@ $this->provideHook('director/Job', $prefix . 'Job\\ImportJob');
$this->provideHook('director/Job', $prefix . 'Job\\SyncJob');
$this->provideHook('cube/Actions', 'CubeLinks');
// ipl compat, unless it is released:
if (class_exists('ipl\\Html\\ValidHtml')) {
return;
}
if ($this->app->getModuleManager()->hasEnabled('ipl')) {
return;
}
require_once __DIR__ . '/library/vendor/ipl/Loader/CompatLoader.php';
CompatLoader::delegateLoadingToIcingaWeb($this->app);