View source
<?php
namespace Drupal\mailhandler_comment\Plugin\inmail\Handler;
use Drupal\comment\CommentInterface;
use Drupal\comment\Entity\Comment;
use Drupal\Core\Entity\EntityTypeManager;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\inmail\DefaultAnalyzerResult;
use Drupal\inmail\MIME\MimeMessageInterface;
use Drupal\inmail\Plugin\inmail\Handler\HandlerBase;
use Drupal\inmail\ProcessorResultInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
class MailhandlerComment extends HandlerBase implements ContainerFactoryPluginInterface {
protected $entityTypeManager;
public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManager $entity_type_manager) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->entityTypeManager = $entity_type_manager;
}
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static($configuration, $plugin_id, $plugin_definition, $container
->get('entity_type.manager'));
}
public function help() {
return [
'#type' => 'item',
'#markup' => $this
->t('Post comments via email.'),
];
}
public function invoke(MimeMessageInterface $message, ProcessorResultInterface $processor_result) {
try {
$result = $processor_result
->getAnalyzerResult();
if (!$result
->hasContext('entity_type') || $result
->getContext('entity_type')
->getContextValue()['entity_type'] != 'comment') {
return;
}
$comment = $this
->createComment($message, $result);
$processor_result
->log('CommentHandler', '@comment has been created by @user.', [
'@comment' => $comment
->label(),
'@user' => $comment
->getAuthorName(),
]);
} catch (\Exception $e) {
$processor_result
->log('CommentHandler', $e
->getMessage());
}
}
protected function createComment(MimeMessageInterface $message, DefaultAnalyzerResult $result) {
$entity_id = $this
->getEntityId($result);
$user = $this
->validateUser($result);
$comment = Comment::create([
'entity_type' => $this->configuration['entity_type'],
'entity_id' => $entity_id,
'uid' => $user
->id(),
'subject' => $result
->getSubject(),
'comment_body' => [
'value' => $result
->getBody(),
'format' => 'basic_html',
],
'field_name' => 'comment',
'comment_type' => 'comment',
'status' => CommentInterface::PUBLISHED,
]);
$comment
->save();
return $comment;
}
protected function validateUser(DefaultAnalyzerResult $result) {
if ($result
->hasContext('verified') && !$result
->getContext('verified')
->getContextValue()) {
throw new \Exception('Failed to process the message. PGP-signed message is not verified.');
}
$account = \Drupal::currentUser()
->getAccount();
$access = $this->entityTypeManager
->getAccessControlHandler('comment')
->createAccess('comment', $account, [], TRUE);
if (!$access
->isAllowed()) {
throw new \Exception('Failed to process the message. User is not authorized to post comments.');
}
return $account;
}
protected function getEntityTypes() {
$comment_entity_types = \Drupal::entityManager()
->getFieldMapByFieldType('comment');
$entity_types = [];
foreach ($comment_entity_types as $entity_type => $bundles) {
$entity_types[$entity_type] = $this->entityTypeManager
->getDefinition($entity_type)
->getLabel();
}
return $entity_types;
}
public function defaultConfiguration() {
return [
'entity_type' => 'node',
];
}
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
$form = parent::buildConfigurationForm($form, $form_state);
$form['entity_type'] = [
'#title' => $this
->t('Entity type'),
'#type' => 'select',
'#options' => $this
->getEntityTypes(),
'#default_value' => $this->configuration['entity_type'],
'#description' => $this
->t('Select a referenced entity type.'),
];
return $form;
}
public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
parent::submitConfigurationForm($form, $form_state);
$this->configuration['entity_type'] = $form_state
->getValue('entity_type');
}
protected function getEntityId(DefaultAnalyzerResult $result) {
$subject = $result
->getSubject();
if (!preg_match('/^\\[#(\\d+)\\]\\s+/', $subject, $matches)) {
throw new \Exception('Referenced entity ID of the comment could not be identified.');
}
$entity_id = $matches[1];
$subject = str_replace(reset($matches), '', $subject);
$result
->setSubject($subject);
$entity_type = $this->configuration['entity_type'];
$commentable_entity_types = \Drupal::entityManager()
->getFieldMapByFieldType('comment');
if (!isset($commentable_entity_types[$entity_type])) {
throw new \Exception('The referenced entity type ' . $entity_type . ' does not support comments.');
}
if (!($entity = $this->entityTypeManager
->getStorage($entity_type)
->load($entity_id))) {
throw new \Exception('The referenced entity ID (' . $entity_type . ':' . $entity_id . ') does not exists.');
}
$allowed_entity_bundles = $commentable_entity_types[$entity_type]['comment']['bundles'];
$entity_bundle = $entity
->bundle();
if (!in_array($entity_bundle, $allowed_entity_bundles)) {
throw new \Exception('The bundle ' . $entity_bundle . ' of entity (' . $entity_type . ':' . $entity_id . ') does not support comments.');
}
return $entity_id;
}
}