plus-8.x-4.x-dev/src/Utility/AttributeArray.php
src/Utility/AttributeArray.php
<?php
namespace Drupal\plus\Utility;
use Drupal\Component\Utility\Html;
/**
* A class that defines a type of Attribute that can be added to as an array.
*
* To use with Attribute, the array must be specified.
* Correct:
* @code
* $attributes = new Attribute();
* $attributes['class'] = array();
* $attributes['class'][] = 'cat';
* @endcode
* Incorrect:
* @code
* $attributes = new Attribute();
* $attributes['class'][] = 'cat';
* @endcode
*
* @see \Drupal\Core\Template\Attribute
*/
class AttributeArray extends AttributeBase {
/**
* Ensures empty array as a result of array_filter will not print '$name=""'.
*
* @see \Drupal\Core\Template\AttributeArray::renderValue()
* @see \Drupal\Core\Template\AttributeValueBase::render()
*/
const RENDER_EMPTY_ATTRIBUTE = FALSE;
/**
* {@inheritdoc}
*/
public function __construct($name, &$value = NULL) {
if (!isset($value)) {
$value = [];
}
parent::__construct($name, $value);
}
/**
* {@inheritdoc}
*/
public function __set($key, $value) {
parent::__set($key, $value);
// After the value was added using object notation, e.g. $attr->0, ensure
// unique and non-empty values. Note: this is highly unlikely as it's
// generally considered poor DX. However, do it just in case.
$this->filter()->unique();
}
/**
* {@inheritdoc}
*/
public function __toString() {
return Html::escape(implode(' ', $this->value()));
}
/**
* {@inheritdoc}
*/
protected function &convertArguments(array &$arguments = []) {
$arguments = [$this->sanitize(...$arguments)->value()];
return parent::convertArguments($arguments);
}
/**
* {@inheritdoc}
*/
public function merge(&...$values) {
parent::merge(...$values);
// After values were merged in, ensure unique and non-empty values.
return $this->filter()->unique();
}
/**
* {@inheritdoc}
*/
public function offsetSet($key, $value) {
parent::offsetSet($key, $value);
// After the value was added using array notation, e.g. $attr[], ensure
// unique and non-empty values.
$this->filter()->unique();
}
/**
* {@inheritdoc}
*/
public function replace(array &$value = [], array &$previous = []) {
parent::replace($value, $previous);;
// After entire values are replaced, ensure unique and non-empty values.
return $this->filter()->unique();
}
/**
* Sanitizes values that are about to be merged in.
*
* @param mixed ...
* The values to sanitize.
*
* @return \Drupal\plus\Utility\ArrayObject
* A new ArrayObject instance with the values to merge.
*/
protected function sanitize(...$values) {
// Since attributes do not have the concept of multi-dimensional arrays,
// flatten it into a single array of values.
return ArrayObject::create()->merge(...$values)->flatten();
}
/**
* {@inheritdoc}
*/
public function remove(...$keys) {
$this->convertArguments($keys);
return parent::remove(...$keys);
}
}
