dipl: align with ipl-html, stop using deprecated
...method Html::escapeForHtml
This commit is contained in:
parent
ec0beb5de8
commit
5a8c785b7c
|
@ -46,7 +46,7 @@ class SuggestController extends ActionController
|
|||
$matches[] = $this->highlight($str, $search);
|
||||
}
|
||||
} else {
|
||||
$matches[] = Html::escapeForHtml($str);
|
||||
$matches[] = Html::escape($str);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -260,7 +260,7 @@ class SuggestController extends ActionController
|
|||
protected function highlight($val, $search)
|
||||
{
|
||||
$search = ($search);
|
||||
$val = Html::escapeForHtml($val);
|
||||
$val = Html::escape($val);
|
||||
return preg_replace(
|
||||
'/(' . preg_quote($search, '/') . ')/i',
|
||||
'<strong>\1</strong>',
|
||||
|
|
|
@ -64,7 +64,7 @@ abstract class Dashboard extends HtmlDocument
|
|||
$this->add(Html::tag(
|
||||
'p',
|
||||
null,
|
||||
HtmlString::create(nl2br(Html::escapeForHtml($description)))
|
||||
HtmlString::create(nl2br(Html::escape($description)))
|
||||
));
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ class StartupLogRenderer implements ValidHtml
|
|||
public function render()
|
||||
{
|
||||
$deployment = $this->deployment;
|
||||
$log = Html::escapeForHtml($deployment->get('startup_log'));
|
||||
$log = Html::escape($deployment->get('startup_log'));
|
||||
$lines = array();
|
||||
$severity = 'information';
|
||||
$sevPattern = '/^(debug|notice|information|warning|critical)\/(\w+)/';
|
||||
|
|
|
@ -34,7 +34,7 @@ class ShowConfigFile extends HtmlDocument
|
|||
*/
|
||||
protected function assemble()
|
||||
{
|
||||
$source = $this->linkObjects(Html::escapeForHtml($this->file->getContent()));
|
||||
$source = $this->linkObjects(Html::escape($this->file->getContent()));
|
||||
if ($this->highlight) {
|
||||
$source = $this->highlight(
|
||||
$source,
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace dipl\Html;
|
||||
|
||||
use Icinga\Exception\ProgrammingError;
|
||||
use InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* HTML Attribute
|
||||
|
@ -27,7 +27,7 @@ class Attribute
|
|||
*
|
||||
* @param $name
|
||||
* @param $value
|
||||
* @throws ProgrammingError
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function __construct($name, $value = null)
|
||||
{
|
||||
|
@ -38,7 +38,7 @@ class Attribute
|
|||
* @param $name
|
||||
* @param $value
|
||||
* @return static
|
||||
* @throws ProgrammingError
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public static function create($name, $value)
|
||||
{
|
||||
|
@ -56,15 +56,15 @@ class Attribute
|
|||
/**
|
||||
* @param $name
|
||||
* @return $this
|
||||
* @throws ProgrammingError
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function setName($name)
|
||||
{
|
||||
if (! preg_match('/^[a-z][a-z0-9:-]*$/i', $name)) {
|
||||
throw new ProgrammingError(
|
||||
throw new InvalidArgumentException(sprintf(
|
||||
'Attribute names with special characters are not yet allowed: %s',
|
||||
$name
|
||||
);
|
||||
));
|
||||
}
|
||||
$this->name = $name;
|
||||
|
||||
|
@ -160,7 +160,7 @@ class Attribute
|
|||
/**
|
||||
* @param $name
|
||||
* @return static
|
||||
* @throws ProgrammingError
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public static function createEmpty($name)
|
||||
{
|
||||
|
@ -185,9 +185,9 @@ class Attribute
|
|||
{
|
||||
// TODO: escape differently
|
||||
if (is_array($value)) {
|
||||
return Html::escapeForHtml(implode(' ', $value));
|
||||
return Html::escape(implode(' ', $value));
|
||||
} else {
|
||||
return Html::escapeForHtml((string) $value);
|
||||
return Html::escape((string) $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,8 +2,7 @@
|
|||
|
||||
namespace dipl\Html;
|
||||
|
||||
use Icinga\Exception\IcingaException;
|
||||
use Icinga\Exception\ProgrammingError;
|
||||
use InvalidArgumentException;
|
||||
|
||||
class Attributes
|
||||
{
|
||||
|
@ -22,7 +21,7 @@ class Attributes
|
|||
/**
|
||||
* Attributes constructor.
|
||||
* @param Attribute[] $attributes
|
||||
* @throws ProgrammingError
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function __construct(array $attributes = null)
|
||||
{
|
||||
|
@ -44,7 +43,7 @@ class Attributes
|
|||
/**
|
||||
* @param Attribute[] $attributes
|
||||
* @return static
|
||||
* @throws ProgrammingError
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public static function create(array $attributes = null)
|
||||
{
|
||||
|
@ -54,7 +53,7 @@ class Attributes
|
|||
/**
|
||||
* @param Attributes|array|null $attributes
|
||||
* @return Attributes
|
||||
* @throws IcingaException
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public static function wantAttributes($attributes)
|
||||
{
|
||||
|
@ -69,10 +68,10 @@ class Attributes
|
|||
|
||||
return $self;
|
||||
} elseif ($attributes !== null) {
|
||||
throw new IcingaException(
|
||||
throw new InvalidArgumentException(sprintf(
|
||||
'Attributes, Array or Null expected, got %s',
|
||||
Html::getPhpTypeName($attributes)
|
||||
);
|
||||
));
|
||||
}
|
||||
return $self;
|
||||
}
|
||||
|
@ -90,7 +89,7 @@ class Attributes
|
|||
* @param Attribute|string $attribute
|
||||
* @param string|array $value
|
||||
* @return $this
|
||||
* @throws ProgrammingError
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function add($attribute, $value = null)
|
||||
{
|
||||
|
@ -121,7 +120,7 @@ class Attributes
|
|||
* @param Attribute|array|string $attribute
|
||||
* @param string|array $value
|
||||
* @return $this
|
||||
* @throws ProgrammingError
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function set($attribute, $value = null)
|
||||
{
|
||||
|
@ -154,7 +153,7 @@ class Attributes
|
|||
/**
|
||||
* @param $name
|
||||
* @return Attribute
|
||||
* @throws ProgrammingError
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function get($name)
|
||||
{
|
||||
|
@ -226,20 +225,20 @@ class Attributes
|
|||
* @param callable $callback
|
||||
* @param callable $setterCallback
|
||||
* @return $this
|
||||
* @throws ProgrammingError
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function registerAttributeCallback($name, $callback, $setterCallback = null)
|
||||
{
|
||||
if ($callback !== null) {
|
||||
if (! is_callable($callback)) {
|
||||
throw new ProgrammingError(__METHOD__ . ' expects a callable callback');
|
||||
throw new InvalidArgumentException(__METHOD__ . ' expects a callable callback');
|
||||
}
|
||||
$this->callbacks[$name] = $callback;
|
||||
}
|
||||
|
||||
if ($setterCallback !== null) {
|
||||
if (! is_callable($setterCallback)) {
|
||||
throw new ProgrammingError(__METHOD__ . ' expects a callable setterCallback');
|
||||
throw new InvalidArgumentException(__METHOD__ . ' expects a callable setterCallback');
|
||||
}
|
||||
$this->setterCallbacks[$name] = $setterCallback;
|
||||
}
|
||||
|
@ -249,7 +248,7 @@ class Attributes
|
|||
|
||||
/**
|
||||
* @return string
|
||||
* @throws ProgrammingError
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function render()
|
||||
{
|
||||
|
@ -265,7 +264,7 @@ class Attributes
|
|||
} elseif (null === $attribute) {
|
||||
continue;
|
||||
} else {
|
||||
throw new ProgrammingError(
|
||||
throw new InvalidArgumentException(
|
||||
'A registered attribute callback must return string, null'
|
||||
. ' or an Attribute'
|
||||
);
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
namespace dipl\Html;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
abstract class BaseHtmlElement extends HtmlDocument
|
||||
{
|
||||
/** @var array You may want to set default attributes when extending this class */
|
||||
|
@ -13,31 +15,40 @@ abstract class BaseHtmlElement extends HtmlDocument
|
|||
/** @var string */
|
||||
protected $tag;
|
||||
|
||||
protected $hasBeenAssembled = false;
|
||||
|
||||
/**
|
||||
* List of void elements which must not contain end tags or content
|
||||
*
|
||||
* If {@link $isVoid} is null, this property should be used to decide whether the content and end tag has to be
|
||||
* rendered.
|
||||
*
|
||||
* @var array
|
||||
*
|
||||
* @see https://www.w3.org/TR/html5/syntax.html#void-elements
|
||||
*/
|
||||
protected static $voidElements = [
|
||||
'area',
|
||||
'base',
|
||||
'br',
|
||||
'col',
|
||||
'embed',
|
||||
'hr',
|
||||
'img',
|
||||
'input',
|
||||
'link',
|
||||
'meta',
|
||||
'param',
|
||||
'source',
|
||||
'track',
|
||||
'wbr'
|
||||
'area' => 1,
|
||||
'base' => 1,
|
||||
'br' => 1,
|
||||
'col' => 1,
|
||||
'embed' => 1,
|
||||
'hr' => 1,
|
||||
'img' => 1,
|
||||
'input' => 1,
|
||||
'link' => 1,
|
||||
'meta' => 1,
|
||||
'param' => 1,
|
||||
'source' => 1,
|
||||
'track' => 1,
|
||||
'wbr' => 1
|
||||
];
|
||||
|
||||
/** @var bool|null Whether the element is void. If null, void check should use {@link $voidElements} */
|
||||
protected $isVoid;
|
||||
|
||||
/**
|
||||
* @return Attributes
|
||||
* @throws \Icinga\Exception\IcingaException
|
||||
* @throws \Icinga\Exception\ProgrammingError
|
||||
* Get the attributes of the element
|
||||
*
|
||||
* @return Attributes
|
||||
*/
|
||||
public function getAttributes()
|
||||
{
|
||||
|
@ -54,9 +65,11 @@ abstract class BaseHtmlElement extends HtmlDocument
|
|||
}
|
||||
|
||||
/**
|
||||
* @param Attributes|array|null $attributes
|
||||
* @return $this
|
||||
* @throws \Icinga\Exception\IcingaException
|
||||
* Set the attributes of the element
|
||||
*
|
||||
* @param Attributes|array|null $attributes
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setAttributes($attributes)
|
||||
{
|
||||
|
@ -66,24 +79,28 @@ abstract class BaseHtmlElement extends HtmlDocument
|
|||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @return $this
|
||||
* @throws \Icinga\Exception\ProgrammingError
|
||||
* @throws \Icinga\Exception\IcingaException
|
||||
* Set the attribute with the given name and value
|
||||
*
|
||||
* If the attribute with the given name already exists, it gets overridden.
|
||||
*
|
||||
* @param string $name The name of the attribute
|
||||
* @param string|bool|array $value The value of the attribute
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setAttribute($key, $value)
|
||||
public function setAttribute($name, $value)
|
||||
{
|
||||
$this->getAttributes()->set($key, $value);
|
||||
$this->getAttributes()->set($name, $value);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Attributes|array|null $attributes
|
||||
* @return $this
|
||||
* @throws \Icinga\Exception\ProgrammingError
|
||||
* @throws \Icinga\Exception\IcingaException
|
||||
* Add the given attributes
|
||||
*
|
||||
* @param Attributes|array $attributes
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addAttributes($attributes)
|
||||
{
|
||||
|
@ -93,13 +110,54 @@ abstract class BaseHtmlElement extends HtmlDocument
|
|||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
* Get the default attributes of the element
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getDefaultAttributes()
|
||||
{
|
||||
return $this->defaultAttributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the tag of the element
|
||||
*
|
||||
* Since HTML Elements must have a tag, this method throws an exception if the element does not have a tag.
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @throws RuntimeException If the element does not have a tag
|
||||
*/
|
||||
final public function getTag()
|
||||
{
|
||||
$tag = $this->tag();
|
||||
|
||||
if (! strlen($tag)) {
|
||||
throw new RuntimeException('Element must have a tag');
|
||||
}
|
||||
|
||||
return $tag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal method for accessing the tag
|
||||
*
|
||||
* You may override this method in order to provide the tag dynamically
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function tag()
|
||||
{
|
||||
return $this->tag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the tag of the element
|
||||
*
|
||||
* @param string $tag
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setTag($tag)
|
||||
{
|
||||
$this->tag = $tag;
|
||||
|
@ -107,21 +165,16 @@ abstract class BaseHtmlElement extends HtmlDocument
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function getTag()
|
||||
{
|
||||
return $this->tag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the content of the element to HTML
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function renderContent()
|
||||
{
|
||||
return parent::renderUnwrapped();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|ValidHtml|string $content
|
||||
* @return $this
|
||||
* @throws \Icinga\Exception\IcingaException
|
||||
*/
|
||||
public function add($content)
|
||||
{
|
||||
$this->ensureAssembled();
|
||||
|
@ -132,50 +185,41 @@ abstract class BaseHtmlElement extends HtmlDocument
|
|||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* @throws \Icinga\Exception\ProgrammingError
|
||||
* @throws \Icinga\Exception\IcingaException
|
||||
* @inheritdoc
|
||||
*
|
||||
* @throws RuntimeException If the element does not have a tag or is void but has content
|
||||
*/
|
||||
public function renderUnwrapped()
|
||||
{
|
||||
$this->ensureAssembled();
|
||||
|
||||
$tag = $this->getTag();
|
||||
|
||||
$attributes = $this->getAttributes()->render();
|
||||
$content = $this->renderContent();
|
||||
if (strlen($content) || $this->wantsClosingTag()) {
|
||||
return sprintf(
|
||||
'<%s%s>%s</%s>',
|
||||
$tag,
|
||||
$this->renderAttributes(),
|
||||
$content,
|
||||
$tag
|
||||
);
|
||||
} else {
|
||||
return sprintf(
|
||||
'<%s%s />',
|
||||
$tag,
|
||||
$this->renderAttributes()
|
||||
);
|
||||
|
||||
if (! $this->wantsClosingTag()) {
|
||||
if (strlen($content)) {
|
||||
throw new RuntimeException('Void elements must not have content');
|
||||
}
|
||||
|
||||
return sprintf('<%s%s />', $tag, $attributes);
|
||||
}
|
||||
|
||||
return sprintf(
|
||||
'<%s%s>%s</%s>',
|
||||
$tag,
|
||||
$attributes,
|
||||
$content,
|
||||
$tag
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* @throws \Icinga\Exception\ProgrammingError
|
||||
* @throws \Icinga\Exception\IcingaException
|
||||
*/
|
||||
public function renderAttributes()
|
||||
{
|
||||
if ($this->attributes === null && empty($this->defaultAttributes)) {
|
||||
return '';
|
||||
} else {
|
||||
return $this->getAttributes()->render();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param HtmlDocument $document
|
||||
* @return $this
|
||||
* Use this element to wrap the given document
|
||||
*
|
||||
* @param HtmlDocument $document
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function wrap(HtmlDocument $document)
|
||||
{
|
||||
|
@ -184,36 +228,54 @@ abstract class BaseHtmlElement extends HtmlDocument
|
|||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get whether the closing tag should be rendered
|
||||
*
|
||||
* @return bool True for void elements, false otherwise
|
||||
*/
|
||||
public function wantsClosingTag()
|
||||
{
|
||||
// TODO: There is more. SVG and MathML namespaces
|
||||
return ! $this->isVoidElement();
|
||||
}
|
||||
|
||||
public function isVoidElement()
|
||||
{
|
||||
if ($this->isVoid === null) {
|
||||
$this->isVoid = in_array($this->tag, self::$voidElements);
|
||||
}
|
||||
|
||||
return $this->isVoid;
|
||||
}
|
||||
|
||||
public function setVoid($void = true)
|
||||
{
|
||||
$this->isVoid = $void;
|
||||
|
||||
return $this;
|
||||
return ! $this->isVoid();
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the given something can be rendered
|
||||
* Get whether the element is void
|
||||
*
|
||||
* @param mixed $any
|
||||
* @return bool
|
||||
* The default void detection which checks whether the element's tag is in the list of void elements according to
|
||||
* https://www.w3.org/TR/html5/syntax.html#void-elements.
|
||||
*
|
||||
* If you want to override this behavior, use {@link setVoid()}.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function canBeRendered($any)
|
||||
public function isVoid()
|
||||
{
|
||||
return is_string($any) || is_int($any) || is_null($any);
|
||||
if ($this->isVoid !== null) {
|
||||
return $this->isVoid;
|
||||
}
|
||||
|
||||
$tag = $this->getTag();
|
||||
|
||||
return isset(self::$voidElements[$tag]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether the element is void
|
||||
*
|
||||
* You may use this method to override the default void detection which checks whether the element's tag is in the
|
||||
* list of void elements according to https://www.w3.org/TR/html5/syntax.html#void-elements.
|
||||
*
|
||||
* If you specify null, void detection is reset to its default behavior.
|
||||
*
|
||||
* @param bool|null $void
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setVoid($void = true)
|
||||
{
|
||||
$this->isVoid = $void === null ?: (bool) $void;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,7 +55,7 @@ class DeferredText implements ValidHtml
|
|||
if ($this->escaped) {
|
||||
return $callback();
|
||||
} else {
|
||||
return Html::escapeForHtml($callback());
|
||||
return Html::escape($callback());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -80,7 +80,7 @@ class DeferredText implements ValidHtml
|
|||
try {
|
||||
return $this->render();
|
||||
} catch (Exception $e) {
|
||||
return Html::renderError($e);
|
||||
return Error::render($e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,118 @@
|
|||
<?php
|
||||
|
||||
namespace dipl\Html;
|
||||
|
||||
use Error as PhpError;
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* Class Error
|
||||
*
|
||||
* TODO: Eventually allow to (statically) inject a custom error renderer.
|
||||
*
|
||||
* @package ipl\Html
|
||||
*/
|
||||
abstract class Error
|
||||
{
|
||||
/** @var bool */
|
||||
protected static $showTraces = true;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param Exception|PhpError|string $error
|
||||
* @return HtmlDocument
|
||||
*/
|
||||
public static function show($error)
|
||||
{
|
||||
if ($error instanceof Exception) {
|
||||
$msg = static::createMessageForException($error);
|
||||
} elseif ($error instanceof PhpError) {
|
||||
$msg = static::createMessageForException($error);
|
||||
} elseif (is_string($error)) {
|
||||
$msg = $error;
|
||||
} else {
|
||||
// TODO: translate?
|
||||
$msg = 'Got an invalid error';
|
||||
}
|
||||
|
||||
$result = static::renderErrorMessage($msg);
|
||||
if (static::showTraces()) {
|
||||
$result->add(Html::tag('pre', $error->getTraceAsString()));
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param Exception|PhpError|string $error
|
||||
* @return string
|
||||
*/
|
||||
public static function render($error)
|
||||
{
|
||||
return static::show($error)->render();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string
|
||||
* @return HtmlDocument
|
||||
*/
|
||||
protected static function renderErrorMessage($message)
|
||||
{
|
||||
$output = new HtmlDocument();
|
||||
$output->add(
|
||||
Html::tag('div', ['class' => 'exception'], [
|
||||
Html::tag('h1', [
|
||||
Html::tag('i', ['class' => 'icon-bug']),
|
||||
// TODO: Translate? More hints?
|
||||
'Oops, an error occurred!'
|
||||
]),
|
||||
Html::tag('pre', $message)
|
||||
])
|
||||
);
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param PhpError|Exception $exception
|
||||
* @return string
|
||||
*/
|
||||
protected static function createMessageForException($exception)
|
||||
{
|
||||
$file = preg_split('/[\/\\\]/', $exception->getFile(), -1, PREG_SPLIT_NO_EMPTY);
|
||||
$file = array_pop($file);
|
||||
return sprintf(
|
||||
'%s (%s:%d)',
|
||||
$exception->getMessage(),
|
||||
$file,
|
||||
$exception->getLine()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool|null $show
|
||||
* @return bool
|
||||
*/
|
||||
public static function showTraces($show = null)
|
||||
{
|
||||
if ($show !== null) {
|
||||
self::$showTraces = (bool) $show;
|
||||
}
|
||||
|
||||
return self::$showTraces;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $any
|
||||
* @return string
|
||||
*/
|
||||
public static function getPhpTypeName($any)
|
||||
{
|
||||
if (is_object($any)) {
|
||||
return get_class($any);
|
||||
} else {
|
||||
return gettype($any);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -16,7 +16,6 @@ class FormattedString implements ValidHtml
|
|||
* FormattedString constructor.
|
||||
* @param $string
|
||||
* @param array $arguments
|
||||
* @throws \Icinga\Exception\IcingaException
|
||||
*/
|
||||
public function __construct($string, array $arguments = [])
|
||||
{
|
||||
|
@ -30,7 +29,6 @@ class FormattedString implements ValidHtml
|
|||
/**
|
||||
* @param $string
|
||||
* @return static
|
||||
* @throws \Icinga\Exception\IcingaException
|
||||
*/
|
||||
public static function create($string)
|
||||
{
|
||||
|
@ -47,4 +45,16 @@ class FormattedString implements ValidHtml
|
|||
$this->arguments
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
try {
|
||||
return $this->render();
|
||||
} catch (Exception $e) {
|
||||
return Error::render($e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,35 +2,80 @@
|
|||
|
||||
namespace dipl\Html;
|
||||
|
||||
use Exception;
|
||||
use Icinga\Exception\IcingaException;
|
||||
use InvalidArgumentException;
|
||||
|
||||
class Html
|
||||
/**
|
||||
* Class Html
|
||||
*
|
||||
* This is your main utility class when working with ipl\Html
|
||||
*
|
||||
* @package ipl\Html
|
||||
*/
|
||||
abstract class Html
|
||||
{
|
||||
/** Charset to be used - we only support UTF-8 */
|
||||
const CHARSET = 'UTF-8';
|
||||
|
||||
/** @var int The flags we use for htmlspecialchars depend on our PHP version */
|
||||
protected static $htmlEscapeFlags;
|
||||
|
||||
/** @var bool */
|
||||
protected static $showTraces = true;
|
||||
|
||||
/**
|
||||
* @param $tag
|
||||
* @param null $attributes
|
||||
* @param null $content
|
||||
* @return HtmlElement
|
||||
* Create a HTML element from the given tag, attributes and content
|
||||
*
|
||||
* This method does not render the HTML element but creates a {@link HtmlElement}
|
||||
* instance from the given tag, attributes and content
|
||||
*
|
||||
* @param string $name The desired HTML tag name
|
||||
* @param mixed $attributes HTML attributes or content for the element
|
||||
* @param mixed $content The content of the element if no attributes have been given
|
||||
*
|
||||
* @return HtmlElement The created element
|
||||
*/
|
||||
public static function tag($tag, $attributes = null, $content = null)
|
||||
public static function tag($name, $attributes = null, $content = null)
|
||||
{
|
||||
return HtmlElement::create($tag, $attributes, $content);
|
||||
if ($attributes instanceof ValidHtml || is_string($attributes)) {
|
||||
$content = $attributes;
|
||||
$attributes = null;
|
||||
} elseif (is_array($attributes)) {
|
||||
reset($attributes);
|
||||
if (is_int(key($attributes))) {
|
||||
$content = $attributes;
|
||||
$attributes = null;
|
||||
}
|
||||
}
|
||||
|
||||
return new HtmlElement($name, $attributes, $content);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert special characters to HTML5 entities using the UTF-8 character
|
||||
* set for encoding
|
||||
*
|
||||
* This method internally uses {@link htmlspecialchars} with the following
|
||||
* flags:
|
||||
*
|
||||
* * Single quotes are not escaped (ENT_COMPAT)
|
||||
* * Uses HTML5 entities, disallowing 
 (ENT_HTML5)
|
||||
* * Invalid characters are replaced with <EFBFBD> (ENT_SUBSTITUTE)
|
||||
*
|
||||
* Already existing HTML entities will be encoded as well.
|
||||
*
|
||||
* @param string $content The content to encode
|
||||
*
|
||||
* @return string The encoded content
|
||||
*/
|
||||
public static function escape($content)
|
||||
{
|
||||
return htmlspecialchars($content, ENT_COMPAT | ENT_HTML5 | ENT_SUBSTITUTE, 'UTF-8');
|
||||
}
|
||||
|
||||
/**
|
||||
* sprintf()-like helper method
|
||||
*
|
||||
* This allows to use sprintf with ValidHtml elements, but with the
|
||||
* advantage that they'll not be rendered immediately. The result is an
|
||||
* instance of FormattedString, being ValidHtml
|
||||
*
|
||||
* Usage:
|
||||
*
|
||||
* echo Html::sprintf('Hello %s!', Html::tag('strong', $name));
|
||||
*
|
||||
* @param $string
|
||||
* @return FormattedString
|
||||
* @throws IcingaException
|
||||
*/
|
||||
public static function sprintf($string)
|
||||
{
|
||||
|
@ -41,25 +86,13 @@ class Html
|
|||
}
|
||||
|
||||
/**
|
||||
* Escape the given value top be safely used in view scripts
|
||||
* Accept any input and try to convert it to ValidHtml
|
||||
*
|
||||
* Returns the very same element in case it's already valid
|
||||
*
|
||||
* @param string $value The output to be escaped
|
||||
* @return string
|
||||
*/
|
||||
public static function escapeForHtml($value)
|
||||
{
|
||||
return htmlspecialchars(
|
||||
$value,
|
||||
static::htmlEscapeFlags(),
|
||||
self::CHARSET,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $any
|
||||
* @return ValidHtml
|
||||
* @throws IcingaException
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public static function wantHtml($any)
|
||||
{
|
||||
|
@ -75,30 +108,22 @@ class Html
|
|||
|
||||
return $html;
|
||||
} else {
|
||||
// TODO: Should we add a dedicated Exception class?
|
||||
throw new IcingaException(
|
||||
throw new InvalidArgumentException(sprintf(
|
||||
'String, Html Element or Array of such expected, got "%s"',
|
||||
Html::getPhpTypeName($any)
|
||||
);
|
||||
Error::getPhpTypeName($any)
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
public static function canBeRenderedAsString($any)
|
||||
{
|
||||
return is_string($any) || is_int($any) || is_null($any) || is_float($any);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether a given variable can be rendered as a string
|
||||
*
|
||||
* @param $any
|
||||
* @return string
|
||||
* @return bool
|
||||
*/
|
||||
public static function getPhpTypeName($any)
|
||||
public static function canBeRenderedAsString($any)
|
||||
{
|
||||
if (is_object($any)) {
|
||||
return get_class($any);
|
||||
} else {
|
||||
return gettype($any);
|
||||
}
|
||||
return is_string($any) || is_int($any) || is_null($any) || is_float($any);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -109,101 +134,24 @@ class Html
|
|||
public static function __callStatic($name, $arguments)
|
||||
{
|
||||
$attributes = array_shift($arguments);
|
||||
$content = null;
|
||||
if ($attributes instanceof ValidHtml || is_string($attributes)) {
|
||||
$content = $attributes;
|
||||
$attributes = null;
|
||||
} elseif (is_array($attributes)) {
|
||||
if (empty($attributes)) {
|
||||
$attributes = null;
|
||||
} elseif (is_int(key($attributes))) {
|
||||
$content = $attributes;
|
||||
$attributes = null;
|
||||
}
|
||||
}
|
||||
$content = array_shift($arguments);
|
||||
|
||||
if (!empty($arguments)) {
|
||||
if (null === $content) {
|
||||
$content = $arguments;
|
||||
} else {
|
||||
$content = [$content, $arguments];
|
||||
}
|
||||
}
|
||||
|
||||
return HtmlElement::create($name, $attributes, $content);
|
||||
return static::tag($name, $attributes, $content);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Exception|string $error
|
||||
* @return string
|
||||
* @deprecated Use {@link Html::encode()} instead
|
||||
*/
|
||||
public static function escapeForHtml($content)
|
||||
{
|
||||
return static::escape($content);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link Error::render()} instead
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param null $show
|
||||
* @return bool|null
|
||||
*/
|
||||
public static function showTraces($show = null)
|
||||
{
|
||||
if ($show !== null) {
|
||||
self::$showTraces = $show;
|
||||
}
|
||||
|
||||
return self::$showTraces;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 
|
||||
*
|
||||
* @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;
|
||||
return Error::render($error);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,13 +4,13 @@ namespace dipl\Html;
|
|||
|
||||
use Countable;
|
||||
use Exception;
|
||||
use Icinga\Exception\ProgrammingError;
|
||||
use InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* Class Html
|
||||
* @package dipl\Html
|
||||
* @package ipl\Html
|
||||
*/
|
||||
class HtmlDocument implements ValidHtml, Countable
|
||||
class HtmlDocument implements Countable, ValidHtml
|
||||
{
|
||||
protected $contentSeparator = '';
|
||||
|
||||
|
@ -28,7 +28,6 @@ class HtmlDocument implements ValidHtml, Countable
|
|||
/**
|
||||
* @param ValidHtml|array|string $content
|
||||
* @return $this
|
||||
* @throws \Icinga\Exception\IcingaException
|
||||
*/
|
||||
public function add($content)
|
||||
{
|
||||
|
@ -96,7 +95,7 @@ class HtmlDocument implements ValidHtml, Countable
|
|||
/**
|
||||
* @param $tag
|
||||
* @return BaseHtmlElement
|
||||
* @throws ProgrammingError
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function getFirst($tag)
|
||||
{
|
||||
|
@ -106,16 +105,15 @@ class HtmlDocument implements ValidHtml, Countable
|
|||
}
|
||||
}
|
||||
|
||||
throw new ProgrammingError(
|
||||
throw new InvalidArgumentException(sprintf(
|
||||
'Trying to get first %s, but there is no such',
|
||||
$tag
|
||||
);
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $content
|
||||
* @return $this
|
||||
* @throws \Icinga\Exception\IcingaException
|
||||
*/
|
||||
public function prepend($content)
|
||||
{
|
||||
|
@ -149,7 +147,6 @@ class HtmlDocument implements ValidHtml, Countable
|
|||
/**
|
||||
* @param $string
|
||||
* @return HtmlDocument
|
||||
* @throws \Icinga\Exception\IcingaException
|
||||
*/
|
||||
public function addPrintf($string)
|
||||
{
|
||||
|
@ -164,7 +161,6 @@ class HtmlDocument implements ValidHtml, Countable
|
|||
/**
|
||||
* @param HtmlDocument|array|string $content
|
||||
* @return $this
|
||||
* @throws \Icinga\Exception\IcingaException
|
||||
*/
|
||||
public function setContent($content)
|
||||
{
|
||||
|
@ -190,8 +186,6 @@ class HtmlDocument implements ValidHtml, Countable
|
|||
|
||||
/**
|
||||
* @return string
|
||||
* @throws ProgrammingError
|
||||
* @throws \Icinga\Exception\IcingaException
|
||||
*/
|
||||
public function render()
|
||||
{
|
||||
|
@ -204,8 +198,6 @@ class HtmlDocument implements ValidHtml, Countable
|
|||
|
||||
/**
|
||||
* @return string
|
||||
* @throws ProgrammingError
|
||||
* @throws \Icinga\Exception\IcingaException
|
||||
*/
|
||||
protected function renderWrapped()
|
||||
{
|
||||
|
@ -222,8 +214,6 @@ class HtmlDocument implements ValidHtml, Countable
|
|||
/**
|
||||
* @param HtmlDocument $document
|
||||
* @return string
|
||||
* @throws ProgrammingError
|
||||
* @throws \Icinga\Exception\IcingaException
|
||||
*/
|
||||
protected function renderWrappedDocument(HtmlDocument $document)
|
||||
{
|
||||
|
@ -271,7 +261,7 @@ class HtmlDocument implements ValidHtml, Countable
|
|||
try {
|
||||
return $this->render();
|
||||
} catch (Exception $e) {
|
||||
return Html::renderError($e);
|
||||
return Error::render($e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,21 +2,26 @@
|
|||
|
||||
namespace dipl\Html;
|
||||
|
||||
/**
|
||||
* The HtmlElement represents any HTML element
|
||||
*
|
||||
* A typical HTML element includes a tag, attributes and content.
|
||||
*/
|
||||
class HtmlElement extends BaseHtmlElement
|
||||
{
|
||||
/**
|
||||
* Container constructor.
|
||||
* Create a new HTML element from the given tag, attributes and content
|
||||
*
|
||||
* @param string $tag
|
||||
* @param Attributes|array $attributes
|
||||
* @param ValidHtml|array|string $content
|
||||
* @param string $tag The tag for the element
|
||||
* @param Attributes|array $attributes The HTML attributes for the element
|
||||
* @param ValidHtml|string|array $content The content of the element
|
||||
*/
|
||||
public function __construct($tag, $attributes = null, $content = null)
|
||||
{
|
||||
$this->tag = $tag;
|
||||
|
||||
if ($attributes !== null) {
|
||||
$this->attributes = $this->getAttributes()->add($attributes);
|
||||
$this->getAttributes()->add($attributes);
|
||||
}
|
||||
|
||||
if ($content !== null) {
|
||||
|
|
|
@ -57,22 +57,10 @@ class Text implements ValidHtml
|
|||
if ($this->escaped) {
|
||||
return $this->string;
|
||||
} else {
|
||||
return Html::escapeForHtml($this->string);
|
||||
return Html::escape($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 Html::renderError($error);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
|
@ -81,7 +69,7 @@ class Text implements ValidHtml
|
|||
try {
|
||||
return $this->render();
|
||||
} catch (Exception $e) {
|
||||
return $this->renderError($e);
|
||||
return Error::render($e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,19 +3,15 @@
|
|||
namespace dipl\Html;
|
||||
|
||||
/**
|
||||
* Interface ValidHtml
|
||||
*
|
||||
* Implementations of this interface MUST guarantee, that the result of the
|
||||
* render() method gives valid UTF-8 encoded HTML5.
|
||||
* Interface for HTML elements or primitives that promise to render valid UTF-8 encoded HTML5 with special characters
|
||||
* converted to HTML entities
|
||||
*/
|
||||
interface ValidHtml
|
||||
{
|
||||
/**
|
||||
* Renders to HTML
|
||||
* Render to HTML
|
||||
*
|
||||
* The result of this method is a valid UTF8-encoded HTML5 string.
|
||||
*
|
||||
* @return string
|
||||
* @return string UTF-8 encoded HTML5 with special characters converted to HTML entities
|
||||
*/
|
||||
public function render();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue