Html\Attributes: callbacks for setters and getters

This commit is contained in:
Thomas Gelf 2018-05-23 08:22:06 +02:00
parent 14cd540ce9
commit 799a332c22
1 changed files with 43 additions and 13 deletions

View File

@ -10,9 +10,12 @@ class Attributes
/** @var Attribute[] */
protected $attributes = [];
/** @var callable */
/** @var callable[] */
protected $callbacks = [];
/** @var callable[] */
protected $setterCallbacks = [];
/** @var string */
protected $prefix = '';
@ -91,7 +94,8 @@ class Attributes
*/
public function add($attribute, $value = null)
{
if ($attribute instanceof static) {
// TODO: do not allow Attribute and Attributes
if ($attribute instanceof Attributes) {
foreach ($attribute->getAttributes() as $a) {
$this->add($a);
}
@ -102,7 +106,12 @@ class Attributes
$this->add($name, $value);
}
} else {
$this->addAttribute(Attribute::create($attribute, $value));
if (array_key_exists($attribute, $this->setterCallbacks)) {
$callback = $this->setterCallbacks[$attribute];
$callback($value);
} else {
$this->addAttribute(Attribute::create($attribute, $value));
}
}
return $this;
@ -131,7 +140,14 @@ class Attributes
return $this;
} else {
return $this->setAttribute(new Attribute($attribute, $value));
if (array_key_exists($attribute, $this->setterCallbacks)) {
$callback = $this->setterCallbacks[$attribute];
$callback($value);
return $this;
} else {
return $this->setAttribute(new Attribute($attribute, $value));
}
}
}
@ -204,17 +220,29 @@ class Attributes
/**
* Callback must return an instance of Attribute
*
* TODO: setCallback
*
* @param string $name
* @param callable $callback
* @param callable $setterCallback
* @return $this
* @throws ProgrammingError
*/
public function registerAttributeCallback($name, $callback)
public function registerAttributeCallback($name, $callback, $setterCallback = null)
{
if (! is_callable($callback)) {
throw new ProgrammingError(__METHOD__ . ' expects a callable callback');
if ($callback !== null) {
if (! is_callable($callback)) {
throw new ProgrammingError(__METHOD__ . ' expects a callable callback');
}
$this->callbacks[$name] = $callback;
}
if ($setterCallback !== null) {
if (! is_callable($setterCallback)) {
throw new ProgrammingError(__METHOD__ . ' expects a callable setterCallback');
}
$this->setterCallbacks[$name] = $setterCallback;
}
$this->callbacks[$name] = $callback;
return $this;
}
@ -225,15 +253,13 @@ class Attributes
*/
public function render()
{
if (empty($this->attributes) && empty($this->callbacks)) {
return '';
}
$parts = [];
foreach ($this->callbacks as $name => $callback) {
$attribute = call_user_func($callback);
if ($attribute instanceof Attribute) {
$parts[] = $attribute->render();
if ($attribute->getValue() !== null) {
$parts[] = $attribute->render();
}
} elseif (is_string($attribute)) {
$parts[] = Attribute::create($name, $attribute)->render();
} elseif (null === $attribute) {
@ -254,6 +280,10 @@ class Attributes
$parts[] = $attribute->render();
}
if (empty($parts)) {
return '';
}
$separator = ' ' . $this->prefix;
return $separator . implode($separator, $parts);