diff --git a/inmail.services.yml b/inmail.services.yml index 58583ca..4ef5986 100644 --- a/inmail.services.yml +++ b/inmail.services.yml @@ -1,7 +1,7 @@ services: inmail.processor: class: Drupal\inmail\MessageProcessor - arguments: ['@entity.manager', '@plugin.manager.inmail.analyzer', '@plugin.manager.inmail.handler', '@logger.channel.inmail', '@inmail.mime_parser'] + arguments: ['@entity.manager', '@plugin.manager.inmail.analyzer', '@plugin.manager.inmail.handler', '@logger.channel.inmail', '@inmail.mime_parser', '@account_switcher'] plugin.manager.inmail.deliverer: class: Drupal\Core\Plugin\DefaultPluginManager arguments: diff --git a/src/MessageProcessor.php b/src/MessageProcessor.php index 04a38fe..a63eb2e 100644 --- a/src/MessageProcessor.php +++ b/src/MessageProcessor.php @@ -5,6 +5,7 @@ namespace Drupal\inmail; use Drupal\Component\Utility\SafeMarkup; use Drupal\Core\Entity\EntityManagerInterface; use Drupal\Core\Logger\LoggerChannelInterface; +use Drupal\Core\Session\AccountSwitcherInterface; use Drupal\inmail\Entity\DelivererConfig; use Drupal\inmail\MIME\ParseException; use Drupal\inmail\MIME\ParserInterface; @@ -62,15 +63,23 @@ class MessageProcessor implements MessageProcessorInterface { protected $parser; /** + * The account switcher service. + * + * @var \Drupal\Core\Session\AccountSwitcherInterface + */ + protected $accountSwitcher; + + /** * Constructs a new message processor. */ - public function __construct(EntityManagerInterface $entity_manager, AnalyzerManagerInterface $analyzer_manager, HandlerManagerInterface $handler_manager, LoggerChannelInterface $logger_channel, ParserInterface $parser) { + public function __construct(EntityManagerInterface $entity_manager, AnalyzerManagerInterface $analyzer_manager, HandlerManagerInterface $handler_manager, LoggerChannelInterface $logger_channel, ParserInterface $parser, AccountSwitcherInterface $account_switcher) { $this->analyzerStorage = $entity_manager->getStorage('inmail_analyzer'); $this->analyzerManager = $analyzer_manager; $this->handlerStorage = $entity_manager->getStorage('inmail_handler'); $this->handlerManager = $handler_manager; $this->loggerChannel = $logger_channel; $this->parser = $parser; + $this->accountSwitcher = $account_switcher; } /** @@ -100,7 +109,8 @@ class MessageProcessor implements MessageProcessorInterface { /** @var \Drupal\inmail\DefaultAnalyzerResult $default_result */ $default_result = $result->ensureAnalyzerResult(DefaultAnalyzerResult::TOPIC, DefaultAnalyzerResult::createFactory()); // Enabled analyzers will be able to update the account. - $default_result->setAccount(User::getAnonymousUser()); + $anonymous_user = User::getAnonymousUser(); + $default_result->setAccount($anonymous_user); $analyzer_configs = $this->analyzerStorage->loadMultiple(); uasort($analyzer_configs, array($this->analyzerStorage->getEntityType()->getClass(), 'sort')); @@ -117,6 +127,11 @@ class MessageProcessor implements MessageProcessorInterface { $event and $event->addArgument(get_class($analyzer_result), $analyzer_result->summarize()); } + // Conditionally switch to the account identified by analyzers. + if ($default_result->getAccount() != $anonymous_user) { + $this->accountSwitcher->switchTo($default_result->getAccount()); + } + // Handle message. foreach ($this->handlerStorage->loadMultiple() as $handler_config) { /** @var \Drupal\inmail\Entity\HandlerConfig $handler_config */ @@ -127,6 +142,11 @@ class MessageProcessor implements MessageProcessorInterface { } } + if ($default_result->getAccount() != $anonymous_user) { + // Switch back to a previous account. + $this->accountSwitcher->switchBack(); + } + if ($event) { // Dump all log items into a past argument per source. foreach ($result->readLog() as $source => $log) { diff --git a/tests/modules/inmail_test/src/Plugin/inmail/Analyzer/TestAnalyzer.php b/tests/modules/inmail_test/src/Plugin/inmail/Analyzer/TestAnalyzer.php index 12a8cc8..e11389d 100644 --- a/tests/modules/inmail_test/src/Plugin/inmail/Analyzer/TestAnalyzer.php +++ b/tests/modules/inmail_test/src/Plugin/inmail/Analyzer/TestAnalyzer.php @@ -8,6 +8,7 @@ use Drupal\inmail\DefaultAnalyzerResult; use Drupal\inmail\MIME\MessageInterface; use Drupal\inmail\Plugin\inmail\Analyzer\AnalyzerBase; use Drupal\inmail\ProcessorResultInterface; +use Drupal\user\Entity\User; /** * Provides a test analyzer. @@ -28,6 +29,16 @@ class TestAnalyzer extends AnalyzerBase { // Provide sample context. $this->addContext($default_result); + + // Update default result with example account. + $users = \Drupal::entityTypeManager()->getStorage('user')->loadByProperties(['mail' => 'demo@example.com']); + if (!$demo_user = reset($users)) { + $demo_user = User::create([ + 'mail' => 'demo@example.com', + 'name' => 'Demo User', + ]); + } + $default_result->setAccount($demo_user); } /** diff --git a/tests/modules/inmail_test/src/Plugin/inmail/Handler/ResultKeeperHandler.php b/tests/modules/inmail_test/src/Plugin/inmail/Handler/ResultKeeperHandler.php index 1aa1734..98abcf4 100644 --- a/tests/modules/inmail_test/src/Plugin/inmail/Handler/ResultKeeperHandler.php +++ b/tests/modules/inmail_test/src/Plugin/inmail/Handler/ResultKeeperHandler.php @@ -30,6 +30,7 @@ class ResultKeeperHandler extends HandlerBase { public function invoke(MessageInterface $message, ProcessorResultInterface $processor_result) { \Drupal::state()->set('inmail_test.result_keeper.message', $message); \Drupal::state()->set('inmail_test.result_keeper.result', $processor_result); + \Drupal::state()->set('inmail_test.result_keeper.account_name', \Drupal::currentUser()->getDisplayName()); } /** @@ -52,4 +53,14 @@ class ResultKeeperHandler extends HandlerBase { return \Drupal::state()->get('inmail_test.result_keeper.result'); } + /** + * Returns the account display name. + * + * @return string + * The account display name. + */ + public static function getAccountName() { + return \Drupal::state()->get('inmail_test.result_keeper.account_name'); + } + } diff --git a/tests/src/Kernel/AnalyzerTest.php b/tests/src/Kernel/AnalyzerTest.php index f4f6e31..db1127b 100644 --- a/tests/src/Kernel/AnalyzerTest.php +++ b/tests/src/Kernel/AnalyzerTest.php @@ -32,6 +32,7 @@ class AnalyzerTest extends KernelTestBase { */ protected function setUp() { parent::setUp(); + $this->installEntitySchema('user'); $this->installConfig(['inmail']); \Drupal::configFactory()->getEditable('inmail.settings') ->set('return_path', 'bounces@example.com') diff --git a/tests/src/Kernel/HandlerTest.php b/tests/src/Kernel/HandlerTest.php new file mode 100644 index 0000000..902f58a --- /dev/null +++ b/tests/src/Kernel/HandlerTest.php @@ -0,0 +1,63 @@ +installEntitySchema('user'); + } + + /** + * Tests account switching mechanism. + */ + public function testAccountSwitching() { + $raw = << +To: receiver@example.com + +Hello world! +EOF; + + /** @var \Drupal\inmail\MessageProcessorInterface $processor */ + $processor = \Drupal::service('inmail.processor'); + + AnalyzerConfig::create(['id' => 'test_analyzer', 'plugin' => 'test_analyzer'])->save(); + HandlerConfig::create(['id' => 'result_keeper', 'plugin' => 'result_keeper'])->save(); + $processor->process($raw, DelivererConfig::create(['id' => 'test'])); + + $processor_result = ResultKeeperHandler::getResult(); + /** @var \Drupal\inmail\DefaultAnalyzerResult $default_result */ + $default_result = $processor_result->getAnalyzerResult(DefaultAnalyzerResult::TOPIC); + + // Assert "Test Analyzer" updated the account on default result. + $this->assertEquals('Demo User', $default_result->getAccount()->getDisplayName()); + // Assert the account was switched on handler's level. + $this->assertEquals('Demo User', ResultKeeperHandler::getAccountName()); + } + +}