Skip to content

Commit

Permalink
Merge pull request #83 from TheDMSGroup/ENG-334-event-id-tokens
Browse files Browse the repository at this point in the history
[ENG-334] Event tokens for dispositions.
  • Loading branch information
heathdutton authored Jun 21, 2018
2 parents 5c458b3 + 3888e0a commit c2c3789
Show file tree
Hide file tree
Showing 11 changed files with 168 additions and 23 deletions.
2 changes: 1 addition & 1 deletion Assets/build/contactclient.min.js

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion Assets/js/02.json_editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -497,7 +497,9 @@ JSONEditor.defaults.custom_validators.push(function (schema, value, path) {
url: mauticAjaxUrl,
type: 'POST',
data: {
action: tokenSource
action: tokenSource,
apiPayload: mQuery('#contactclient_api_payload:first').val(),
filePayload: mQuery('#contactclient_file_payload:first').val()
},
cache: true,
dataType: 'json',
Expand Down
4 changes: 3 additions & 1 deletion Assets/js/03.api_payload.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ Mautic.contactclientApiPayloadPre = function () {
url: mauticAjaxUrl,
type: 'POST',
data: {
action: tokenSource
action: tokenSource,
apiPayload: $apiPayload.val(),
filePayload: mQuery('#contactclient_file_payload:first').val()
},
cache: true,
dataType: 'json',
Expand Down
4 changes: 3 additions & 1 deletion Assets/js/05.file_payload.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ Mautic.contactclientFilePayloadPre = function () {
url: mauticAjaxUrl,
type: 'POST',
data: {
action: tokenSource
action: tokenSource,
apiPayload: mQuery('#contactclient_api_payload:first').val(),
filePayload: $filePayload
},
cache: true,
dataType: 'json',
Expand Down
6 changes: 6 additions & 0 deletions Assets/json/api_payload_default.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@
"value": "{{phone}}",
"test_value": "+15555555555",
"required": true
},
{
"key": "eventToken",
"value": "{{event.token}}",
"test_value": "10101",
"required": false
}
]
}
Expand Down
22 changes: 17 additions & 5 deletions Controller/AjaxController.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use Mautic\CoreBundle\Helper\InputHelper;
use Mautic\CoreBundle\Translation\Translator;
use Mautic\LeadBundle\Entity\Lead as Contact;
use MauticPlugin\MauticContactClientBundle\Entity\ContactClient;
use MauticPlugin\MauticContactClientBundle\Helper\TokenHelper;
use MauticPlugin\MauticContactClientBundle\Integration\ClientIntegration;
use Symfony\Component\HttpFoundation\Request;
Expand All @@ -34,8 +35,8 @@ class AjaxController extends CommonAjaxController
*/
public function ajaxTimelineAction(Request $request)
{
$filters = [];
$eventsModel = $this->get('mautic.contactclient.model.contactclient');
$filters = [];
$contactClientModel = $this->get('mautic.contactclient.model.contactclient');

foreach ($request->request->get('filters') as $key => $filter) {
$filter['name'] = str_replace(
Expand All @@ -46,7 +47,7 @@ public function ajaxTimelineAction(Request $request)
$filters[$filter['name']] = $filter['value'];
}
if (isset($filters['contactClientId'])) {
if (!$contactClient = $eventsModel->getEntity($filters['contactClientId'])) {
if (!$contactClient = $contactClientModel->getEntity($filters['contactClientId'])) {
throw new \InvalidArgumentException('Contact Client argument is Invalid.');
}
} else {
Expand All @@ -56,7 +57,7 @@ public function ajaxTimelineAction(Request $request)
$page = isset($filters['page']) ? $filters['page'] : 1;
$limit = isset($filters['limit']) ? $filters['limit'] : 25;

$events = $eventsModel->getEngagements($contactClient, $filters, $orderBy, $page, $limit, true);
$events = $contactClientModel->getEngagements($contactClient, $filters, $orderBy, $page, $limit, true);
$view = $this->render(
'MauticContactClientBundle:Timeline:list.html.php',
[
Expand Down Expand Up @@ -175,6 +176,17 @@ protected function getTokensAction(Request $request)
'success' => 0,
];

// Get an array representation of the current payload (of last save) for context.
$filePayload = [];
// Leaving File payload out of the tokens for now, since token use is not cognizant of the type yet.
// $filePayload = html_entity_decode(InputHelper::clean($request->request->get('filePayload')));
// $filePayload = json_decode($filePayload, true);
// $filePayload = is_array($filePayload) ? $filePayload : [];
$apiPayload = html_entity_decode(InputHelper::clean($request->request->get('apiPayload')));
$apiPayload = json_decode($apiPayload, true);
$apiPayload = is_array($apiPayload) ? $apiPayload : [];
$payload = array_merge($filePayload, $apiPayload);

/** @var \Mautic\LeadBundle\Model\FieldModel $fieldModel */
$fieldModel = $this->get('mautic.lead.model.field');

Expand Down Expand Up @@ -210,7 +222,7 @@ protected function getTokensAction(Request $request)

/** @var TokenHelper $tokenHelper */
$tokenHelper = $this->get('mautic.contactclient.helper.token');
$tokenHelper->addContextContact($contact);
$tokenHelper->newSession(null, $contact, $payload);

$tokens = $tokenHelper->getContext(true);
if ($tokens) {
Expand Down
134 changes: 128 additions & 6 deletions Helper/TokenHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,18 @@ public function __construct(CoreParametersHelper $coreParametersHelper)
* @param ContactClient|null $contactClient
* @param Contact|null $contact
* @param array $payload
* @param null $campaign
* @param array $event
*
* @return $this
*/
public function newSession(ContactClient $contactClient = null, Contact $contact = null, $payload = [])
{
public function newSession(
ContactClient $contactClient = null,
Contact $contact = null,
$payload = [],
$campaign = null,
$event = []
) {
$this->context = [];
$this->renderCache = [];
if ($this->engine->hasHelper('date')) {
Expand All @@ -99,6 +106,8 @@ public function newSession(ContactClient $contactClient = null, Contact $contact
$this->setContactClient($contactClient);
$this->addContextContact($contact);
$this->addContextPayload($payload);
$this->addContextCampaign($campaign);
$this->addContextEvent($event);

return $this;
}
Expand All @@ -110,7 +119,7 @@ public function newSession(ContactClient $contactClient = null, Contact $contact
*/
public function setContactClient(ContactClient $contactClient = null)
{
if ($contactClient !== $this->contactClient) {
if ($contactClient && $contactClient !== $this->contactClient) {
$this->contactClient = $contactClient;

// Set the timezones for date/time conversion.
Expand Down Expand Up @@ -261,7 +270,7 @@ public function addContextContact(Contact $contact = null)
// $contacts = !empty($this->context['contacts']) ? $this->context['contacts'] : [];

// Set the context to this contact.
$this->context = $context;
$this->context = array_merge($this->context, $context);

// Support multiple contacts for future batch processing.
// $this->context['contacts'] = $contacts;
Expand Down Expand Up @@ -320,6 +329,77 @@ public function addContextPayload($payload = [], $operationId = null, $responseA
}
}

/**
* @param null $campaign
*/
public function addContextCampaign($campaign = null)
{
$this->context['campaign']['id'] = $campaign ? $campaign->getId() : null;
}

/**
* Take an event array and use it to enhance the context for later dispositional callback.
* Campaign context should be added before this, as it is used for the token.
*
* @param array $event
*/
public function addContextEvent($event = [])
{
$contactId = isset($this->context['id']) ? $this->context['id'] : 0;
$this->context['event']['id'] = !empty($event['id']) ? (int) $event['id'] : null;
$this->context['event']['name'] = !empty($event['name']) ? $event['name'] : null;
$this->context['event']['token'] = null;
if ($contactId || $this->context['event']['id'] || $this->context['campaign']['id']) {
$this->context['event']['token'] = $this->eventTokenEncode(
[
$this->context['campaign']['id'],
$this->context['event']['id'],
$contactId,
]
);
}
}

/**
* Encode Campaign ID, Event ID, and Contact ID into a short base62 string.
* Zeros are used as delimiters reducing the subsequent integers to base61.
*
* @param $values
*
* @return string
*/
private function eventTokenEncode($values)
{
list($campaignId, $eventId, $contactId) = $values;
$campaignIdString = $this->baseEncode((int) $campaignId);
$eventIdString = $this->baseEncode((int) $eventId);
$contactIdString = $this->baseEncode((int) $contactId);

return $campaignIdString.'0'.$eventIdString.'0'.$contactIdString;
}

/**
* @param $integer
* @param int $b
*
* @return string
*/
private function baseEncode($integer)
{
$b = 61;
$base = '123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$r = $integer % $b;
$result = $base[$r];
$q = floor($integer / $b);
while ($q) {
$r = $q % $b;
$q = floor($q / $b);
$result = $base[$r].$result;
}

return $result;
}

/**
* @param array $context
*
Expand Down Expand Up @@ -459,10 +539,11 @@ public function setContext($context = [])
* @param array $array
* @param string $keys
* @param bool $sort
* @param bool $payload
*
* @return array
*/
private function labels($array = [], $keys = '', $sort = true)
private function labels($array = [], $keys = '', $sort = true, $payload = false)
{
foreach ($array as $key => &$value) {
if (is_array($value)) {
Expand All @@ -471,7 +552,7 @@ private function labels($array = [], $keys = '', $sort = true)
unset($array[$key]);
continue;
} else {
$value = $this->labels($value, $keys.' '.$key);
$value = $this->labels($value, $keys.' '.$key, $sort, ($payload || 'payload' === $key));
}
} else {
if (is_bool($value) || null === $value || 0 === $value) {
Expand All @@ -488,6 +569,10 @@ private function labels($array = [], $keys = '', $sort = true)
$value = trim(preg_replace('/\s+/', ' ', implode(' ', $words[0])));
// One exception is UTM variables.
$value = str_replace('Utm ', 'UTM ', $value);
} elseif ($payload) {
// For payload tokens, don't label at all but express the path to the token instead.
// This is for advanced use.
$value = implode('.', explode(' ', trim($keys))).'.'.$key;
}
}
}
Expand Down Expand Up @@ -516,4 +601,41 @@ private function flattenArray($original, &$new = [], $delimiter = '.', $keys = '
}
}
}

/**
* Take a string from eventTokenEncode and reverse it to an array.
*
* @param $string
*
* @return array
*/
private function eventTokenDecode($string)
{
list($campaignIdString, $eventIdString, $contactIdString) = explode('0', $string);

return [
$this->baseDecode($campaignIdString),
$this->baseDecode($eventIdString),
$this->baseDecode($contactIdString),
];
}

/**
* @param $string
* @param int $b
*
* @return bool|float|int
*/
private function baseDecode($string)
{
$b = 61;
$base = '123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$limit = strlen($string);
$result = strpos($base, $string[0]);
for ($i = 1; $i < $limit; ++$i) {
$result = $b * $result + strpos($base, $string[$i]);
}

return $result;
}
}
5 changes: 2 additions & 3 deletions Model/ApiPayload.php
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ class ApiPayload
protected $contactClientModel;

/** @var array */
protected $event;
protected $event = [];

/** @var Campaign */
protected $campaign;
Expand Down Expand Up @@ -330,7 +330,7 @@ public function run()
// We will create and reuse the same Transport session throughout our operations.
/** @var Transport $transport */
$transport = $this->getTransport();
$tokenHelper = $this->tokenHelper->newSession($this->contactClient, $this->contact, $this->payload);
$tokenHelper = $this->tokenHelper->newSession($this->contactClient, $this->contact, $this->payload, $this->campaign, $this->event);
$updatePayload = (bool) $this->settings['autoUpdate'];
$opsRemaining = count($this->payload->operations);

Expand Down Expand Up @@ -474,7 +474,6 @@ private function updatePayload()
if (!$this->contactClient->isNew()) {
try {
$this->contactClientModel->saveEntity($this->contactClient);
$this->setLogs('Updated our response payload expectations.', 'payload');
} catch (\Exception $e) {
$this->setLogs('Unable to save updates to the payload. '.$e->getMessage(), 'error');
}
Expand Down
2 changes: 1 addition & 1 deletion Model/ApiPayloadOperation.php
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ public function run()

$this->setValid($valid);
$this->setLogs($valid, 'valid');
if ($this->updatePayload) {
if ($this->updatePayload && $this->test) {
$this->updatePayloadResponse();
}

Expand Down
2 changes: 1 addition & 1 deletion Model/ContactClientModel.php
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,7 @@ public function getTimeUnitFromDateRange($dateFrom, $dateTo)
$sameDay = $dateTo->format('d') == $dateFrom->format('d') ? 1 : 0;
$hourDiff = $dateTo->diff($dateFrom)->format('%h');
$minuteDiff = $dateTo->diff($dateFrom)->format('%i');
if ($sameDay && !intval($hourDiff) && intval($minutesDiff)) {
if ($sameDay && !intval($hourDiff) && intval($minuteDiff)) {
$unit = 'i';
}
$secondDiff = $dateTo->diff($dateFrom)->format('%s');
Expand Down
6 changes: 3 additions & 3 deletions Model/FilePayload.php
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ class FilePayload
protected $queue;

/** @var array */
protected $event;
protected $event = [];

/** @var Campaign */
protected $campaign;
Expand Down Expand Up @@ -457,7 +457,7 @@ private function getFieldValues()
{
$requestFields = [];
if (!empty($this->payload->body) && !is_string($this->payload->body)) {
$this->tokenHelper->newSession($this->contactClient, $this->contact, $this->payload);
$this->tokenHelper->newSession($this->contactClient, $this->contact, $this->payload, $this->campaign, $this->event);
$requestFields = $this->fieldValues($this->payload->body);
if ($this->file) {
$nullCsv = $this->file->getCsvNull();
Expand Down Expand Up @@ -1040,7 +1040,7 @@ private function fileGenerateTmp($compression = null)
*/
private function getFileName($compression = null)
{
$this->tokenHelper->newSession($this->contactClient, null, $this->payload);
$this->tokenHelper->newSession($this->contactClient, null, $this->payload, $this->campaign, $this->event);
$type = $this->file->getType();
$extension = $type.($compression ? '.'.$compression : '');
$this->tokenHelper->addContext(
Expand Down

0 comments on commit c2c3789

Please sign in to comment.