entity_legal-4.0.x-dev/src/Entity/EntityLegalDocument.php

src/Entity/EntityLegalDocument.php
<?php

declare(strict_types=1);

namespace Drupal\entity_legal\Entity;

use Drupal\Component\Utility\Xss;
use Drupal\Core\Cache\Cache;
use Drupal\Core\Config\Entity\ConfigEntityBundleBase;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Url;
use Drupal\entity_legal\EntityLegalDocumentInterface;
use Drupal\entity_legal\EntityLegalDocumentVersionInterface;
use Drupal\entity_legal\Form\EntityLegalDocumentAcceptanceForm;
use Drupal\field\Entity\FieldConfig;
use Drupal\field\Entity\FieldStorageConfig;

/**
 * Defines the entity legal document entity.
 *
 * @ConfigEntityType(
 *   id = "entity_legal_document",
 *   label = @Translation("Legal document"),
 *   handlers = {
 *     "access" = "Drupal\entity_legal\EntityLegalDocumentAccessControlHandler",
 *     "list_builder" = "Drupal\entity_legal\EntityLegalDocumentListBuilder",
 *     "form" = {
 *       "add" = "Drupal\entity_legal\Form\EntityLegalDocumentForm",
 *       "edit" = "Drupal\entity_legal\Form\EntityLegalDocumentForm",
 *       "delete" = "Drupal\Core\Entity\EntityDeleteForm"
 *     }
 *   },
 *   config_prefix = "document",
 *   admin_permission = "administer entity legal",
 *   bundle_of = "entity_legal_document_version",
 *   entity_keys = {
 *     "id" = "id",
 *     "label" = "label"
 *   },
 *   links = {
 *     "delete-form" = "/admin/structure/legal/manage/{entity_legal_document}/delete",
 *     "edit-form" = "/admin/structure/legal/manage/{entity_legal_document}",
 *     "collection" = "/admin/structure/legal",
 *     "canonical" = "/legal/document/{entity_legal_document}",
 *   },
 *   config_export = {
 *     "id",
 *     "label",
 *     "require_signup",
 *     "require_existing",
 *     "settings",
 *   },
 * )
 */
class EntityLegalDocument extends ConfigEntityBundleBase implements EntityLegalDocumentInterface {

  /**
   * The legal document ID.
   */
  protected string $id;

  /**
   * The human-readable label of the legal document.
   */
  protected string $label;

  /**
   * Require new users to accept this document on signup.
   */
  protected bool $require_signup = FALSE;

  /**
   * Require existing users to accept this document.
   */
  protected bool $require_existing = FALSE;

  /**
   * Am array of additional data related to the legal document.
   */
  protected array $settings = [];

  /**
   * {@inheritdoc}
   */
  public static function preCreate(EntityStorageInterface $storage, array &$values): void {
    parent::preCreate($storage, $values);
    if (empty($values['settings']['title_pattern'])) {
      $values['settings']['title_pattern'] = '[entity_legal_document:label]';
    }
  }

  /**
   * {@inheritdoc}
   */
  public function delete(): void {
    if (!$this->isNew()) {
      // Delete all associated versions.
      $versions = $this->getAllVersions();
      foreach ($versions as $version) {
        $version->delete();
      }
    }

    parent::delete();
  }

  /**
   * {@inheritdoc}
   */
  public function getAcceptanceForm(): array {
    /** @var \Drupal\entity_legal\Form\EntityLegalDocumentAcceptanceForm $form */
    $form = \Drupal::classResolver()->getInstanceFromDefinition(EntityLegalDocumentAcceptanceForm::class);
    $form->setDocument($this);
    return \Drupal::formBuilder()->getForm($form);
  }

  /**
   * {@inheritdoc}
   */
  public function getAllVersions(): array {
    $query = \Drupal::entityQuery(ENTITY_LEGAL_DOCUMENT_VERSION_ENTITY_NAME)
      ->accessCheck(FALSE)
      ->condition('document_name', $this->id());
    $results = $query->execute();
    if (!empty($results)) {
      return \Drupal::entityTypeManager()
        ->getStorage(ENTITY_LEGAL_DOCUMENT_VERSION_ENTITY_NAME)
        ->loadMultiple($results);
    }
    return [];
  }

  /**
   * {@inheritdoc}
   */
  public function getPublishedVersion(): ?EntityLegalDocumentVersionInterface {
    $storage = $this->entityTypeManager()->getStorage(ENTITY_LEGAL_DOCUMENT_VERSION_ENTITY_NAME);
    $ids = $storage->getQuery()
      ->accessCheck(FALSE)
      ->condition('document_name', $this->id())
      ->condition('published', TRUE)
      ->execute();

    if (!$ids) {
      return NULL;
    }
    $id = reset($ids);
    $publishedVersion = $storage->load($id);

    $currentLangCode = \Drupal::languageManager()->getCurrentLanguage()->getId();

    if ($publishedVersion->hasTranslation($currentLangCode)) {
      $publishedVersion = $publishedVersion->getTranslation($currentLangCode);
    }

    return $publishedVersion;
  }

  /**
   * {@inheritdoc}
   */
  public function setPublishedVersion(EntityLegalDocumentVersionInterface $versionEntity): bool {
    if (!$versionEntity->isNew()) {
      /** @var \Drupal\entity_legal\EntityLegalDocumentVersionInterface $unchangedVersion */
      $unchangedVersion = $this->entityTypeManager()
        ->getStorage(ENTITY_LEGAL_DOCUMENT_VERSION_ENTITY_NAME)
        ->loadUnchanged($versionEntity->id());
      if ($unchangedVersion->isPublished()) {
        // An existing entity is already published.
        return TRUE;
      }
    }

    // If the version entity is not of this bundle, fail.
    if ($versionEntity->bundle() != $this->id()) {
      return FALSE;
    }

    // Unpublish a published version.
    if ($actualPublishedVersion = $this->getPublishedVersion()) {
      $actualPublishedVersion->unpublish()->save();
    }

    $versionEntity->publish()->save();

    return TRUE;
  }

  /**
   * {@inheritdoc}
   */
  public function getAcceptanceLabel(): string {
    $label = '';
    $publishedVersion = $this->getPublishedVersion();

    if ($publishedVersion) {
      $label = $publishedVersion->get('acceptance_label')->value;
    }

    $label = \Drupal::service('token')->replace($label, [ENTITY_LEGAL_DOCUMENT_ENTITY_NAME => $this]);

    return Xss::filter($label);
  }

  /**
   * {@inheritdoc}
   */
  public function toUrl($rel = 'canonical', array $options = []): Url {
    // Unless language was already provided, avoid setting an explicit language.
    $options += ['language' => NULL];
    return parent::toUrl($rel, $options);
  }

  /**
   * {@inheritdoc}
   */
  public function userMustAgree(bool $newUser = FALSE, ?AccountInterface $account = NULL): bool {
    // User cannot agree unless there is a published version.
    if (!$this->getPublishedVersion()) {
      return FALSE;
    }

    if (empty($account)) {
      $account = \Drupal::currentUser();
    }

    if ($newUser) {
      return !empty($this->require_signup);
    }
    else {
      return !empty($this->require_existing) && $account->hasPermission($this->getPermissionExistingUser());
    }
  }

  /**
   * {@inheritdoc}
   */
  public function userHasAgreed(?AccountInterface $account = NULL): bool {
    $account = $account ?? \Drupal::currentUser();
    return count($this->getAcceptances($account)) > 0;
  }

  /**
   * {@inheritdoc}
   */
  public function getAcceptances(?AccountInterface $account = NULL, bool $published = TRUE): array {
    $acceptances = [];
    $versions = [];

    if ($published) {
      $versions[] = $this->getPublishedVersion();
    }
    else {
      $versions = $this->getAllVersions();
    }

    /** @var \Drupal\entity_legal\EntityLegalDocumentVersionInterface $version */
    foreach ($versions as $version) {
      $acceptances += $version->getAcceptances($account);
    }

    return $acceptances;
  }

  /**
   * {@inheritdoc}
   */
  public function getPermissionView(): string {
    return 'legal view ' . $this->id();
  }

  /**
   * {@inheritdoc}
   */
  public function getPermissionExistingUser(): string {
    return 'legal re-accept ' . $this->id();
  }

  /**
   * {@inheritdoc}
   */
  public function getAcceptanceDeliveryMethod(bool $newUser = FALSE): ?string {
    $settingGroup = $newUser ? 'new_users' : 'existing_users';
    return $this->get('settings')[$settingGroup]['require_method'] ?? NULL;
  }

  /**
   * {@inheritdoc}
   */
  public function save() {
    $status = parent::save();

    if ($status == SAVED_NEW && !\Drupal::isConfigSyncing()) {
      // Add or remove the body field, as needed.
      $field = FieldConfig::loadByName('entity_legal_document_version', $this->id(), 'entity_legal_document_text');
      if (empty($field)) {
        FieldConfig::create([
          'field_storage' => FieldStorageConfig::loadByName('entity_legal_document_version', 'entity_legal_document_text'),
          'bundle' => $this->id(),
          'label' => 'Document text',
          'settings' => ['display_summary' => FALSE],
        ])->save();

        // Assign widget settings for the 'default' form mode.
        \Drupal::service('entity_display.repository')->getFormDisplay('entity_legal_document_version', $this->id(), 'default')
          ->setComponent('entity_legal_document_text', [
            'type' => 'text_textarea_with_summary',
          ])
          ->save();

        // Assign display settings for 'default' view mode.
        \Drupal::service('entity_display.repository')->getViewDisplay('entity_legal_document_version', $this->id(), 'default')
          ->setComponent('entity_legal_document_text', [
            'label' => 'hidden',
            'type' => 'text_default',
          ])
          ->save();
      }
    }

    else {
      Cache::invalidateTags(["entity_legal_document:{$this->id()}"]);
    }

    return $status;
  }

}

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

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