Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • project/private_message
  • issue/private_message-3102091
  • issue/private_message-3184577
  • issue/private_message-3186067
  • issue/private_message-3095101
  • issue/private_message-3164669
  • issue/private_message-3203419
  • issue/private_message-2942602
  • issue/private_message-3095232
  • issue/private_message-3216927
  • issue/private_message-3217509
  • issue/private_message-3232483
  • issue/private_message-3226703
  • issue/private_message-3231433
  • issue/private_message-3137648
  • issue/private_message-3094213
  • issue/private_message-3156194
  • issue/private_message-3183628
  • issue/private_message-3231711
  • issue/private_message-3142633
  • issue/private_message-3042276
  • issue/private_message-3236702
  • issue/private_message-3239279
  • issue/private_message-3239575
  • issue/private_message-3281258
  • issue/private_message-3243139
  • issue/private_message-3195730
  • issue/private_message-3184550
  • issue/private_message-3041599
  • issue/private_message-3179135
  • issue/private_message-3029461
  • issue/private_message-3245298
  • issue/private_message-3250059
  • issue/private_message-3261287
  • issue/private_message-3221475
  • issue/private_message-3261292
  • issue/private_message-3050359
  • issue/private_message-3249348
  • issue/private_message-3248258
  • issue/private_message-3082478
  • issue/private_message-3265901
  • issue/private_message-3300046
  • issue/private_message-2947762
  • issue/private_message-3321802
  • issue/private_message-3051300
  • issue/private_message-3207855
  • issue/private_message-3099166
  • issue/private_message-3344346
  • issue/private_message-3297889
  • issue/private_message-3261083
  • issue/private_message-3151941
  • issue/private_message-3317985
  • issue/private_message-3285143
  • issue/private_message-3337185
  • issue/private_message-3337186
  • issue/private_message-3337189
  • issue/private_message-3322900
  • issue/private_message-2977313
  • issue/private_message-3333001
  • issue/private_message-3337216
  • issue/private_message-3088743
  • issue/private_message-3337221
  • issue/private_message-3337222
  • issue/private_message-3343726
  • issue/private_message-3337224
  • issue/private_message-3339976
  • issue/private_message-3297888
  • issue/private_message-3355273
  • issue/private_message-3356586
  • issue/private_message-3378251
  • issue/private_message-3391546
  • issue/private_message-3381016
  • issue/private_message-3412209
  • issue/private_message-3414396
  • issue/private_message-3204985
  • issue/private_message-3043898
  • issue/private_message-3384791
  • issue/private_message-3121606
  • issue/private_message-3035510
  • issue/private_message-3337240
  • issue/private_message-3417386
  • issue/private_message-3183523
  • issue/private_message-3386742
  • issue/private_message-3322629
  • issue/private_message-3322625
  • issue/private_message-3417433
  • issue/private_message-3241221
  • issue/private_message-3417449
  • issue/private_message-3417461
  • issue/private_message-3271454
  • issue/private_message-3417457
  • issue/private_message-3417644
  • issue/private_message-3417654
  • issue/private_message-3417705
  • issue/private_message-3417731
  • issue/private_message-3417742
  • issue/private_message-3417747
  • issue/private_message-3417751
  • issue/private_message-3417752
  • issue/private_message-3212104
  • issue/private_message-3427223
  • issue/private_message-3365542
  • issue/private_message-3424499
  • issue/private_message-3432140
  • issue/private_message-3439400
  • issue/private_message-3454771
  • issue/private_message-3456956
  • issue/private_message-3464363
  • issue/private_message-3464371
  • issue/private_message-3470070
  • issue/private_message-3470072
  • issue/private_message-3470928
  • issue/private_message-3475462
  • issue/private_message-2987189
  • issue/private_message-3477667
  • issue/private_message-3477873
  • issue/private_message-3478456
  • issue/private_message-3054106
  • issue/private_message-3479391
  • issue/private_message-3417748
  • issue/private_message-3480219
  • issue/private_message-3482103
  • issue/private_message-3482504
  • issue/private_message-3482630
  • issue/private_message-2971692
  • issue/private_message-3484561
  • issue/private_message-3484828
  • issue/private_message-3484854
  • issue/private_message-3485607
  • issue/private_message-3486915
  • issue/private_message-3487175
  • issue/private_message-3482416
  • issue/private_message-3487689
  • issue/private_message-3487705
  • issue/private_message-3487770
  • issue/private_message-3488097
  • issue/private_message-3484915
  • issue/private_message-3488247
  • issue/private_message-3488508
  • issue/private_message-3487692
  • issue/private_message-3484246
  • issue/private_message-3488863
  • issue/private_message-3486047
  • issue/private_message-3489091
  • issue/private_message-3489205
  • issue/private_message-3490037
  • issue/private_message-3490119
  • issue/private_message-3490456
  • issue/private_message-3489224
  • issue/private_message-3490346
  • issue/private_message-3490816
  • issue/private_message-3491252
  • issue/private_message-3491271
  • issue/private_message-3492177
  • issue/private_message-3492289
  • issue/private_message-3331865
  • issue/private_message-3497800
  • issue/private_message-3499154
  • issue/private_message-3499926
  • issue/private_message-3501083
  • issue/private_message-3501286
  • issue/private_message-3501694
  • issue/private_message-3502128
  • issue/private_message-3502140
  • issue/private_message-3502159
  • issue/private_message-3502162
  • issue/private_message-3502180
  • issue/private_message-3502186
  • issue/private_message-3502190
  • issue/private_message-3502496
  • issue/private_message-3504372
  • issue/private_message-3512770
  • issue/private_message-3513969
173 results
Show changes
Commits on Source (4)
Showing
with 260 additions and 201 deletions
(($, Drupal) => {
/**
* Override drupal selectHandler function
* @param {jQuery.Event} event The event
* @param {Object} ui UI
* @return {boolean} Members ban
*/
function membersBanSelectHandler(event, ui) {
let valueField = $(event.target);
if ($(event.target).hasClass('private-message-ban-autocomplete')) {
const valueFieldName = 'banned_user';
if ($(`input[name=${valueFieldName}]`).length > 0) {
valueField = $(`input[name=${valueFieldName}]`);
// Update the labels too.
const labels = Drupal.autocomplete.splitValues(event.target.value);
labels.pop();
labels.push(ui.item.label);
event.target.value = labels.join(', ');
}
}
const terms = Drupal.autocomplete.splitValues(valueField.val());
// Remove the current input.
terms.pop();
// Add the selected item.
terms.push(ui.item.value);
valueField.val(terms.join(', '));
// Return false to tell jQuery UI that we've filled in the value already.
return false;
}
Drupal.behaviors.privateMessageBan = {
attach() {
// Attach custom select handler to fields with class.
$('input.private-message-ban-autocomplete').autocomplete({
select: membersBanSelectHandler,
});
},
};
})(jQuery, Drupal);
/**
* @file
* Adds JavaScript functionality to the uninstall preparation confirm page.
*/
(($, Drupal, window, once) => {
function uninstallButtonWatcher(context) {
$(
once(
'uninstall-button-watcher',
'#private-message-admin-uninstall-form #edit-submit',
context,
),
).each(() => {
$(this).click(() => {
return window.confirm(
Drupal.t(
'This will delete all private message content from the database. Are you absolutely sure you wish to proceed?',
),
);
});
});
}
Drupal.behaviors.privateMessageUninstallPrepConfirm = {
attach(context) {
uninstallButtonWatcher(context);
},
};
})(jQuery, Drupal, window, once);
......@@ -63,16 +63,3 @@ message_form:
- core/once
- core/drupalSettings
- private_message/browser_notification
uninstall_page:
js:
js/private_message_uninstall_prep_confirm.js: {}
dependencies:
- core/jquery
- core/once
ban_autocomplete:
js:
js/private_message_ban_user_autocomplete.js: {}
dependencies:
- core/jquery
......@@ -130,6 +130,13 @@ private_message.admin_config.uninstall:
requirements:
_permission: 'administer private message module'
private_message.admin_config.uninstall_confirm:
path: '/admin/config/private-message/uninstall/confirm'
defaults:
_form: '\Drupal\private_message\Form\AdminUninstallForm'
requirements:
_permission: 'administer private message module'
private_message.ajax_callback:
path: '/private-message/ajax-callback/{op}'
defaults:
......@@ -147,15 +154,6 @@ private_message.ban_page:
requirements:
_permission: 'use private messaging system,access user profiles'
private_message.ban_autocomplete:
path: '/private-message/autocomplete/ban-members'
defaults:
_controller: '\Drupal\private_message\Controller\AjaxController::privateMessageBanMembersAutocomplete'
_format: json
requirements:
_user_is_logged_in: 'TRUE'
_permission: 'use private messaging system,access user profiles'
private_message.ban_user_form:
path: '/private-message/ban/{user}'
defaults:
......
......@@ -3,7 +3,6 @@
namespace Drupal\private_message\Controller;
use Drupal\Component\Utility\Crypt;
use Drupal\Component\Utility\Tags;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\SettingsCommand;
use Drupal\Core\Config\ConfigFactoryInterface;
......@@ -25,8 +24,6 @@ use Drupal\private_message\Entity\PrivateMessageThread;
use Drupal\private_message\Service\PrivateMessageBanManagerInterface;
use Drupal\private_message\Service\PrivateMessageServiceInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
......@@ -244,30 +241,6 @@ class AjaxController extends ControllerBase implements AjaxControllerInterface {
return $response;
}
/**
* Handler for autocomplete request for banning people.
*/
public function privateMessageBanMembersAutocomplete(Request $request) {
$results = [];
if ($input = $request->query->get('q')) {
$typed_string = Tags::explode($input);
$typed_string = mb_strtolower(array_pop($typed_string));
$accounts = $this->privateMessageService->getUsersFromString($typed_string, self::AUTOCOMPLETE_COUNT);
foreach ($accounts as $account) {
if (!$this->privateMessageBanManager->isBanned($account->id())) {
$results[] = [
'value' => $account->id(),
'label' => $account->getDisplayName(),
];
}
}
}
return new JsonResponse($results);
}
/**
* Creates an Ajax Command containing new private message.
*
......
......@@ -170,9 +170,19 @@ class PrivateMessageController extends ControllerBase implements PrivateMessageC
*/
public function adminUninstallPage() {
return [
'#prefix' => '<div id="private_message_admin_uninstall_page">',
'#suffix' => '</div>',
'form' => $this->formBuilder->getForm('Drupal\private_message\Form\AdminUninstallForm'),
'message' => [
'#prefix' => '<div id="private_message_admin_uninstall_page">',
'#suffix' => '</div>',
'#markup' => $this->t('The private message module cannot be uninstalled if there is private message content in the database.'),
],
'link' => [
'#type' => 'link',
'#title' => $this->t('Delete all private message content'),
'#url' => Url::fromRoute('private_message.admin_config.uninstall_confirm'),
'#attributes' => [
'class' => ['button'],
],
],
];
}
......
......@@ -112,7 +112,7 @@ class PrivateMessageThreadViewBuilder extends EntityViewBuilder {
$build['#suffix'] = '</div></div>';
}
else {
$build['#prefix'] = '<div id="private-message-thread-' . $entity->id() . '" class="' . implode(' ', $classes) . '" data-thread-id="' . $entity->id() . '" data-last-update="' . $entity->get('updated')->value . '">';
$build['#prefix'] = '<div class="' . implode(' ', $classes) . '" data-thread-id="' . $entity->id() . '" data-last-update="' . $entity->get('updated')->value . '">';
$build['#suffix'] = '</div>';
}
......
......@@ -57,37 +57,14 @@ class AdminUninstallForm extends ConfirmFormBase {
* {@inheritdoc}
*/
public function getCancelUrl() {
return Url::fromRoute('private_message.admin_config');
return Url::fromRoute('private_message.admin_config.uninstall');
}
/**
* {@inheritdoc}
*/
public function getDescription() {
return $this->t('The private message module cannot be uninstalled if there is private message content in the database. Clicking the button below will delete all private message content from the system, allowing the module to be uninstalled.') . '<br><strong>' . $this->t('THIS ACTION CANNOT BE REVERSED') . '</strong>';
}
/**
* {@inheritdoc}
*/
public function getConfirmText() {
return $this->t('Delete all private message content');
}
/**
* {@inheritdoc}
*/
public function getCancelText() {
return $this->t('Cancel');
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$form['#attached']['library'][] = 'private_message/uninstall_page';
return parent::buildForm($form, $form_state);
return $this->t('Clicking the button below will delete all private message content from the system, allowing the module to be uninstalled.') . '<br><strong>' . $this->t('THIS ACTION CANNOT BE REVERSED') . '</strong>';
}
/**
......@@ -105,6 +82,8 @@ class AdminUninstallForm extends ConfirmFormBase {
batch_set($batch);
$this->messenger->addMessage($this->t('Private message data has been deleted.'));
$form_state->setRedirectUrl($this->getCancelUrl());
}
/**
......
......@@ -70,7 +70,7 @@ class BanUserForm extends FormBase {
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
public static function create(ContainerInterface $container): self {
return new static(
$container->get('current_user'),
$container->get('entity_type.manager'),
......@@ -89,44 +89,24 @@ class BanUserForm extends FormBase {
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state, $target_id = NULL): array {
public function buildForm(array $form, FormStateInterface $form_state): array {
$config = $this->configFactory->get('private_message.settings');
if ($target_id === NULL) {
$form['user_name'] = [
'#title' => ('Select User'),
'#type' => 'textfield',
'#required' => FALSE,
'#attributes' => [
'class' => [
'private-message-ban-autocomplete',
],
],
'#autocomplete_route_name' => 'private_message.ban_autocomplete',
'#attached' => [
'library' => [
'private_message/ban_autocomplete',
],
],
];
}
$form['banned_user'] = [
'#type' => 'hidden',
'#title' => $this->t('Blocked User'),
'#default_value' => $target_id,
'#required' => FALSE,
'#title' => $this->t('Select User'),
'#required' => TRUE,
'#type' => 'entity_autocomplete',
'#target_type' => 'user',
'#tags' => FALSE,
'#selection_handler' => 'private_message:not_blocked_user',
'#selection_settings' => [
'include_anonymous' => FALSE,
],
];
$submitLabel = $config->get('ban_label');
if ($target_id && $this->privateMessageBanManager->isBanned($target_id)) {
$submitLabel = $config->get('unban_label');
}
$form['submit'] = [
'#type' => 'submit',
'#value' => $submitLabel,
'#value' => $config->get('ban_label'),
];
return $form;
......@@ -136,35 +116,30 @@ class BanUserForm extends FormBase {
* {@inheritdoc}
*/
public function validateForm(array &$form, FormStateInterface $form_state): void {
$user_id_field = !empty($form_state->getValue('banned_user')) ? 'banned_user' : 'user_name';
$user_id = $form_state->getValue('banned_user');
$userId = $form_state->getValue('banned_user');
// Add security to prevent blocking ourselves.
if ($user_id === $this->currentUser->id()) {
$form_state->setErrorByName($user_id_field, $this->t("You can't block yourself."));
if ($userId === $this->currentUser->id()) {
$form_state->setErrorByName($userId, $this->t("You can't block yourself."));
}
// Add a security if the user id is unknown.
if (empty($user_id) ||
empty($this->entityTypeManager->getStorage('user')->load($user_id))) {
$form_state->setErrorByName($user_id_field, $this->t('The user id is unknown.'));
if (empty($userId) ||
empty($this->entityTypeManager->getStorage('user')->load($userId))) {
$form_state->setErrorByName($userId, $this->t('The user id is unknown.'));
}
if (!empty($userId) && $this->privateMessageBanManager->isBanned($userId)) {
$form_state->setErrorByName($userId, $this->t('The user is already blocked.'));
}
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$target_id = $form_state->getValue('banned_user');
public function submitForm(array &$form, FormStateInterface $form_state): void {
$userId = $form_state->getValue('banned_user');
// Unban if already banned.
if ($this->privateMessageBanManager->isBanned($target_id)) {
$this->privateMessageBanManager->unbanUser($target_id);
}
// Ban if not banned.
else {
$this->privateMessageBanManager->banUser($target_id);
}
$this->privateMessageBanManager->banUser($userId);
}
}
......@@ -100,11 +100,11 @@ class PrivateMessageForm extends ContentEntityForm {
protected $formBuilder;
/**
* The private message configuration.
* The message configuration.
*
* @var \Drupal\Core\Config\ImmutableConfig
*/
private ImmutableConfig $config;
protected ImmutableConfig $config;
/**
* Constructs a PrivateMessageForm object.
......
<?php
declare(strict_types=1);
namespace Drupal\private_message\Plugin\EntityReferenceSelection;
use Drupal\Core\Entity\Attribute\EntityReferenceSelection;
use Drupal\Core\Entity\Query\QueryInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\user\Plugin\EntityReferenceSelection\UserSelection;
/**
* Provides reference selection for not blocked users.
*/
#[EntityReferenceSelection(
id: "private_message:not_blocked_user",
label: new TranslatableMarkup("Not blocked user selection"),
group: "private_message",
weight: 3,
entity_types: ["user"]
)]
class NotBlockedUserSelection extends UserSelection {
/**
* {@inheritdoc}
*/
protected function buildEntityQuery($match = NULL, $match_operator = 'CONTAINS'): QueryInterface {
$query = parent::buildEntityQuery($match, $match_operator);
$subquery = $this->connection->select('private_message_ban', 'pmb')
->fields('pmb', ['target']);
$subquery->condition('owner', $this->currentUser->id());
$query->condition('uid', $subquery, 'NOT IN');
return $query;
}
}
......@@ -156,4 +156,18 @@ class PrivateMessageThreadMembersTest extends BrowserTestBase {
$this->assertSession()->elementTextContains('css', '.private-message-recipients article:nth-of-type(2) .username', $this->userC->getDisplayName());
}
/**
* Regression test for multiple add more clicks.
*/
public function testMultipleAddMoreClicks(): void {
$this->drupalLogin($this->userA);
$this->drupalGet('/private-message/create');
$this->getSession()->getPage()->pressButton('edit-members-add-more');
$this->assertSession()->statusCodeEquals(200);
$this->getSession()->getPage()->pressButton('edit-members-add-more');
$this->assertSession()->statusCodeEquals(200);
}
}
<?php
declare(strict_types=1);
namespace Drupal\Tests\private_message\Functional;
use Drupal\Tests\BrowserTestBase;
use Drupal\private_message\Entity\PrivateMessage;
use Drupal\private_message\Entity\PrivateMessageThread;
/**
* Tests for the uninstallation process.
*
* @group private_message
*/
class PrivateMessageUninstallTest extends BrowserTestBase {
/**
* {@inheritdoc}
*/
protected $defaultTheme = 'stark';
/**
* Modules to install.
*
* @var array
*/
protected static $modules = ['private_message'];
/**
* Tests the access to uninstall routes.
*/
public function testLimitedAccess(): void {
$this->drupalGet('/admin/config/private-message/uninstall');
$this->assertSession()->statusCodeEquals(403);
$this->drupalGet('/admin/config/private-message/uninstall/confirm');
$this->assertSession()->statusCodeEquals(403);
}
/**
* Tests deletion of all private message content from the system.
*/
public function testUninstallation(): void {
$owner = $this->DrupalCreateUser();
$adminUser = $this->DrupalCreateUser([
'administer site configuration',
'administer private message module',
]);
PrivateMessageThread::create([
'members' => [$owner, $adminUser],
'subject' => $this->getRandomGenerator()->word(10),
'updated' => \Drupal::time()->getRequestTime() - 3600,
'private_messages' => [
PrivateMessage::create([
'owner' => $owner,
'message' => [
'value' => $this->getRandomGenerator()->sentences(5),
'format' => 'plain_text',
],
]),
],
])->save();
$this->drupalLogin($adminUser);
$this->drupalGet('/admin/config/private-message/uninstall');
$this->getSession()
->getPage()
->clickLink('Delete all private message content');
$this->assertSession()->statusCodeEquals(200);
$this->getSession()->getPage()->clickLink('Cancel');
$this->assertSame(2, $this->retrieveCount());
$this->getSession()
->getPage()
->clickLink('Delete all private message content');
$this->assertSession()->statusCodeEquals(200);
$this->submitForm([], t('Confirm'));
$this->assertSame(0, $this->retrieveCount());
}
/**
* Returns a count of entities.
*
* @return int
* Number of entities.
*/
protected function retrieveCount(): int {
$messages = $this
->container
->get('entity_type.manager')
->getStorage('private_message')
->getQuery()
->accessCheck(FALSE)
->count()
->execute();
$threads = $this
->container
->get('entity_type.manager')
->getStorage('private_message_thread')
->getQuery()
->accessCheck(FALSE)
->count()
->execute();
return $messages + $threads;
}
}
......@@ -88,6 +88,46 @@ class PrivateMessageUserBanTest extends BrowserTestBase {
$this->assertSession()->linkExists('Block');
}
/**
* Tests access to the ban listing.
*/
public function testBanPageRouteAccess() {
$this->drupalLogin($this->userA);
$this->drupalGet('/private-message/ban');
$this->assertSession()->statusCodeEquals(200);
$this->assertSession()->pageTextContains('Ban/Unban users');
$this->drupalLogout();
$this->drupalGet('/private-message/ban');
$this->assertSession()->statusCodeEquals(403);
}
/**
* Tests for BanUserForm.
*/
public function testBanUserFormSubmission() {
$this->drupalLogin($this->userA);
$this->drupalGet('/private-message/ban');
$edit = [
'banned_user' => $this->userA->getDisplayName() . ' (' . $this->userA->id() . ')',
];
$this->submitForm($edit, 'Block');
$this->assertSession()->statusMessageContains("You can't block yourself.", 'error');
$edit = [
'banned_user' => $this->userB->getDisplayName() . ' (' . $this->userB->id() . ')',
];
$this->submitForm($edit, 'Block');
$this->assertSession()->statusMessageContains("The user " . $this->userB->getDisplayName() . " has been banned.", 'status');
$edit = [
'banned_user' => $this->userB->getDisplayName() . ' (' . $this->userB->id() . ')',
];
$this->submitForm($edit, 'Block');
$this->assertSession()->statusMessageContains('The user is already blocked', 'error');
}
/**
* Returns a count of bans.
*/
......
......@@ -123,7 +123,7 @@ class PrivateMessageJavascriptTest extends WebDriverTestBase {
// Test loading threads by clicking inbox links.
$this->drupalGet('/private-messages');
foreach ($threads_map as $threadId => $expectedUser) {
$this->click("#private-message-thread-$threadId .private-message-inbox-thread-link");
$this->click(".private-message-thread-inbox[data-thread-id=$threadId] .private-message-inbox-thread-link");
$this->assertSession()->assertWaitOnAjaxRequest();
$this->assertSession()->elementTextContains('css', '#private-message-page .private-message-recipients article:nth-of-type(1) .username', $expectedUser->getDisplayName());
}
......