knowledge-8.x-1.x-dev/src/KnowledgeForm.php

src/KnowledgeForm.php
<?php

namespace Drupal\knowledge;

use Drupal\Component\Datetime\TimeInterface;
use Drupal\Component\Utility\Html;
use Drupal\Core\Datetime\DrupalDateTime;
use Drupal\Core\Entity\ContentEntityForm;
use Drupal\Core\Entity\EntityConstraintViolationListInterface;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Entity\EntityRepositoryInterface;
use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Link;
use Drupal\Core\Render\RendererInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\knowledge\Plugin\Field\FieldType\KnowledgeItemInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Base handler for knowledge forms.
 *
 * @internal
 */
class KnowledgeForm extends ContentEntityForm {

  /**
   * The current user.
   *
   * @var \Drupal\Core\Session\AccountInterface
   */
  protected $currentUser;

  /**
   * The renderer.
   *
   * @var \Drupal\Core\Render\RendererInterface
   */
  protected $renderer;

  /**
   * The entity field manager.
   *
   * @var \Drupal\Core\Entity\EntityFieldManagerInterface
   */
  protected $entityFieldManager;

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('entity.repository'),
      $container->get('current_user'),
      $container->get('renderer'),
      $container->get('entity_type.bundle.info'),
      $container->get('datetime.time'),
      $container->get('entity_field.manager')
    );
  }

  /**
   * Constructs a new KnowledgeForm.
   *
   * @param \Drupal\Core\Entity\EntityRepositoryInterface $entity_repository
   *   The entity repository.
   * @param \Drupal\Core\Session\AccountInterface $current_user
   *   The current user.
   * @param \Drupal\Core\Render\RendererInterface $renderer
   *   The renderer.
   * @param \Drupal\Core\Entity\EntityTypeBundleInfoInterface $entity_type_bundle_info
   *   The entity type bundle service.
   * @param \Drupal\Component\Datetime\TimeInterface $time
   *   The time service.
   * @param \Drupal\Core\Entity\EntityFieldManagerInterface $entity_field_manager
   *   The entity field manager service.
   */
  public function __construct(EntityRepositoryInterface $entity_repository, AccountInterface $current_user, RendererInterface $renderer, ?EntityTypeBundleInfoInterface $entity_type_bundle_info = NULL, ?TimeInterface $time = NULL, ?EntityFieldManagerInterface $entity_field_manager = NULL) {
    parent::__construct($entity_repository, $entity_type_bundle_info, $time);
    $this->currentUser = $current_user;
    $this->renderer = $renderer;
    $this->entityFieldManager = $entity_field_manager;
  }

  /**
   * {@inheritdoc}
   */
  public function form(array $form, FormStateInterface $form_state) {
    /** @var \Drupal\knowledge\KnowledgeInterface $knowledge */
    $knowledge = $this->entity;
    $entity = $this->entityTypeManager->getStorage($knowledge->getKnowledgeedEntityTypeId())->load($knowledge->getKnowledgeedEntityId());
    $field_name = $knowledge->getFieldName();
    $field_definition = $this->entityFieldManager->getFieldDefinitions($entity->getEntityTypeId(), $entity->bundle())[$knowledge->getFieldName()];
    $config = $this->config('user.settings');

    // In several places within this function, we vary $form on:
    // - The current user's permissions.
    // - Whether the current user is authenticated or anonymous.
    // - The 'user.settings' configuration.
    // - The knowledge field's definition.
    $form['#cache']['contexts'][] = 'user.permissions';
    $form['#cache']['contexts'][] = 'user.roles:authenticated';

    $this->renderer->addCacheableDependency($form, $config);
    $this->renderer->addCacheableDependency($form, $field_definition->getConfig($entity->bundle()));

    // Use #knowledge-form as unique jump target, regardless of entity type.
    $form['#id'] = Html::getUniqueId('knowledge_form');
    $form['#theme'] = [
      'knowledge_form__' . $entity->getEntityTypeId() . '__' . $entity->bundle() . '__' . $field_name,
      'knowledge_form',
    ];

    $anonymous_contact = $field_definition->getSetting('anonymous');
    $is_admin = $knowledge->id() && $this->currentUser->hasPermission('administer knowledge');

    if (!$this->currentUser->isAuthenticated() && $anonymous_contact != KnowledgeInterface::ANONYMOUS_MAYNOT_CONTACT) {
      $form['#attached']['library'][] = 'core/drupal.form';
      $form['#attributes']['data-user-info-from-browser'] = TRUE;
    }

    $knowledge_preview = $form_state->get('knowledge_preview');
    if (isset($knowledge_preview)) {
      $form += $knowledge_preview;
    }

    $form['author'] = [];
    // Display author information in a details element for knowledge moderators.
    if ($is_admin) {
      $form['author'] += [
        '#type' => 'details',
        '#title' => $this->t('Administration'),
      ];
    }

    // Prepare default values for form elements.
    if ($is_admin) {
      $status = $knowledge->isPublished() ? KnowledgeInterface::PUBLISHED : KnowledgeInterface::NOT_PUBLISHED;
      if (empty($knowledge_preview)) {
        $form['#title'] = $this->t('Edit knowledge %title', [
          '%title' => $knowledge->label(),
        ]);
      }
    }
    else {
      $status = ($this->currentUser->hasPermission('skip knowledge approval') ? KnowledgeInterface::PUBLISHED : KnowledgeInterface::NOT_PUBLISHED);
    }

    $date = '';
    if ($knowledge->id()) {
      $date = !empty($knowledge->date) ? $knowledge->date : DrupalDateTime::createFromTimestamp($knowledge->getCreatedTime());
    }

    // The uid field is only displayed when a user with the permission
    // 'administer knowledge' is editing an existing knowledge from an
    // authenticated user.
    $owner = $knowledge->getOwner();
    $form['author']['uid'] = [
      '#type' => 'entity_autocomplete',
      '#target_type' => 'user',
      '#default_value' => $owner->isAnonymous() ? NULL : $owner,
      // A knowledge can be made anonymous by leaving this field empty therefore
      // there is no need to list them in the autocomplete.
      '#selection_settings' => ['include_anonymous' => FALSE],
      '#title' => $this->t('Authored by'),
      '#description' => $this->t('Leave blank for %anonymous.', ['%anonymous' => $config->get('anonymous')]),
      '#access' => $is_admin,
    ];

    // Add administrative knowledge publishing options.
    $form['author']['date'] = [
      '#type' => 'datetime',
      '#title' => $this->t('Authored on'),
      '#default_value' => $date,
      '#size' => 20,
      '#access' => $is_admin,
    ];

    $form['author']['status'] = [
      '#type' => 'radios',
      '#title' => $this->t('Status'),
      '#default_value' => $status,
      '#options' => [
        KnowledgeInterface::PUBLISHED => $this->t('Published'),
        KnowledgeInterface::NOT_PUBLISHED => $this->t('Not published'),
      ],
      '#access' => $is_admin,
    ];

    $form = parent::form($form, $form_state);

    $form['revision_log_message']['#access'] = !$knowledge->isNew();

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  protected function actions(array $form, FormStateInterface $form_state) {
    $element = parent::actions($form, $form_state);
    /** @var \Drupal\knowledge\KnowledgeInterface $knowledge */
    $knowledge = $this->entity;
    $entity = $knowledge->getKnowledgeedEntity();
    $field_definition = $this->entityFieldManager->getFieldDefinitions($entity->getEntityTypeId(), $entity->bundle())[$knowledge->getFieldName()];
    $preview_mode = $field_definition->getSetting('preview');

    // No delete action on the knowledge form.
    unset($element['delete']);

    // Mark the submit action as the primary action, when it appears.
    $element['submit']['#button_type'] = 'primary';

    // Only show the save button if knowledge previews are optional or if we are
    // already previewing the submission.
    $element['submit']['#access'] = ($knowledge->id() && $this->currentUser->hasPermission('administer knowledge')) || $preview_mode != DRUPAL_REQUIRED || $form_state->get('knowledge_preview');

    $element['preview'] = [
      '#type' => 'submit',
      '#value' => $this->t('Preview'),
      '#access' => $preview_mode != DRUPAL_DISABLED,
      '#submit' => ['::submitForm', '::preview'],
    ];

    return $element;
  }

  /**
   * {@inheritdoc}
   */
  public function buildEntity(array $form, FormStateInterface $form_state) {
    /** @var \Drupal\knowledge\KnowledgeInterface $knowledge */
    $knowledge = parent::buildEntity($form, $form_state);
    if (!$form_state->isValueEmpty('date') && $form_state->getValue('date') instanceof DrupalDateTime) {
      $knowledge->setCreatedTime($form_state->getValue('date')->getTimestamp());
    }
    else {
      $knowledge->setCreatedTime($this->time->getRequestTime());
    }
    // Empty author ID should revert to anonymous.
    $author_id = $form_state->getValue('uid');
    if ($knowledge->id() && $this->currentUser->hasPermission('administer knowledge')) {
      // Admin can leave the author ID blank to revert to anonymous.
      $author_id = $author_id ?: 0;
    }
    if (is_null($author_id)) {
      $author_id = $this->currentUser->id();
    }
    $knowledge->setOwnerId($author_id);

    $incident_type_id = $knowledge->knowledge_type[0]->entity->getIncidentEntityTypeId();
    $knowledge->incident_type = $incident_type_id;

    return $knowledge;
  }

  /**
   * {@inheritdoc}
   */
  protected function getEditedFieldNames(FormStateInterface $form_state) {
    return array_merge(['created'], parent::getEditedFieldNames($form_state));
  }

  /**
   * {@inheritdoc}
   */
  protected function flagViolations(EntityConstraintViolationListInterface $violations, array $form, FormStateInterface $form_state) {
    // Manually flag violations of fields not handled by the form display.
    foreach ($violations->getByField('created') as $violation) {
      $form_state->setErrorByName('date', $violation->getMessage());
    }
    foreach ($violations->getByField('name') as $violation) {
      $form_state->setErrorByName('name', $violation->getMessage());
    }
    parent::flagViolations($violations, $form, $form_state);
  }

  /**
   * Form submission handler for the 'preview' action.
   *
   * @param array $form
   *   An associative array containing the structure of the form.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The current state of the form.
   */
  public function preview(array &$form, FormStateInterface $form_state) {
    $knowledge_preview = knowledge_preview($this->entity, $form_state);
    $knowledge_preview['#title'] = $this->t('Preview knowledge');
    $form_state->set('knowledge_preview', $knowledge_preview);
    $form_state->setRebuild();
  }

  /**
   * {@inheritdoc}
   */
  public function save(array $form, FormStateInterface $form_state) {
    /** @var \Drupal\knowledge\KnowledgeInterface $knowledge */
    $knowledge = $this->entity;
    $knowledge->setNewRevision(TRUE);
    $entity = $knowledge->getKnowledgeedEntity();

    $field_name = $knowledge->getFieldName();
    $uri = $entity->toUrl();
    $logger = $this->logger('knowledge');
    $status = 0;
    if ($this->currentUser->hasPermission('post knowledge')
      && ($this->currentUser->hasPermission('administer knowledge') || $entity->{$field_name}->status == KnowledgeItemInterface::OPEN)) {
      $status = $knowledge->save();
      $form_state->setValue('kid', $knowledge->id());

      // Add a log entry.
      $logger->notice('Knowledge posted: %subject.', [
        '%subject' => $knowledge->label(),
        'link' => Link::fromTextAndUrl($this->t('View'), $knowledge->toUrl()->setOption('fragment', 'knowledge-' . $knowledge->id()))->toString(),
      ]);

      // Explain the approval queue if necessary.
      if (!$knowledge->isPublished()) {
        if (!$this->currentUser->hasPermission('administer knowledge')) {
          $this->messenger()->addStatus($this->t('Your knowledge has been queued for review by site administrators and will be published after approval.'));
        }
      }
      else {
        $this->messenger()->addStatus($this->t('Your knowledge has been posted.'));
      }
      $query = [];
      // Find the current display page for this knowledge.
      $field_definition = $this->entityFieldManager->getFieldDefinitions($entity->getEntityTypeId(), $entity->bundle())[$field_name];
      /** @var \Drupal\knowledge\KnowledgeStorageInterface $knowledge_storage */
      $knowledge_storage = $this->entityTypeManager->getStorage('knowledge');
      $page = $knowledge_storage->getDisplayOrdinal($knowledge, $field_definition->getSetting('default_mode'), $field_definition->getSetting('per_page'));
      if ($page > 0) {
        $query['page'] = $page;
      }
      // Redirect to the newly posted knowledge.
      $uri->setOption('query', $query);
      $uri->setOption('fragment', 'knowledge-' . $knowledge->id());
    }
    else {
      $logger->warning('Knowledge: unauthorized knowledge submitted or knowledge submitted to a closed post %subject.', ['%subject' => $knowledge->label()]);
      $this->messenger()->addError($this->t('Knowledge: unauthorized knowledge submitted or knowledge submitted to a closed post %subject.', ['%subject' => $knowledge->label()]));
      // Redirect the user to the entity they are linking on.
    }
    $form_state->setRedirectUrl($uri);

    return $status;
  }

}

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

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