xero-8.x-2.x-dev/src/Plugin/DataType/XeroItemBase.php

src/Plugin/DataType/XeroItemBase.php
<?php

namespace Drupal\xero\Plugin\DataType;

use Drupal\Component\Utility\Html;
use Drupal\Core\TypedData\Plugin\DataType\Map;
use Drupal\xero\TypedData\XeroItemInterface;

/**
 * Provides a base class for Xero data.
 */
abstract class XeroItemBase extends Map implements XeroItemInterface {

  /**
   * The Xero property name e.g. Invoice.
   *
   * @var string
   */
  public static $xero_name;

  /**
   * The plural name of the Xero type.
   *
   * @var string
   */
  public static $plural_name;

  /**
   * The label property for the Xero type.
   *
   * @var string
   */
  public static $label;

  /**
   * Determines if the data type has been changed or not.
   *
   * @var bool
   */
  protected $pristine = TRUE;

  /**
   * An array of names of properties that have been explicitly specified.
   *
   * @var string[]
   */
  protected $specifiedPropertyNames = [];

  /**
   * {@inheritdoc}
   */
  public static function getXeroProperty($name) {
    $allowed_props = ['plural_name', 'xero_name', 'label'];
    if (!in_array($name, $allowed_props)) {
      throw new \InvalidArgumentException('Invalid xero property.');
    }

    return static::${$name};
  }

  /**
   * {@inheritdoc}
   */
  public function view(): array {
    $className = substr($this->getName(), 5);
    $item = [
      '#type' => 'container',
      '#attributes' => [
        'class' => ['xero-item', 'xero-item--' . $className],
      ],
    ];

    /** @var \Drupal\Core\TypedData\ComplexDataDefinitionInterface $definition */
    foreach ($this->getDataDefinition()->getPropertyDefinitions() as $name => $definition) {
      $item[$name] = [
        'label' => [
          '#type' => 'label',
          '#title' => $definition->getLabel(),
        ],
        'value' => [
          '#markup' => isset($this->values[$name]) ? Html::escape($this->values[$name]) : '',
        ],
      ];
    }

    return $item;
  }

  /**
   * {@inheritdoc}
   */
  public function onChange($name, $notify = TRUE) {
    $item = $this->get($name);
    if ($item instanceof XeroItemInterface &&
        $item->isPristine() &&
        !$item->getDataDefinition()->isRequired()) {
      // Removes the property name from the specified property names if it is
      // pristine.
      $this->specifiedPropertyNames = array_filter($this->specifiedPropertyNames, function ($propName) use ($name) {
        return $propName !== $name;
      });

      if (empty($this->specifiedPropertyNames)) {
        // Sets the current data type to pristine if there are no more specified
        // property names.
        $this->pristine = TRUE;
      }
    }
    else {
      $this->recordSpecifiedProperty($name);
    }
    parent::onChange($name, $notify);
  }

  /**
   * {@inheritdoc}
   */
  public function getValue() {
    // Update the values and return them, but only include specified properties.
    foreach ($this->getSpecifiedProperties() as $name => $property) {
      $definition = $property->getDataDefinition();
      if (!$definition->isComputed()) {
        $value = $property->getValue();
        // Only write NULL values if the whole map is not NULL.
        if (isset($this->values) || isset($value)) {
          $this->values[$name] = $value;
        }
      }
    }
    return $this->values;
  }

  /**
   * {@inheritdoc}
   */
  public function setValue($values, $notify = TRUE) {
    parent::setValue($values, $notify);

    // The parent method enforces that $values is an array if it is set.
    if (isset($values)) {
      foreach ($values as $name => $property) {
        $this->recordSpecifiedProperty($name);
      }
    }

    $this->pristine = FALSE;
  }

  /**
   * Track which properties on the typed data object have been explicitly set.
   *
   * @param string $name
   *   The property name.
   */
  protected function recordSpecifiedProperty($name) {
    if (!in_array($name, $this->specifiedPropertyNames)) {
      $this->specifiedPropertyNames[] = $name;
    }
  }

  /**
   * {@inheritdoc}
   */
  public function getSpecifiedProperties() {
    $properties = $this->getProperties(FALSE);
    $specifiedProperties = array_intersect_key($properties, array_flip($this->specifiedPropertyNames));
    $writableSpecifiedProperties = array_filter($specifiedProperties,
      fn ($prop) => !$prop->getDataDefinition()->isReadOnly(),
      ARRAY_FILTER_USE_BOTH
    );
    return $writableSpecifiedProperties;
  }

  /**
   * {@inheritdoc}
   */
  public function isPristine() {
    return $this->pristine;
  }

  /**
   * {@inheritdoc}
   */
  public function markAsPristine($notify = TRUE) {
    foreach ($this->getSpecifiedProperties() as $name => $property) {
      if ($property->getDataDefinition()->isRequired()) {
        continue;
      }

      if ($property instanceof XeroItemInterface) {
        $property->markAsPristine(FALSE);
      }
      elseif (is_a($property, '\Drupal\xero\Plugin\DataType\XeroItemList')) {
        foreach ($property as $index => $child) {
          $child->markAsPristine(FALSE);
        }
      }

      $this->specifiedPropertyNames = array_diff($this->specifiedPropertyNames, [$name]);
    }
    $this->pristine = TRUE;

    if ($notify && $this->parent !== NULL) {
      $this->parent->onChange($this->name);
    }
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc