Skip to content

Commit

Permalink
Merge branch 'MAUT-11466' into development
Browse files Browse the repository at this point in the history
  • Loading branch information
Avikarsha Saha committed Jun 14, 2024
2 parents 840decf + 89d36ef commit 7e5c612
Show file tree
Hide file tree
Showing 3 changed files with 235 additions and 0 deletions.
92 changes: 92 additions & 0 deletions EventListener/TokenSubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Mautic\CampaignBundle\Entity\Event;
use Mautic\CampaignBundle\Model\EventModel;
use Mautic\CoreBundle\Event\BuilderEvent;
use Mautic\CoreBundle\Event\TokenReplacementEvent;
use Mautic\EmailBundle\EmailEvents;
use Mautic\EmailBundle\Entity\Email;
use Mautic\EmailBundle\Event\EmailSendEvent;
Expand Down Expand Up @@ -121,6 +122,7 @@ public static function getSubscribedEvents()
EmailEvents::EMAIL_ON_SEND => ['decodeTokens', 0],
EmailEvents::EMAIL_ON_DISPLAY => ['decodeTokens', 0],
CustomItemEvents::ON_CUSTOM_ITEM_LIST_DBAL_QUERY => ['onListQuery', -1],
EmailEvents::TOKEN_REPLACEMENT => ['onTokenReplacement', 100],
];
}

Expand Down Expand Up @@ -323,4 +325,94 @@ private function getCustomFieldValues(CustomObject $customObject, Token $token,

return $fieldValues;
}

public function onTokenReplacement(TokenReplacementEvent $event): void
{
$clickthrough = $event->getClickthrough();

if (!array_key_exists('dynamicContent', $clickthrough)) {
return;
}

$lead = $event->getLead();
$tokenData = $clickthrough['dynamicContent'];
$tokens = $clickthrough['tokens'];

foreach ($tokenData as $data) {
// Default content
$filterContent = $data['content'];

$isCustomObject = false;
foreach ($data['filters'] as $filter) {
foreach ($filter['filters'] as $condition) {
if ('custom_object' !== $condition['object'] || empty($condition['display'])) {
continue;
}
$isCustomObject = true;

list($customObjectAlias, $customItemAlias) = array_map(
function ($part) {
return trim($part);
}, explode(':', $condition['display']));

$customObject = $this->customObjectModel->fetchEntityByAlias($customObjectAlias);
$result = $this->getCustomItemValue($customObject, (int) $lead['id'], $customItemAlias);
$lead[$condition['field']] = $result;
}

if ($isCustomObject && $this->matchFilterForLead($filter['filters'], $lead)) {
$filterContent = $filter['content'];
break;
}
}

if ($isCustomObject) {
$event->addToken('{dynamiccontent="'.$data['tokenName'].'"}', $filterContent);
}
}
}

/**
* @throws InvalidCustomObjectFormatListException
*/
public function getCustomItemValue(CustomObject $customObject, int $id, string $customItemAlias): string
{
$orderBy = CustomItem::TABLE_ALIAS.'.id';
$orderDir = 'DESC';

$tableConfig = new TableConfig(1, 1, $orderBy, $orderDir);
$tableConfig->addParameter('customObjectId', $customObject->getId());
$tableConfig->addParameter('filterEntityType', 'contact');
$tableConfig->addParameter('filterEntityId', (int) $id);
$tableConfig->addParameter('token', $customItemAlias);
$customItems = $this->customItemModel->getArrayTableData($tableConfig);
$fieldValues = [];

foreach ($customItems as $customItemData) {
// Name is known from the CI data array.
if ('name' === $customItemAlias) {
$fieldValues[] = $customItemData['name'];

continue;
}

// Custom Field values are handled like this.
$customItem = new CustomItem($customObject);
$customItem->populateFromArray($customItemData);
$customItem = $this->customItemModel->populateCustomFields($customItem);

try {
$fieldValue = $customItem->findCustomFieldValueForFieldAlias($customItemAlias);
// If the CO item doesn't have a value, get the default value
if (empty($fieldValue->getValue())) {
$fieldValue->setValue($fieldValue->getCustomField()->getDefaultValue());
}
$fieldValues[] = $fieldValue->getCustomField()->getTypeObject()->valueToString($fieldValue);
} catch (NotFoundException $e) {
// Custom field not found.
}
}

return $this->tokenFormatter->format($fieldValues, TokenFormatter::DEFAULT_FORMAT);
}
}
142 changes: 142 additions & 0 deletions Tests/Functional/PreviewFunctionalTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
<?php

declare(strict_types=1);

