drupalorg-1.0.x-dev/src/Form/MailmanSubscribeForm.php
src/Form/MailmanSubscribeForm.php
<?php
declare(strict_types=1);
namespace Drupal\drupalorg\Form;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Form\FormInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Site\Settings;
use Drupal\Core\Url;
use Drupal\user\UserInterface;
use GuzzleHttp\Client;
use Symfony\Component\DependencyInjection\Attribute\Autowire;
/**
* Subscribing to or unsubscribing from Mailman lists.
*/
class MailmanSubscribeForm extends ControllerBase implements FormInterface {
public function __construct(
#[Autowire(service: 'http_client')]
protected Client $http_client,
) {
}
/**
* {@inheritdoc}
*/
public function getFormId(): string {
return 'drupalorg_newsletter_subscribe_form';
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state, ?UserInterface $user = NULL): array {
$mailman_config = Settings::get('drupalorg_mailman_config', []);
$storage = &$form_state->getStorage();
if ($mailman_config === []) {
$this->messenger()->addWarning($this->t('Mailman integration is not configured.'));
return $form;
}
$this->messenger()->addMessage($this->t('<strong>Looking for other newsletters?</strong> New newsletters are <a href=":url">configured on your user profile</a>.', [
':url' => Url::fromRoute('entity.user.edit_form', ['user' => $user->id()])->toString(),
]));
$form['help']['#markup'] = '<p>' . $this->t('Select the newsletter(s) which you want to subscribe to or unsubscribe from.
') . '</p>';
$lists = [
'security-news' => [
'name' => 'Security announcements',
'description' => 'A low volume mailing list where all security issues affecting Drupal and Drupal contributed modules are publicly announced.',
],
];
$form['lists'] = [
'#tree' => TRUE,
];
foreach ($lists as $list_id => $list) {
$subscribed = FALSE;
try {
$subscriber_info = json_decode($this->http_client->post('3.1/members/find', array_merge($mailman_config['client-options'], [
'json' => [
'subscriber' => $user->getEmail(),
'list_id' => $list_id . '.' . $mailman_config['list-domain'],
],
]))->getBody()->getContents());
if ($subscribed = (bool) $subscriber_info->total_size) {
$storage['subscriber_ids'][$list_id] = $subscriber_info->entries[0]->member_id;
}
}
catch (\Throwable $e) {
$this->messenger()->addWarning(t('Could not check subscription to the @name list.', [
'@name' => $list['name'],
]));
$this->getLogger('drupalorg')->error('Error checking subscription to the @name list. Message: @message', [
'@name' => $list['name'],
'@message' => $e->getMessage(),
]);
}
$form['lists'][$list_id] = [
'#type' => 'checkbox',
'#title' => $list['name'],
'#description' => $list['description'],
'#default_value' => $subscribed,
];
}
$form['actions']['#type'] = 'actions';
$form['actions']['submit'] = [
'#type' => 'submit',
'#value' => t('Save subscription'),
];
return $form;
}
/**
* {@inheritdoc}
*/
public function validateForm(array &$form, FormStateInterface $form_state) {
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state): void {
$mailman_config = Settings::get('drupalorg_mailman_config', []);
$storage = $form_state->getStorage();
foreach ($form_state->getValues()['lists'] as $list_id => $subscribed) {
try {
if ($subscribed && !isset($storage['subscriber_ids'][$list_id])) {
$this->http_client->post('3.1/members', array_merge($mailman_config['client-options'], [
'json' => [
'list_id' => $list_id . '.' . $mailman_config['list-domain'],
'subscriber' => $form_state->getBuildInfo()['args'][0]->getEmail(),
'display_name' => $form_state->getBuildInfo()['args'][0]->getDisplayName(),
'pre_verified' => 'True',
'pre_confirmed' => 'True',
'pre_approved' => 'True',
'send_welcome_message' => 'False',
],
]));
$this->messenger()->addMessage($this->t('You have been subscribed to the @name list.', [
'@name' => $form['lists'][$list_id]['#title'],
]));
}
elseif (!$subscribed && isset($storage['subscriber_ids'][$list_id])) {
$this->http_client->delete('3.1/members/' . $storage['subscriber_ids'][$list_id], $mailman_config['client-options']);
$this->messenger()->addMessage($this->t('You have been unsubscribed from the @name list.', [
'@name' => $form['lists'][$list_id]['#title'],
]));
}
}
catch (\Throwable $e) {
$this->messenger()->addWarning(t('Could not update subscription for the @name list.', [
'@name' => $list_id,
]));
$this->getLogger('drupalorg')->error('Error updating subscription for the @name list. Message: @message', [
'@name' => $list_id,
'@message' => $e->getMessage(),
]);
}
}
}
}
