Skip to content
Snippets Groups Projects
PrivateMessageForm.php 10.5 KiB
Newer Older
Jay Friendly's avatar
Jay Friendly committed
<?php

namespace Drupal\private_message\Form;

use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\ReplaceCommand;
use Drupal\Component\Utility\Html;
use Drupal\Core\Config\ConfigFactoryInterface;
Jay Friendly's avatar
Jay Friendly committed
use Drupal\Core\Entity\ContentEntityForm;
use Drupal\Core\Entity\EntityManagerInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Entity\Entity\EntityFormDisplay;
Jay Friendly's avatar
Jay Friendly committed
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Session\AccountProxyInterface;
use Drupal\Core\TypedData\TypedDataManagerInterface;
use Drupal\private_message\Ajax\PrivateMessageInboxTriggerUpdateCommand;
use Drupal\private_message\Ajax\PrivateMessageLoadNewMessagesCommand;
Jay Friendly's avatar
Jay Friendly committed
use Drupal\private_message\Entity\PrivateMessageThread;
use Drupal\private_message\Entity\PrivateMessageThreadInterface;
Jay Friendly's avatar
Jay Friendly committed
use Drupal\private_message\Service\PrivateMessageServiceInterface;
use Drupal\private_message\Service\PrivateMessageThreadManagerInterface;
use Drupal\user\UserDataInterface;
Jay Friendly's avatar
Jay Friendly committed
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Defines the private message form.
 */
Jay Friendly's avatar
Jay Friendly committed
class PrivateMessageForm extends ContentEntityForm {

  /**
   * A unique instance identifier for the form.
Jay Friendly's avatar
Jay Friendly committed
   *
Jay Friendly's avatar
Jay Friendly committed
   */
Jay Friendly's avatar
Jay Friendly committed

  /**
Jay Friendly's avatar
Jay Friendly committed
   *
   * @var \Drupal\Core\Session\AccountProxyInterface
Jay Friendly's avatar
Jay Friendly committed
   */
  protected $currentUser;

   * The entity type manager service.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entityTypeManager;

  /**
   * The typed data manager service.
   *
   * @var \Drupal\Core\TypedData\TypedDataManagerInterface
   */
  protected $typedDataManager;

   * The user data service.
   *
   * @var \Drupal\user\UserDataInterface
   */
  protected $userData;

  /**
   * The private message configuration.
   * @var \Drupal\Core\Config\ConfigFactoryInterface
   * The private message service.
   *
   * @var \Drupal\private_message\Service\PrivateMessageServiceInterface
   */
  protected $privateMessageService;

  /**
   * The private message thread manager service.
   *
   * @var \Drupal\private_message\Service\PrivateMessageThreadManagerInterface
   */
  protected $privateMessageThreadManager;