namespace MauticPlugin\CustomObjectsBundle\Tests\Functional;

use DateTime;
use Mautic\CoreBundle\Test\MauticMysqlTestCase;
use Mautic\EmailBundle\Entity\Email;
use Mautic\LeadBundle\Entity\Lead;
use MauticPlugin\CustomObjectsBundle\Entity\CustomItem;
use MauticPlugin\CustomObjectsBundle\Model\CustomFieldValueModel;
use MauticPlugin\CustomObjectsBundle\Model\CustomItemModel;
use MauticPlugin\CustomObjectsBundle\Tests\Functional\DataFixtures\Traits\CustomObjectsTrait;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

class PreviewFunctionalTest extends MauticMysqlTestCase
{
use CustomObjectsTrait;

/**
* @var CustomItemModel
*/
private $customItemModel;

/**
* @var CustomFieldValueModel
*/
private $customFieldValueModel;

protected function setUp(): void
{
parent::setUp();

$this->customItemModel = self::$container->get('mautic.custom.model.item');
$this->customFieldValueModel = self::$container->get('mautic.custom.model.field.value');
}

public function testPreviewPageCODynamicContent(): void
{
$customObject = $this->createCustomObjectWithAllFields(self::$container, 'Car');
$customItem = new CustomItem($customObject);

$customItem->setName('Nexon');
$this->customFieldValueModel->createValuesForItem($customItem);

$textValue = $customItem->findCustomFieldValueForFieldAlias('text-test-field');
$textValue->setValue('abracadabra');

$customItem = $this->customItemModel->save($customItem);

$lead = $this->createLead();
$email = $this->createEmail();
$email->setDynamicContent(
[
[
'tokenName' => 'Dynamic Content 1',
'content' => 'Default Dynamic Content',
'filters' => [
[
'content' => null,
'filters' => [
],
],
],
],
[
'tokenName' => 'Dynamic Content 2',
'content' => 'Default Dynamic Content',
'filters' => [
[
'content' => 'Nexon Dynamic Content',
'filters' => [
[
'glue' => 'and',
'field' => 'cmf_'.$textValue->getCustomField()->getId(),
'object' => 'custom_object',
'type' => 'text',
'filter' => 'abracadabra',
'display' => $customObject->getAlias().':text-test-field',
'operator' => '=',
],
],
],
],
],
]
);
$this->em->persist($email);
$this->em->flush();

$this->customItemModel->linkEntity($customItem, 'contact', (int) $lead->getId());

$url = "/email/preview/{$email->getId()}";
$urlWithContact = "{$url}?contactId={$lead->getId()}";
$contentNoContactInfo = 'Default Dynamic Content';
$contentWithContactInfo = 'Nexon Dynamic Content';

// Anonymous visitor
$this->assertPageContent($url, $contentNoContactInfo);
$this->assertPageContent($urlWithContact, $contentNoContactInfo);

$this->loginUser('admin');

// Admin user
$this->assertPageContent($url, $contentNoContactInfo);
$this->assertPageContent($urlWithContact, $contentWithContactInfo);
}

private function assertPageContent(string $url, string ...$expectedContents): void
{
$crawler = $this->client->request(Request::METHOD_GET, $url);
self::assertSame(Response::HTTP_OK, $this->client->getResponse()->getStatusCode());
foreach ($expectedContents as $expectedContent) {
self::assertStringContainsString($expectedContent, $crawler->text());
}
}

private function createEmail(bool $publicPreview = true): Email
{
$email = new Email();
$email->setDateAdded(new DateTime());
$email->setName('Email name');
$email->setSubject('Email subject');
$email->setTemplate('Blank');
$email->setPublicPreview($publicPreview);
$email->setCustomHtml('<html><body>{dynamiccontent="Dynamic Content 2"}</body></html>');
$this->em->persist($email);

return $email;
}

private function createLead(): Lead
{
$lead = new Lead();
$lead->setEmail('[email protected]');
$this->em->persist($lead);

return $lead;
}
}
1 change: 1 addition & 0 deletions Tests/Unit/EventListener/TokenSubscriberTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ public function testGetSubscribedEvents(): void
EmailEvents::EMAIL_ON_SEND => ['decodeTokens', 0],
EmailEvents::EMAIL_ON_DISPLAY => ['decodeTokens', 0],
CustomItemEvents::ON_CUSTOM_ITEM_LIST_DBAL_QUERY => ['onListQuery', -1],
EmailEvents::TOKEN_REPLACEMENT => ['onTokenReplacement', 100],
],
TokenSubscriber::getSubscribedEvents()
);
Expand Down

0 comments on commit 7e5c612

Please sign in to comment.