dipl: align with ipl, first step

This commit is contained in:
Thomas Gelf 2018-05-05 00:18:45 +02:00
parent be0d41459f
commit 403df971a1
15 changed files with 246 additions and 159 deletions

View File

@ -27,6 +27,7 @@ class Attribute
*
* @param $name
* @param $value
* @throws ProgrammingError
*/
public function __construct($name, $value = null)
{
@ -37,6 +38,7 @@ class Attribute
* @param $name
* @param $value
* @return static
* @throws ProgrammingError
*/
public static function create($name, $value)
{
@ -158,6 +160,7 @@ class Attribute
/**
* @param $name
* @return static
* @throws ProgrammingError
*/
public static function createEmpty($name)
{
@ -182,9 +185,9 @@ class Attribute
{
// TODO: escape differently
if (is_array($value)) {
return Util::escapeForHtml(implode(' ', $value));
return Html::escapeForHtml(implode(' ', $value));
} else {
return Util::escapeForHtml((string) $value);
return Html::escapeForHtml((string) $value);
}
}
}

View File

@ -8,10 +8,10 @@ use Icinga\Exception\ProgrammingError;
class Attributes
{
/** @var Attribute[] */
protected $attributes = array();
protected $attributes = [];
/** @var callable */
protected $callbacks = array();
protected $callbacks = [];
/** @var string */
protected $prefix = '';
@ -19,6 +19,7 @@ class Attributes
/**
* Attributes constructor.
* @param Attribute[] $attributes
* @throws ProgrammingError
*/
public function __construct(array $attributes = null)
{
@ -40,6 +41,7 @@ class Attributes
/**
* @param Attribute[] $attributes
* @return static
* @throws ProgrammingError
*/
public static function create(array $attributes = null)
{
@ -66,7 +68,7 @@ class Attributes
} elseif ($attributes !== null) {
throw new IcingaException(
'Attributes, Array or Null expected, got %s',
Util::getPhpTypeName($attributes)
Html::getPhpTypeName($attributes)
);
}
return $self;
@ -85,6 +87,7 @@ class Attributes
* @param Attribute|string $attribute
* @param string|array $value
* @return $this
* @throws ProgrammingError
*/
public function add($attribute, $value = null)
{
@ -106,9 +109,10 @@ class Attributes
}
/**
* @param Attribute|string|array $attribute
* @param Attribute|array|string $attribute
* @param string|array $value
* @return $this
* @throws ProgrammingError
*/
public function set($attribute, $value = null)
{
@ -134,6 +138,7 @@ class Attributes
/**
* @param $name
* @return Attribute
* @throws ProgrammingError
*/
public function get($name)
{
@ -146,18 +151,28 @@ class Attributes
/**
* @param $name
* @return bool
* @return Attribute|false
*/
public function delete($name)
public function remove($name)
{
if ($this->has($name)) {
$attribute = $this->attributes[$name];
unset($this->attributes[$name]);
return true;
return $attribute;
} else {
return false;
}
}
/**
* @deprecated
*/
public function delete($name)
{
return $this->remove($name);
}
/**
* @param $name
* @return bool
@ -202,17 +217,19 @@ class Attributes
* @return $this
* @throws ProgrammingError
*/
public function registerCallbackFor($name, $callback)
public function registerAttributeCallback($name, $callback)
{
if (! is_callable($callback)) {
throw new ProgrammingError('registerCallBack expects a callable callback');
throw new ProgrammingError(__METHOD__ . ' expects a callable callback');
}
$this->callbacks[$name] = $callback;
return $this;
}
/**
* @inheritdoc
* @return string
* @throws ProgrammingError
*/
public function render()
{
@ -220,7 +237,7 @@ class Attributes
return '';
}
$parts = array();
$parts = [];
foreach ($this->callbacks as $name => $callback) {
$attribute = call_user_func($callback);
if ($attribute instanceof Attribute) {

View File

@ -37,7 +37,7 @@ abstract class BaseElement extends Html
/**
* @return Attributes
*/
public function attributes()
public function getAttributes()
{
if ($this->attributes === null) {
$default = $this->getDefaultAttributes();
@ -51,6 +51,14 @@ abstract class BaseElement extends Html
return $this->attributes;
}
/**
* @deprecated
*/
public function attributes()
{
return $this->getAttributes();
}
/**
* @param Attributes|array|null $attributes
* @return $this
@ -61,13 +69,19 @@ abstract class BaseElement extends Html
return $this;
}
public function setAttribute($key, $value)
{
$this->getAttributes()->set($key, $value);
return $this;
}
/**
* @param Attributes|array|null $attributes
* @return $this
*/
public function addAttributes($attributes)
{
$this->attributes()->add($attributes);
$this->getAttributes()->add($attributes);
return $this;
}
@ -93,6 +107,8 @@ abstract class BaseElement extends Html
* @param string $tag
* @param Attributes|array $attributes
*
* @deprecated
*
* @return Element
*/
public function addElement($tag, $attributes = null)
@ -155,7 +171,7 @@ abstract class BaseElement extends Html
if ($this->attributes === null && empty($this->defaultAttributes)) {
return '';
} else {
return $this->attributes()->render();
return $this->getAttributes()->render();
}
}

View File

@ -55,7 +55,7 @@ class DeferredText implements ValidHtml
if ($this->escaped) {
return $callback();
} else {
return Util::escapeForHtml($callback());
return Html::escapeForHtml($callback());
}
}
@ -80,7 +80,7 @@ class DeferredText implements ValidHtml
try {
return $this->render();
} catch (Exception $e) {
return Util::renderError($e);
return Html::renderError($e);
}
}
}

View File

@ -16,7 +16,7 @@ class Element extends BaseElement
$this->tag = $tag;
if ($attributes !== null) {
$this->attributes = $this->attributes()->add($attributes);
$this->attributes = $this->getAttributes()->add($attributes);
}
if ($content !== null) {

View File

@ -12,15 +12,26 @@ class FormattedString implements ValidHtml
/** @var ValidHtml */
protected $string;
/**
* FormattedString constructor.
* @param $string
* @param array $arguments
* @throws \Icinga\Exception\IcingaException
*/
public function __construct($string, array $arguments = [])
{
$this->string = Util::wantHtml($string);
$this->string = Html::wantHtml($string);
foreach ($arguments as $key => $val) {
$this->arguments[$key] = Util::wantHtml($val);
$this->arguments[$key] = Html::wantHtml($val);
}
}
/**
* @param $string
* @return static
* @throws \Icinga\Exception\IcingaException
*/
public static function create($string)
{
$args = func_get_args();

View File

@ -4,6 +4,7 @@ namespace dipl\Html;
use Countable;
use Exception;
use Icinga\Exception\IcingaException;
use Icinga\Exception\ProgrammingError;
/**
@ -12,6 +13,15 @@ use Icinga\Exception\ProgrammingError;
*/
class Html implements ValidHtml, Countable
{
/** 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;
protected $contentSeparator = '';
/** @var ValidHtml[] */
@ -31,7 +41,7 @@ class Html implements ValidHtml, Countable
$this->addContent($c);
}
} else {
$this->addIndexedContent(Util::wantHtml($content));
$this->addIndexedContent(Html::wantHtml($content));
}
return $this;
@ -68,7 +78,7 @@ class Html implements ValidHtml, Countable
}
} else {
$pos = 0;
$html = Util::wantHtml($content);
$html = Html::wantHtml($content);
array_unshift($this->content, $html);
$this->incrementIndexKeys();
$this->addObjectPosition($html, $pos);
@ -103,6 +113,22 @@ class Html implements ValidHtml, Countable
);
}
/**
* 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 Html|array|string $content
* @return $this
@ -209,6 +235,51 @@ class Html implements ValidHtml, Countable
return $element;
}
/**
* @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"',
Html::getPhpTypeName($any)
);
}
}
public static function canBeRenderedAsString($any)
{
return is_string($any) || is_int($any) || is_null($any) || is_float($any);
}
/**
* @param $any
* @return string
*/
public static function getPhpTypeName($any)
{
if (is_object($any)) {
return get_class($any);
} else {
return gettype($any);
}
}
/**
* @param $name
* @param $arguments
@ -230,7 +301,7 @@ class Html implements ValidHtml, Countable
}
}
if (! empty($arguments)) {
if (!empty($arguments)) {
if (null === $content) {
$content = $arguments;
} else {
@ -245,9 +316,51 @@ class Html implements ValidHtml, Countable
* @param Exception|string $error
* @return string
*/
protected function renderError($error)
public static function renderError($error)
{
return Util::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;
}
/**
@ -258,7 +371,7 @@ class Html implements ValidHtml, Countable
try {
return $this->render();
} catch (Exception $e) {
return $this->renderError($e);
return static::renderError($e);
}
}
@ -302,4 +415,27 @@ class Html implements ValidHtml, Countable
}
}
}
/**
* 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;
}
}

View File

@ -9,7 +9,7 @@ class Icon extends BaseElement
public function __construct($name, $attributes = null)
{
$this->setAttributes($attributes);
$this->attributes()->add('class', array('icon', 'icon-' . $name));
$this->getAttributes()->add('class', array('icon', 'icon-' . $name));
}
/**

View File

@ -30,7 +30,7 @@ class Img extends BaseElement
/** @var Img $img */
$img = new static();
$img->setAttributes($attributes);
$img->attributes()->registerCallbackFor('src', array($img, 'getSrcAttribute'));
$img->getAttributes()->registerAttributeCallback('src', array($img, 'getSrcAttribute'));
$img->setUrl($url, $urlParams);
return $img;
}

View File

@ -23,7 +23,7 @@ class Link extends BaseElement
{
$this->setContent($content);
$this->setAttributes($attributes);
$this->attributes()->registerCallbackFor('href', array($this, 'getHrefAttribute'));
$this->getAttributes()->registerAttributeCallback('href', array($this, 'getHrefAttribute'));
$this->setUrl($url, $urlParams);
}

View File

@ -170,7 +170,7 @@ class Table extends BaseElement
{
$classes = $this->getRowClasses($row);
if (! empty($classes)) {
$tr->attributes()->add('class', $classes);
$tr->getAttributes()->add('class', $classes);
}
return $tr;

View File

@ -57,7 +57,7 @@ class Text implements ValidHtml
if ($this->escaped) {
return $this->string;
} else {
return Util::escapeForHtml($this->string);
return Html::escapeForHtml($this->string);
}
}
@ -70,7 +70,7 @@ class Text implements ValidHtml
*/
protected function renderError($error)
{
return Util::renderError($error);
return Html::renderError($error);
}
/**

View File

@ -2,152 +2,56 @@
namespace dipl\Html;
use Exception;
use Icinga\Exception\IcingaException;
/**
* @deprecated
*/
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
* @deprecated
*/
public static function escapeForHtml($value)
{
return htmlspecialchars(
$value,
static::htmlEscapeFlags(),
self::CHARSET,
true
);
return Html::escapeForHtml($value);
}
/**
* @param Exception|string $error
* @return string
* @deprecated
*/
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;
return Html::renderError($error);
}
/**
* @param $any
* @return ValidHtml
* @throws IcingaException
* @deprecated
*/
public static function showTraces($show = null)
{
return Html::showTraces($show);
}
/**
* @deprecated
*/
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) || is_float($any);
return Html::wantHtml($any);
}
/**
* @param $any
* @return string
* @deprecated
*/
public static function canBeRenderedAsString($any)
{
return Html::canBeRenderedAsString($any);
}
/**
* @deprecated
*/
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;
return Html::getPhpTypeName($any);
}
}

View File

@ -156,11 +156,11 @@ trait ZfSortablePriority
);
if ($this->isOnFirstRow()) {
$up->attributes()->add('disabled', 'disabled');
$up->getAttributes()->add('disabled', 'disabled');
}
if ($this->isOnLastRow()) {
$down->attributes()->add('disabled', 'disabled');
$down->getAttributes()->add('disabled', 'disabled');
}
return [$down, $up];

View File

@ -19,7 +19,7 @@ class ActionBar extends BaseElement
*/
public function setBaseTarget($target)
{
$this->attributes()->set('data-base-target', $target);
$this->getAttributes()->set('data-base-target', $target);
return $this;
}
}