class OpignoPrivateMessageThreadForm in Opigno messaging 3.x
Custom form to create/edit private message thread.
@package Drupal\opigno_messaging\Form
Hierarchy
- class \Drupal\Core\Form\FormBase implements ContainerInjectionInterface, FormInterface uses DependencySerializationTrait, LoggerChannelTrait, MessengerTrait, RedirectDestinationTrait, StringTranslationTrait
- class \Drupal\opigno_messaging\Form\OpignoPrivateMessageThreadForm
Expanded class hierarchy of OpignoPrivateMessageThreadForm
1 file declares its use of OpignoPrivateMessageThreadForm
- OpignoMessageThreadController.php in src/
Controller/ OpignoMessageThreadController.php
File
- src/
Form/ OpignoPrivateMessageThreadForm.php, line 32
Namespace
Drupal\opigno_messaging\FormView source
class OpignoPrivateMessageThreadForm extends FormBase {
/**
* The current user ID.
*
* @var int
*/
protected $currentUid;
/**
* The loaded current user entity.
*
* @var \Drupal\Core\Entity\EntityInterface|null
*/
protected $currentUser = NULL;
/**
* The PM thread entity storage.
*
* @var \Drupal\Core\Entity\EntityStorageInterface|null
*/
protected $threadStorage = NULL;
/**
* The PM entity storage.
*
* @var \Drupal\Core\Entity\EntityStorageInterface|null
*/
protected $messageStorage = NULL;
/**
* The date formatter service.
*
* @var \Drupal\Core\Datetime\DateFormatterInterface
*/
protected $dateFormatter;
/**
* Learning path members manager service.
*
* @var \Drupal\opigno_learning_path\LearningPathMembersManager
*/
protected $lpMembersManager;
/**
* Opigno PM manager service.
*
* @var \Drupal\opigno_messaging\Services\OpignoMessageThread
*/
protected $pmService;
/**
* PM thread view builder service.
*
* @var \Drupal\Core\Entity\EntityViewBuilderInterface
*/
protected $threadViewBuilder;
/**
* OpignoPrivateMessageThreadForm constructor.
*
* @param \Drupal\Core\Session\AccountInterface $account
* The current user account.
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager service.
* @param \Drupal\Core\Datetime\DateFormatterInterface $date_formatter
* The date formatter service.
* @param \Drupal\opigno_learning_path\LearningPathMembersManager $lp_members_manager
* The LP members manager service.
* @param \Drupal\opigno_messaging\Services\OpignoMessageThread $pm_service
* The private messages manager service.
*/
public function __construct(AccountInterface $account, EntityTypeManagerInterface $entity_type_manager, DateFormatterInterface $date_formatter, LearningPathMembersManager $lp_members_manager, OpignoMessageThread $pm_service) {
$this->currentUid = (int) $account
->id();
$this->dateFormatter = $date_formatter;
$this->lpMembersManager = $lp_members_manager;
$this->pmService = $pm_service;
$this->threadViewBuilder = $entity_type_manager
->getViewBuilder('private_message_thread');
try {
$this->threadStorage = $entity_type_manager
->getStorage('private_message_thread');
$this->messageStorage = $entity_type_manager
->getStorage('private_message');
$this->currentUser = $entity_type_manager
->getStorage('user')
->load($this->currentUid);
} catch (PluginNotFoundException|InvalidPluginDefinitionException $e) {
watchdog_exception('opigno_messaging_exception', $e);
}
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static($container
->get('current_user'), $container
->get('entity_type.manager'), $container
->get('date.formatter'), $container
->get('opigno_learning_path.members.manager'), $container
->get('opigno_messaging.manager'));
}
/**
* {@inheritdoc}
*/
public function getFormId() {
return 'opigno_pm_thread_form';
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state, int $tid = 0) {
$plugin_instance = $this->lpMembersManager
->createInstance('recipients_plugin');
if (!$this->currentUser instanceof UserInterface || !$plugin_instance instanceof RecipientsPlugin) {
return [];
}
// Don't render form for existing 1-to-1 messages.
$thread = NULL;
if ($tid && $this->threadStorage instanceof EntityStorageInterface) {
$thread = $this->threadStorage
->load($tid);
if (!$thread instanceof PrivateMessageThreadInterface || count($thread
->getMembers()) <= 2) {
return [];
}
}
// Check if the thread is a group discussion.
$is_group = $thread instanceof PrivateMessageThreadInterface && $thread
->hasField('field_create_group') && $thread
->get('field_create_group')
->getString();
$form['#attributes']['class'] = $is_group ? [
'opigno-pm-thread-form__edit',
] : [
'opigno-pm-thread-form__add',
];
// Add the placeholder for the status messages.
$form['status_messages_container'] = [
'#type' => 'container',
'#attributes' => [
'class' => [
'opigno-status-messages-container',
],
],
'#weight' => -50,
];
// Add the "Create a group" checkbox.
$form['create_group'] = [
'#type' => 'checkbox',
'#title' => $this
->t('Create a group'),
'#default_value' => $is_group,
'#weight' => -20,
'#attributes' => [
'class' => [
'checkbox-slider',
],
],
];
// Hide the checkbox on the thread editing form.
if ($is_group) {
$form['create_group']['#prefix'] = '<div class="hidden">';
$form['create_group']['#suffix'] = '</div>';
}
$form['group_data_container'] = [
'#type' => 'container',
'#tree' => FALSE,
'#states' => [
'visible' => [
':input[name="create_group"]' => [
'checked' => TRUE,
],
],
],
'#weight' => -15,
];
// Add the subject.
$form['group_data_container']['subject'] = [
'#type' => 'textfield',
'#title' => $this
->t('Subject'),
'#placeholder' => $this
->t('Enter a subject'),
'#default_value' => $is_group ? $thread
->get('field_pm_subject')
->getString() : '',
'#maxlength' => 128,
];
// The group picture field.
$timestamp = strtotime('now');
$year = $this->dateFormatter
->format($timestamp, 'custom', 'Y');
$month = $this->dateFormatter
->format($timestamp, 'custom', 'm');
$form['group_data_container']['image'] = [
'#type' => 'managed_file',
'#title' => $this
->t('Picture'),
'#upload_validators' => [
'file_validate_extensions' => [
'gif png jpg jpeg',
],
],
'#upload_location' => "public://{$year}-{$month}",
'#theme' => 'image_widget',
'#preview_image_style' => 'private_message_group_upload',
'#default_value' => $is_group && !$thread
->get('field_image')
->isEmpty() ? [
$thread
->get('field_image')->target_id,
] : '',
'#multiple' => FALSE,
];
// Add members selection tool and message field.
$plugin_instance
->getMembersForm($form, $form_state, $this->currentUser, $is_group);
if ($is_group) {
$form['users_to_send']['#default_value'] = $thread
->getMembersId();
// Display the extra checkbox to manage members on thread edit form.
$form['edit_members'] = [
'#type' => 'checkbox',
'#title' => $this
->t('Manage participants'),
'#ajax' => [
'callback' => '::showMembersAjax',
'event' => 'change',
],
'#weight' => -5,
'#attributes' => [
'class' => [
'checkbox-slider',
],
],
];
}
if (!$tid) {
$form['message'] = [
'#type' => 'text_format',
'#title' => $this
->t('Message'),
'#title_display' => 'invisible',
'#format' => 'basic_html',
'#required' => TRUE,
];
}
// Actions.
$form['actions'] = [
'#type' => 'actions',
];
$form['actions']['submit'] = [
'#type' => 'submit',
'#value' => $is_group ? $this
->t('Save') : $this
->t('Send'),
'#ajax' => [
'callback' => '::ajaxSubmit',
],
'#attributes' => [
'class' => [
'use-ajax-submit',
],
],
];
return $form;
}
/**
* {@inheritdoc}
*/
public function validateForm(array &$form, FormStateInterface $form_state) {
parent::validateForm($form, $form_state);
$selected_users = $form_state
->getValue('users_to_send', []);
// Display the error message if fields are empty.
if (!$selected_users) {
$form_state
->setErrorByName('users_to_send', t("Please select at least one user to send your message."));
}
// Force the group creation if there are more than 2 members selected.
$is_group = $form_state
->getValue('create_group', FALSE);
if (count($selected_users) > 1 && !$is_group) {
$form_state
->setErrorByName('create_group', t('Please create a group to send the message to the several participants.'));
}
// Don't create a group if there are only 2 members.
if (count($selected_users) === 1 && $is_group) {
$form_state
->setErrorByName('create_group', t('Please use one-to-one discussion if you want to send the message only to one person.'));
}
// Add the error message if the subject isn't set for the group.
$subject = $form_state
->getValue('subject');
if ($is_group && !$subject) {
$form_state
->setErrorByName('subject', t('Subject field is required for the group discussion.'));
}
}
/**
* Hide/show members selector depending on the checkbox value.
*
* @param array $form
* The form.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The form state object.
*
* @return \Drupal\Core\Ajax\AjaxResponse
* The AJAX response object.
*/
public function showMembersAjax(array $form, FormStateInterface $form_state) : AjaxResponse {
$response = new AjaxResponse();
$command = $form_state
->getValue('edit_members') ? 'removeClass' : 'addClass';
$response
->addCommand(new InvokeCommand('#users-to-send', $command, [
'hidden',
]));
return $response;
}
/**
* The custom form AJAX submit callback.
*
* @param array $form
* The form.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The form state object.
*
* @return \Drupal\Core\Ajax\AjaxResponse
* The AJAX response.
*/
public function ajaxSubmit(array $form, FormStateInterface $form_state) : AjaxResponse {
$response = new AjaxResponse();
// Check if there are any errors and display them.
if ($form_state
->getErrors()) {
$status_messages = [
'#type' => 'status_messages',
'#weight' => -50,
];
$response
->addCommand(new HtmlCommand('.modal-ajax .modal-body .opigno-status-messages-container', $status_messages));
$response
->setStatusCode(400);
return $response;
}
// That's impossible to render the ajax form in the ajax callback, so we'll
// reload the page to display the updated content.
$build = $form_state
->getBuildInfo();
$tid = $build['args'][0] ?? 0;
if ($tid) {
$url = Url::fromRoute('entity.private_message_thread.canonical', [
'private_message_thread' => $tid,
]);
}
else {
$url = Url::fromRoute('private_message.private_message_page');
}
$response
->addCommand(new RedirectCommand($url
->toString()));
return $response;
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
if (!$this->messageStorage instanceof EntityStorageInterface || !$this->threadStorage instanceof EntityStorageInterface) {
return;
}
// Prepare the list of thread members.
$members = $form_state
->getValue('users_to_send', []);
array_unshift($members, $this->currentUid);
// Check if the thread can be taken from the form.
$thread = NULL;
$build = $form_state
->getBuildInfo();
$tid = $build['args'][0] ?? 0;
if ($tid) {
$thread = $this->threadStorage
->load($tid);
}
// Update the members list, it can be changed for existing thread.
if ($thread instanceof PrivateMessageThreadInterface) {
$thread
->set('members', $members);
}
else {
$thread = $this->pmService
->getThreadForMembers($members);
}
// Set the thread info.
$create_group = $form_state
->getValue('create_group', FALSE);
if (count($members) > 2 && $create_group) {
// Set the author only if no other value was set before.
if ($thread
->hasField('field_author') && $thread
->get('field_author')
->isEmpty()) {
$thread
->set('field_author', $this->currentUid);
}
// Don't update the subject/image/members/etc if the user picks the same
// members list that is exactly the same as in any existing thread.
if ($thread
->hasField('field_author') && (int) $thread
->get('field_author')
->getString() === $this->currentUid) {
$subject = $form_state
->getValue('subject', 'Discussion');
$thread
->set('field_pm_subject', $subject);
$thread
->set('field_create_group', TRUE);
// Set/unset the group image.
$image = $form_state
->getValue('image');
$thread
->set('field_image', $image);
}
}
$text = $form_state
->getValue('message', '');
$msg = NULL;
if ($text) {
// Create the message, add it to the thread and save.
$msg = $this->messageStorage
->create([
'message' => $text,
]);
try {
$msg
->save();
} catch (EntityStorageException $e) {
watchdog_exception('opigno_messaging_exception', $e);
}
}
if ($msg instanceof PrivateMessageInterface) {
$thread
->addMessage($msg);
}
try {
$thread
->save();
if ($msg instanceof PrivateMessageInterface) {
$this->pmService
->sendEmailToThreadMembers($thread, $msg);
}
} catch (EntityStorageException $e) {
watchdog_exception('opigno_messaging_exception', $e);
}
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
DependencySerializationTrait:: |
protected | property | ||
DependencySerializationTrait:: |
protected | property | ||
DependencySerializationTrait:: |
public | function | 2 | |
DependencySerializationTrait:: |
public | function | 2 | |
FormBase:: |
protected | property | The config factory. | 3 |
FormBase:: |
protected | property | The request stack. | 1 |
FormBase:: |
protected | property | The route match. | |
FormBase:: |
protected | function | Retrieves a configuration object. | |
FormBase:: |
protected | function | Gets the config factory for this form. | 3 |
FormBase:: |
private | function | Returns the service container. | |
FormBase:: |
protected | function | Gets the current user. | |
FormBase:: |
protected | function | Gets the request object. | |
FormBase:: |
protected | function | Gets the route match. | |
FormBase:: |
protected | function | Gets the logger for a specific channel. | |
FormBase:: |
protected | function | Returns a redirect response object for the specified route. | |
FormBase:: |
public | function | Resets the configuration factory. | |
FormBase:: |
public | function | Sets the config factory for this form. | |
FormBase:: |
public | function | Sets the request stack object to use. | |
LoggerChannelTrait:: |
protected | property | The logger channel factory service. | |
LoggerChannelTrait:: |
protected | function | Gets the logger for a specific channel. | |
LoggerChannelTrait:: |
public | function | Injects the logger channel factory. | |
MessengerTrait:: |
protected | property | The messenger. | 27 |
MessengerTrait:: |
public | function | Gets the messenger. | 27 |
MessengerTrait:: |
public | function | Sets the messenger. | |
OpignoPrivateMessageThreadForm:: |
protected | property | The current user ID. | |
OpignoPrivateMessageThreadForm:: |
protected | property | The loaded current user entity. | |
OpignoPrivateMessageThreadForm:: |
protected | property | The date formatter service. | |
OpignoPrivateMessageThreadForm:: |
protected | property | Learning path members manager service. | |
OpignoPrivateMessageThreadForm:: |
protected | property | The PM entity storage. | |
OpignoPrivateMessageThreadForm:: |
protected | property | Opigno PM manager service. | |
OpignoPrivateMessageThreadForm:: |
protected | property | The PM thread entity storage. | |
OpignoPrivateMessageThreadForm:: |
protected | property | PM thread view builder service. | |
OpignoPrivateMessageThreadForm:: |
public | function | The custom form AJAX submit callback. | |
OpignoPrivateMessageThreadForm:: |
public | function |
Form constructor. Overrides FormInterface:: |
|
OpignoPrivateMessageThreadForm:: |
public static | function |
Instantiates a new instance of this class. Overrides FormBase:: |
|
OpignoPrivateMessageThreadForm:: |
public | function |
Returns a unique string identifying the form. Overrides FormInterface:: |
|
OpignoPrivateMessageThreadForm:: |
public | function | Hide/show members selector depending on the checkbox value. | |
OpignoPrivateMessageThreadForm:: |
public | function |
Form submission handler. Overrides FormInterface:: |
|
OpignoPrivateMessageThreadForm:: |
public | function |
Form validation handler. Overrides FormBase:: |
|
OpignoPrivateMessageThreadForm:: |
public | function | OpignoPrivateMessageThreadForm constructor. | |
RedirectDestinationTrait:: |
protected | property | The redirect destination service. | 1 |
RedirectDestinationTrait:: |
protected | function | Prepares a 'destination' URL query parameter for use with \Drupal\Core\Url. | |
RedirectDestinationTrait:: |
protected | function | Returns the redirect destination service. | |
RedirectDestinationTrait:: |
public | function | Sets the redirect destination service. | |
StringTranslationTrait:: |
protected | property | The string translation service. | 4 |
StringTranslationTrait:: |
protected | function | Formats a string containing a count of items. | |
StringTranslationTrait:: |
protected | function | Returns the number of plurals supported by a given language. | |
StringTranslationTrait:: |
protected | function | Gets the string translation service. | |
StringTranslationTrait:: |
public | function | Sets the string translation service to use. | 2 |
StringTranslationTrait:: |
protected | function | Translates a string to the current language or to a given language. |