  /**
   * The user manager service.
   *
   * @var \Drupal\user\UserStorageInterface
   */
  protected $userManager;

Jay Friendly's avatar
Jay Friendly committed
  /**
   * Constructs a PrivateMessageForm object.
Jay Friendly's avatar
Jay Friendly committed
   *
   * @param \Drupal\Core\Entity\EntityManagerInterface $entityManager
   *   The entity manager service.
Jay Friendly's avatar
Jay Friendly committed
   * @param \Drupal\Core\Session\AccountProxyInterface $currentUser
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
   *   The entity type manager service.
   * @param \Drupal\Core\TypedData\TypedDataManagerInterface $typedDataManager
   *   The typed data manager service.
   * @param \Drupal\user\UserDataInterface $userData
   *   The user data service.
   * @param \Drupal\Core\Config\ConfigFactoryInterface $configFactory
   *   The configuration factory service.
Jay Friendly's avatar
Jay Friendly committed
   * @param \Drupal\private_message\Service\PrivateMessageServiceInterface $privateMessageService
   *   The private message service.
   * @param \Drupal\private_message\Service\PrivateMessageThreadManagerInterface $privateMessageThreadManager
   *   The private message thread manager service.
Jay Friendly's avatar
Jay Friendly committed
   */
  public function __construct(
    EntityManagerInterface $entityManager,
    AccountProxyInterface $currentUser,
    EntityTypeManagerInterface $entityTypeManager,
    TypedDataManagerInterface $typedDataManager,
    UserDataInterface $userData,
    ConfigFactoryInterface $configFactory,
    PrivateMessageServiceInterface $privateMessageService,
    PrivateMessageThreadManagerInterface $privateMessageThreadManager
    parent::__construct($entityManager);
Jay Friendly's avatar
Jay Friendly committed

    $this->currentUser = $currentUser;
    $this->entityTypeManager = $entityTypeManager;
    $this->typedDataManager = $typedDataManager;
    $this->configFactory = $configFactory;
    $this->privateMessageService = $privateMessageService;
    $this->privateMessageThreadManager = $privateMessageThreadManager;
    $this->userManager = $entityManager->getStorage('user');
Jay Friendly's avatar
Jay Friendly committed
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('entity.manager'),
Jay Friendly's avatar
Jay Friendly committed
      $container->get('current_user'),
      $container->get('entity_type.manager'),
      $container->get('typed_data_manager'),
      $container->get('user.data'),
      $container->get('config.factory'),
      $container->get('private_message.service'),
      $container->get('private_message.thread_manager')
  /**
   * Set the ID of the form.
   *
   * This allows for the form to be used multiple times on a page.
   *
   * @param mixed $id
   *   An ID required to be unique each time the form is called on a page.
   */
  public function setFormId($id) {
    $this->formId = Html::escape($id);
  }

Jay Friendly's avatar
Jay Friendly committed
  /**
   * {@inheritdoc}
   */
  public function getFormId() {
    $form_id = parent::getFormId();

    if ($this->formId) {
      $form_id .= '-' . $this->formId;
    }

    return $form_id;
  }

  /**
   * {@inheritdoc}
   */
   public function buildForm(array $form, FormStateInterface $form_state, PrivateMessageThreadInterface $privateMessageThread = NULL) {
    $form = parent::buildForm($form, $form_state);
Jay Friendly's avatar
Jay Friendly committed

    if ($privateMessageThread) {
      $form_state->set('thread_members', $privateMessageThread->getMembers());
Jay Friendly's avatar
Jay Friendly committed
      $form['actions']['submit']['#ajax'] = [
        'callback' => '::ajaxCallback',
      ];
      // Only to do these when using #ajax.
      $form['#attached']['library'][] = 'private_message/message_form';
      $form['message']['widget'][0]['#attributes']['autofocus'] = 'autofocus';
    }
    else {
      // Create a dummy private message thread form so as to retrieve the
      // members element from it.
      $private_message_thread = PrivateMessageThread::create();
      $form_copy = $form;
      $form_state_copy = clone($form_state);
      $form_display = EntityFormDisplay::collectRenderDisplay($private_message_thread, 'default');
      $form_display->buildForm($private_message_thread, $form_copy, $form_state_copy);
      $form['members'] = $form_copy['members'];
    if ($this->configFactory->get('private_message.settings')->get('hide_form_filter_tips')) {
Jay Friendly's avatar
Jay Friendly committed
    return $form;
  }

   * Validate members that have been added to a private message thread.
   *
   * Validates that submitted members have permission to use the Private message
   * system. This validation is not added automatically, as the members field is
   * not part of the Private Message entity, but rather something that has been
   * shoehorned in from the PrivateMessageThread entity, to make for a better
   * user experience, by creating a thread and a message in a single form.
   *
   * @see \Drupal\private_message\Entity\PrivateMessageThead::baseFieldDefinitions
   */
  public function validateMembers(array &$form, FormStateInterface $formState) {
    // The members form element was loaded from the PrivateMessageThread entity
    // type. As it is not a part of the PrivateMessage entity, for which this
    // form is built, the constraints that are a part of the field on the
    // Private Message Thread are not applied. As such, the constraints need to
    // be checked manually.
    // First, get the PrivateMessageThread entity type.
    $entity_type = $this->entityTypeManager->getDefinition('private_message_thread');
    // Next, load the field definitions as defined on the entity type.
    $field_definitions = PrivateMessageThread::baseFieldDefinitions($entity_type);

    // Get the member's field, as this is the field to be validated.
    // Retrieve any members submitted on the form.
    foreach ($formState->getValue('members') as $info) {
      if (is_array($info) && is_numeric($info['target_id'])) {
        $user = $this->userManager->load($info['target_id']);
        if ($user) {
          $members[] = $user;
        }
      }
    }

    // Get a typed data element that can be used for validation.
    $typed_data = $this->typedDataManager->create($members_field, $members);

    // Validate the submitted members.
    // Check to see if any contraint violations were found.
      // Output any errors for found constraint violations.
        $formState->setError($form['members'], $violation->getMessage());
   * Ajax callback for the PrivateMessageForm.
  public function ajaxCallback(array $form, FormStateInterface $formState) {
    $response = new AjaxResponse();
    $form['message']['widget'][0]['value']['#value'] = '';
    $response->addCommand(new ReplaceCommand(NULL, $form));
    $response->addCommand(new PrivateMessageLoadNewMessagesCommand());
    $response->addCommand(new PrivateMessageInboxTriggerUpdateCommand());
   * After build callback for the Private Message Form.
  public function afterBuild(array $form, FormStateInterface $formState) {
    $form['message']['widget'][0]['format']['#access'] = FALSE;
    return $form;
  }

Jay Friendly's avatar
Jay Friendly committed
  /**
   * {@inheritdoc}
   */
  public function save(array $form, FormStateInterface $formState) {
    $status = parent::save($form, $formState);
Jay Friendly's avatar
Jay Friendly committed

    $members = $formState->get('thread_members');
      // Generate an array containing the members of the thread.
      $current_user = $this->userManager->load($this->currentUser->id());

      foreach ($formState->getValue('members') as $info) {
        $user = $this->userManager->load($info['target_id']);
Jay Friendly's avatar
Jay Friendly committed
          $members[] = $user;
        }
      }
    // Get a private message thread containing the given users.
    $private_message_thread = $this->privateMessageService->getThreadForMembers($members);
Jay Friendly's avatar
Jay Friendly committed

    // Save the thread.
    $this->privateMessageThreadManager->saveThread($this->entity, $members, [], $private_message_thread);
    // Save the thread to the form state.
    $formState->set('private_message_thread', $private_message_thread);
Jay Friendly's avatar
Jay Friendly committed
    // Send the user to the private message page. As this thread is the newest,
    // it wll be at the top of the list.
    $formState->setRedirect('entity.private_message_thread.canonical', ['private_message_thread' => $private_message_thread->id()]);
Jay Friendly's avatar
Jay Friendly committed

    return $status;
  }