View source
<?php
namespace Drupal\markdown\Annotation;
use Drupal\Component\Annotation\AnnotationBase;
use Drupal\Component\Annotation\AnnotationInterface;
use Drupal\Component\Plugin\Definition\PluginDefinitionInterface;
use Drupal\Component\Utility\NestedArray;
use Drupal\Core\DependencyInjection\DependencySerializationTrait;
abstract class AnnotationObject extends AnnotationBase implements \ArrayAccess, \IteratorAggregate, PluginDefinitionInterface {
use DependencySerializationTrait {
__sleep as __sleepTrait;
__wakeup as __wakeupTrait;
}
const DEPRECATED_REGEX = '/@deprecated ([^@]+|\\n)+(?:@see (.*))?/';
protected $_deprecated = [];
protected $_deprecatedProperties = [];
private $_triggeredDeprecations = [];
public $description;
public $label;
public $weight = 0;
public function __construct(array $values = []) {
$this
->validateIdentifier(Identifier::createFromArray($values));
foreach (array_keys(get_object_vars($this)) as $name) {
try {
$ref = new \ReflectionProperty($this, $name);
if (!$ref
->isPublic()) {
continue;
}
if (($doc = $ref
->getDocComment()) && preg_match(static::DEPRECATED_REGEX, $doc, $matches)) {
$deprecation = array_filter(array_map(function ($line) {
return preg_replace('/^\\s*\\*?\\s*/', '', $line);
}, explode("\n", $matches[1])));
array_unshift($deprecation, static::class . "::\${$name} is deprecated");
if (!empty($matches[2])) {
$deprecation[] = 'See ' . $matches[2];
}
$this->_deprecatedProperties[$name] = implode(' ', $deprecation);
unset($this->{$name});
}
} catch (\ReflectionException $e) {
}
}
$this
->doMerge($values);
}
public static function create($values = []) {
if ($values instanceof \Traversable) {
$values = iterator_to_array($values);
}
return new static($values);
}
public function &__get($name) {
return $this
->offsetGet($name);
}
public function __isset($name) {
return $this
->offsetExists($name);
}
public function __set($name, $value) {
$this
->offsetSet($name, $value);
}
public function __sleep() {
unset($this->_triggeredDeprecations);
return $this
->__sleepTrait();
}
public function __unset($name) {
$this
->offsetUnset($name);
}
public function __wakeup() {
foreach (array_keys($this->_deprecatedProperties) as $property) {
unset($this->{$property});
}
$this
->__wakeupTrait();
}
protected function doMerge($values, array $excludedProperties = []) {
if ($values instanceof \Traversable) {
$values = iterator_to_array($values);
}
if (!is_array($values)) {
return $this;
}
if ($excludedProperties) {
$excludedProperties = array_unique($excludedProperties);
}
foreach ($values as $key => $value) {
if ($excludedProperties && in_array($key, $excludedProperties, TRUE)) {
continue;
}
if ($key === 'id' && !$value instanceof Identifier) {
$value = new Identifier($value);
}
if (property_exists($this, $key) || $key[0] === '_') {
if (is_array($value)) {
$existing = $this
->offsetGet($key);
if (is_array($existing)) {
$value = NestedArray::mergeDeep($existing, $value);
}
}
if (isset($value)) {
$this
->offsetSet($key, $value);
}
}
}
return $this;
}
public function get() {
return $this;
}
public function getId() {
return (string) parent::getId();
}
public function getIterator() {
$iterator = new \ArrayIterator($this);
foreach ($this->_deprecated as $key => $value) {
$iterator
->offsetSet($key, $value);
}
return $iterator;
}
public function id() {
return $this
->getId();
}
public function merge($values, array $excludedProperties = []) {
return $this
->doMerge($values, array_merge($excludedProperties, $this
->protectedProperties()));
}
protected function normalizeValue($value) {
$normalized = [];
if ($value instanceof AnnotationInterface) {
return $value
->get();
}
elseif (is_array($value) || $value instanceof \Traversable) {
foreach ($value as $k => $v) {
$normalized[$k] = $this
->normalizeValue($v);
}
}
else {
return $value;
}
return $normalized;
}
public function offsetExists($offset) {
if (array_key_exists($offset, $this->_deprecatedProperties)) {
return isset($this->_deprecated[$offset]);
}
return isset($this->{$offset});
}
public function &offsetGet($offset) {
$value = NULL;
if (array_key_exists($offset, $this->_deprecatedProperties)) {
if (isset($this->_deprecated[$offset])) {
$this
->triggerDeprecation($offset);
$value =& $this->_deprecated[$offset];
}
}
elseif (property_exists($this, $offset)) {
$value =& $this->{$offset};
}
return $value;
}
public function offsetSet($offset, $value = NULL) {
if (array_key_exists($offset, $this->_deprecatedProperties)) {
$this->_deprecated[$offset] = $this
->normalizeValue($value);
$this
->triggerDeprecation($offset);
}
else {
$this->{$offset} = $this
->normalizeValue($value);
}
}
public function offsetUnset($offset) {
if (array_key_exists($offset, $this->_deprecatedProperties)) {
unset($this->_deprecated[$offset]);
}
elseif (property_exists($this, $offset)) {
unset($this->{$offset});
}
}
protected function protectedProperties() {
return [
'id',
'class',
'provider',
];
}
private function triggerDeprecation($name) {
if (isset($this->_deprecatedProperties[$name]) && !isset($this->_triggeredDeprecations[$name]) && isset($this->_deprecated[$name])) {
@trigger_error($this->_deprecatedProperties[$name], E_USER_DEPRECATED);
$this->_triggeredDeprecations[$name] = TRUE;
}
}
protected function validateIdentifier(Identifier $id) {
}
}