Skip to content

Commit

Permalink
Merge branch 'staging' into staging.error-new-entity
Browse files Browse the repository at this point in the history
  • Loading branch information
kuzmany committed May 19, 2019
2 parents 28f689e + b8ad211 commit c9ac87b
Show file tree
Hide file tree
Showing 225 changed files with 6,829 additions and 3,073 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ Installing from source is only recommended if you are comfortable using the comm

## Requirements

#### Contributors Agreement

By contributing to this project, you accept and agree to the [Contributors Agreement](https://www.mautic.org/contributors-agreement) in its entirety.

#### Development / Build process requirements

1. Mautic uses Git as a version control system. Download and install git for your OS from https://git-scm.com/.
Expand Down
6 changes: 4 additions & 2 deletions app/AppKernel.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class AppKernel extends Kernel
*
* @const integer
*/
const PATCH_VERSION = 1;
const PATCH_VERSION = 2;

/**
* Extra version identifier.
Expand Down Expand Up @@ -527,7 +527,9 @@ protected function initializeContainer()

// Warm up the cache if classes.php is missing or in dev mode
if (!$fresh && $this->container->has('cache_warmer')) {
$this->container->get('cache_warmer')->warmUp($this->container->getParameter('kernel.cache_dir'));
$warmer = $this->container->get('cache_warmer');
$warmer->enableOptionalWarmers();
$warmer->warmUp($this->container->getParameter('kernel.cache_dir'));
}
}

Expand Down
52 changes: 48 additions & 4 deletions app/bundles/CampaignBundle/Assets/js/campaign.js
Original file line number Diff line number Diff line change
Expand Up @@ -1868,21 +1868,23 @@ Mautic.campaignBuilderValidateConnection = function (epDetails, targetType, targ
*/
Mautic.updateScheduledCampaignEvent = function(eventId, contactId) {
// Convert scheduled date/time to an input
mQuery('#timeline-campaign-event-'+eventId+' .btn-edit').prop('disabled', true).addClass('disabled');
mQuery('#timeline-campaign-event-'+eventId+' .btn-reschedule').addClass('disabled');

var converting = false;
var eventWrapper = '#timeline-campaign-event-'+eventId;
var eventSpan = '.timeline-campaign-event-date-'+eventId;
var eventText = '#timeline-campaign-event-text-'+eventId;
var saveButton = '#timeline-campaign-event-save-' + eventId;
var originalDate = mQuery(eventWrapper+' '+eventSpan).first().text();
var revertInput = function(input) {
converting = true;
mQuery(input).datetimepicker('destroy');
mQuery(eventSpan).text(originalDate);
mQuery(eventWrapper+' .btn').prop('disabled', false).removeClass('disabled');
mQuery(eventWrapper+' .btn-reschedule').removeClass('disabled');
};

var date = mQuery(eventSpan).attr('data-date');
mQuery(saveButton).show();
var input = mQuery('<input type="text" id="timeline-reschedule"/>')
.css('height', '20px')
.css('color', '#000000')
Expand All @@ -1902,30 +1904,72 @@ Mautic.updateScheduledCampaignEvent = function(eventId, contactId) {
originalDate: date
}, function (response) {
mQuery(eventSpan).text(response.formattedDate);
mQuery(eventSpan).attr('data-data', response.date);
mQuery(eventWrapper+' .btn').prop('disabled', false).removeClass('disabled');
mQuery(eventSpan).attr('data-date', response.date);
mQuery(eventWrapper+' .btn-reschedule').removeClass('disabled');

if (response.success) {
mQuery(eventText).removeClass('text-warning').addClass('text-info');
mQuery(eventSpan).css('textDecoration', 'inherit');
mQuery('.fa.timeline-campaign-event-cancelled-'+eventId).remove();
mQuery('.timeline-campaign-event-scheduled-'+eventId).removeClass('hide');
mQuery('.timeline-campaign-event-cancelled-'+eventId).addClass('hide');
mQuery(saveButton).hide();
}
}, false
);
} else if (code == 27) {
e.preventDefault();
revertInput(input);
mQuery(saveButton).hide();
}
})
.on('blur', function (e) {
if (!converting) {
revertInput(input);
}
mQuery(saveButton).hide();
});
mQuery('#timeline-campaign-event-'+eventId+' '+eventSpan).html(input);
Mautic.activateDateTimeInputs('#timeline-reschedule');
mQuery('#timeline-reschedule').focus();
};

/**
*
* @param eventId
* @param contactId
*/
Mautic.saveScheduledCampaignEvent = function (eventId, contactId) {
var saveButton = '#timeline-campaign-event-save-' + eventId;
mQuery(saveButton).addClass('disabled');

// Convert scheduled date/time to an input
var eventWrapper = '#timeline-campaign-event-' + eventId;
var eventSpan = '.timeline-campaign-event-date-' + eventId;
var eventText = '#timeline-campaign-event-text-' + eventId;

var date = mQuery(eventSpan).attr('data-date');
Mautic.ajaxActionRequest('campaign:updateScheduledCampaignEvent',
{
eventId: eventId,
contactId: contactId,
date: mQuery('#timeline-reschedule').val(),
originalDate: date
}, function (response) {
mQuery(eventSpan).text(response.formattedDate);
mQuery(eventSpan).attr('data-date', response.date);

if (response.success) {
mQuery(eventText).removeClass('text-warning').addClass('text-info');
mQuery(eventSpan).css('textDecoration', 'inherit');
mQuery('.fa.timeline-campaign-event-cancelled-' + eventId).remove();
mQuery('.timeline-campaign-event-scheduled-' + eventId).removeClass('hide');
mQuery('.timeline-campaign-event-cancelled-' + eventId).addClass('hide');
}

mQuery(saveButton).removeClass('disabled').hide();
mQuery(eventWrapper + ' .btn-reschedule').removeClass('disabled');
}, false);
};

/**
Expand Down
1 change: 1 addition & 0 deletions app/bundles/CampaignBundle/Config/config.php
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,7 @@
'mautic.campaign.model.event',
'mautic.campaign.model.campaign',
'mautic.helper.ip_lookup',
'mautic.campaign.scheduler',
],
],
],
Expand Down
53 changes: 37 additions & 16 deletions app/bundles/CampaignBundle/Controller/CampaignController.php
Original file line number Diff line number Diff line change
Expand Up @@ -680,33 +680,54 @@ protected function getViewArguments(array $args, $action)
$dateRangeForm = $this->get('form.factory')->create('daterange', $dateRangeValues, ['action' => $action]);

/** @var LeadEventLogRepository $eventLogRepo */
$eventLogRepo = $this->getDoctrine()->getManager()->getRepository('MauticCampaignBundle:LeadEventLog');
$events = $this->getCampaignModel()->getEventRepository()->getCampaignEvents($entity->getId());
$leadCount = $this->getCampaignModel()->getRepository()->getCampaignLeadCount($entity->getId());
$campaignLogCounts = $eventLogRepo->getCampaignLogCounts($entity->getId(), false, false);
$sortedEvents = [
$eventLogRepo = $this->getDoctrine()->getManager()->getRepository('MauticCampaignBundle:LeadEventLog');
$events = $this->getCampaignModel()->getEventRepository()->getCampaignEvents($entity->getId());
$leadCount = $this->getCampaignModel()->getRepository()->getCampaignLeadCount($entity->getId());
$campaignLogCounts = $eventLogRepo->getCampaignLogCounts($entity->getId(), false, false, true);
$pendingCampaignLogCounts = $eventLogRepo->getCampaignLogCounts($entity->getId(), false, false);
$sortedEvents = [
'decision' => [],
'action' => [],
'condition' => [],
];

foreach ($events as $event) {
$event['logCount'] =
$event['percent'] =
$event['yesPercent'] =
$event['noPercent'] = 0;
$event['leadCount'] = $leadCount;
foreach ($events as &$event) {
$event['logCount'] =
$event['logCountForPending'] =
$event['percent'] =
$event['yesPercent'] =
$event['noPercent'] = 0;
$event['leadCount'] = $leadCount;

if (isset($campaignLogCounts[$event['id']])) {
$event['logCount'] = array_sum($campaignLogCounts[$event['id']]);
$event['logCount'] = array_sum($campaignLogCounts[$event['id']]);
$event['logCountForPending'] = isset($pendingCampaignLogCounts[$event['id']]) ? array_sum($pendingCampaignLogCounts[$event['id']]) : 0;

$pending = $event['leadCount'] - $event['logCountForPending'];
$totalYes = $campaignLogCounts[$event['id']][1];
$totalNo = $campaignLogCounts[$event['id']][0];
$total = $totalYes + $totalNo + $pending;
if ($leadCount) {
$event['percent'] = round(($event['logCount'] / $leadCount) * 100, 1);
$event['yesPercent'] = round(($campaignLogCounts[$event['id']][1] / $leadCount) * 100, 1);
$event['noPercent'] = round(($campaignLogCounts[$event['id']][0] / $leadCount) * 100, 1);
$event['percent'] = round(($event['logCount'] / $total) * 100, 1);
$event['yesPercent'] = round(($campaignLogCounts[$event['id']][1] / $total) * 100, 1);
$event['noPercent'] = round(($campaignLogCounts[$event['id']][0] / $total) * 100, 1);
}
}
}

// rewrite stats data from parent condition if exist
foreach ($events as &$event) {
if (!empty($event['decisionPath']) && !empty($event['parent_id']) && isset($events[$event['parent_id']])) {
$parentEvent = $events[$event['parent_id']];
$event['logCountForPending'] = $parentEvent['logCountForPending'];
$event['percent'] = $parentEvent['percent'];
$event['yesPercent'] = $parentEvent['yesPercent'];
$event['noPercent'] = $parentEvent['noPercent'];
if ($event['decisionPath'] == 'yes') {
$event['noPercent'] = 0;
} else {
$event['yesPercent'] = 0;
}
}
$sortedEvents[$event['eventType']][] = $event;
}

Expand Down
23 changes: 15 additions & 8 deletions app/bundles/CampaignBundle/Entity/LeadEventLogRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -215,19 +215,26 @@ public function getUpcomingEvents(array $options = null)
/**
* @param $campaignId
* @param bool $excludeScheduled
* @param bool $excludeNegative
* @param bool $all
*
* @return array
*/
public function getCampaignLogCounts($campaignId, $excludeScheduled = false, $excludeNegative = true)
public function getCampaignLogCounts($campaignId, $excludeScheduled = false, $excludeNegative = true, $all = false)
{
$q = $this->getSlaveConnection()->createQueryBuilder()
->from(MAUTIC_TABLE_PREFIX.'campaign_lead_event_log', 'o')
->innerJoin(
'o',
MAUTIC_TABLE_PREFIX.'campaign_leads',
'l',
'l.campaign_id = '.(int) $campaignId.' and l.manually_removed = 0 and o.lead_id = l.lead_id and l.rotation = o.rotation'
);
->from(MAUTIC_TABLE_PREFIX.'campaign_lead_event_log', 'o');

$join = 'innerJoin';
if ($all === true) {
$join = 'leftJoin';
}
$q->$join(
'o',
MAUTIC_TABLE_PREFIX.'campaign_leads',
'l',
'l.campaign_id = '.(int) $campaignId.' and l.manually_removed = 0 and o.lead_id = l.lead_id and l.rotation = o.rotation'
);

$expr = $q->expr()->andX(
$q->expr()->eq('o.campaign_id', (int) $campaignId)
Expand Down
4 changes: 2 additions & 2 deletions app/bundles/CampaignBundle/Event/CampaignExecutionEvent.php
Original file line number Diff line number Diff line change
Expand Up @@ -233,8 +233,8 @@ public function wasLogUpdatedByListener()
}

/**
* @param $channel
* @param null $channelId
* @param string $channel
* @param string|int|null $channelId
*
* @return $this
*/
Expand Down
2 changes: 1 addition & 1 deletion app/bundles/CampaignBundle/Model/CampaignModel.php
Original file line number Diff line number Diff line change
Expand Up @@ -653,7 +653,7 @@ public function saveCampaignLead(CampaignLead $campaignLead)

return true;
} catch (\Exception $exception) {
$this->logger->log('error', $exception->getMessage());
$this->logger->log('error', $exception->getMessage(), ['exception' => $exception]);

return false;
}
Expand Down
33 changes: 14 additions & 19 deletions app/bundles/CampaignBundle/Model/EventLogModel.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,9 @@

namespace Mautic\CampaignBundle\Model;

use Mautic\CampaignBundle\CampaignEvents;
use Mautic\CampaignBundle\Entity\Event;
use Mautic\CampaignBundle\Entity\LeadEventLog;
use Mautic\CampaignBundle\Event\CampaignScheduledEvent;
use Mautic\CampaignBundle\Executioner\Scheduler\EventScheduler;
use Mautic\CoreBundle\Helper\InputHelper;
use Mautic\CoreBundle\Helper\IpLookupHelper;
use Mautic\CoreBundle\Model\AbstractCommonModel;
Expand All @@ -40,18 +39,24 @@ class EventLogModel extends AbstractCommonModel
*/
protected $ipLookupHelper;

/**
* @var EventScheduler
*/
protected $eventScheduler;

/**
* EventLogModel constructor.
*
* @param EventModel $eventModel
* @param CampaignModel $campaignModel
* @param IpLookupHelper $ipLookupHelper
*/
public function __construct(EventModel $eventModel, CampaignModel $campaignModel, IpLookupHelper $ipLookupHelper)
public function __construct(EventModel $eventModel, CampaignModel $campaignModel, IpLookupHelper $ipLookupHelper, EventScheduler $eventScheduler)
{
$this->eventModel = $eventModel;
$this->campaignModel = $campaignModel;
$this->ipLookupHelper = $ipLookupHelper;
$this->eventScheduler = $eventScheduler;
}

/**
Expand Down Expand Up @@ -198,26 +203,16 @@ public function updateContactEvent(Event $event, Lead $contact, array $parameter
}

/**
* @param $entity
* @param LeadEventLog $entity
*/
public function saveEntity(LeadEventLog $entity)
{
$eventSettings = $this->campaignModel->getEvents();
if ($this->dispatcher->hasListeners(CampaignEvents::ON_EVENT_SCHEDULED)) {
$event = $entity->getEvent();
$args = [
'eventSettings' => $eventSettings[$event->getEventType()][$event->getType()],
'eventDetails' => null,
'event' => $event->convertToArray(),
'lead' => $entity->getLead(),
'systemTriggered' => false,
'dateScheduled' => $entity->getTriggerDate(),
];

$scheduledEvent = new CampaignScheduledEvent($args, $entity);
$this->dispatcher->dispatch(CampaignEvents::ON_EVENT_SCHEDULED, $scheduledEvent);
$triggerDate = $entity->getTriggerDate();
if (null === $triggerDate) {
// Reschedule for now
$triggerDate = new \DateTime();
}

$this->getRepository()->saveEntity($entity);
$this->eventScheduler->reschedule($entity, $triggerDate);
}
}
4 changes: 2 additions & 2 deletions app/bundles/CampaignBundle/Tests/Command/campaign_schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ VALUES
(15,1,3,'Tag EmailNotOpen Again',NULL,'lead.changetags','action',3,'a:16:{s:14:\"canvasSettings\";a:2:{s:8:\"droppedX\";s:4:\"1612\";s:8:\"droppedY\";s:3:\"374\";}s:4:\"name\";s:22:\"Tag EmailNotOpen Again\";s:11:\"triggerMode\";s:8:\"interval\";s:11:\"triggerDate\";N;s:15:\"triggerInterval\";s:1:\"6\";s:19:\"triggerIntervalUnit\";s:1:\"i\";s:6:\"anchor\";s:2:\"no\";s:10:\"properties\";a:1:{s:8:\"add_tags\";a:1:{i:0;s:1:\"9\";}}s:4:\"type\";s:15:\"lead.changetags\";s:9:\"eventType\";s:6:\"action\";s:15:\"anchorEventType\";s:8:\"decision\";s:10:\"campaignId\";s:1:\"1\";s:6:\"_token\";s:43:\"Wd8bGtv2HJ6Nyf3K90Efoo2Rn2VkDWwXhwzCIPMiD-M\";s:7:\"buttons\";a:1:{s:4:\"save\";s:0:\"\";}s:8:\"add_tags\";a:1:{i:0;s:12:\"EmailNotOpen\";}s:11:\"remove_tags\";a:0:{}}',NULL,6,'i','interval','no','newf16dfec5f2a65aa9c527675e7be516020a90daa6',NULL,NULL),
(16,1,12,'Tag ChainedAction',NULL,'lead.changetags','action',4,'a:16:{s:14:\"canvasSettings\";a:2:{s:8:\"droppedX\";s:3:\"168\";s:8:\"droppedY\";s:3:\"439\";}s:4:\"name\";s:14:\"Chained Action\";s:11:\"triggerMode\";s:9:\"immediate\";s:11:\"triggerDate\";N;s:15:\"triggerInterval\";s:1:\"1\";s:19:\"triggerIntervalUnit\";s:1:\"d\";s:6:\"anchor\";s:6:\"bottom\";s:10:\"properties\";a:1:{s:8:\"add_tags\";a:1:{i:0;s:2:\"10\";}}s:4:\"type\";s:15:\"lead.changetags\";s:9:\"eventType\";s:6:\"action\";s:15:\"anchorEventType\";s:6:\"action\";s:10:\"campaignId\";s:1:\"1\";s:6:\"_token\";s:43:\"6xgHe74aRnc1V7AGzdang3-iJ0Ub5BKfbdU5NsxQmv0\";s:7:\"buttons\";a:1:{s:4:\"save\";s:0:\"\";}s:8:\"add_tags\";a:1:{i:0;s:13:\"ChainedAction\";}s:11:\"remove_tags\";a:0:{}}',NULL,1,'d','immediate',NULL,'new60f74507aeccf217f78647e41ae29af51debe666',NULL,NULL);

INSERT INTO `#__lead_lists` (`id`,`is_published`,`date_added`,`created_by`,`created_by_user`,`date_modified`,`modified_by`,`modified_by_user`,`checked_out`,`checked_out_by`,`checked_out_by_user`,`name`,`description`,`alias`,`filters`,`is_global`)
INSERT INTO `#__lead_lists` (`id`,`is_preference_center`, `is_published`,`date_added`,`created_by`,`created_by_user`,`date_modified`,`modified_by`,`modified_by_user`,`checked_out`,`checked_out_by`,`checked_out_by_user`,`name`,`description`,`alias`,`filters`,`is_global`)
VALUES
(1,1,'2018-01-04 23:41:20',1,'Admin User',NULL,NULL,NULL,NULL,NULL,NULL,'Campaign Test',NULL,'campaign-test','a:0:{}',1);
(1,0,1,'2018-01-04 23:41:20',1,'Admin User',NULL,NULL,NULL,NULL,NULL,NULL,'Campaign Test',NULL,'campaign-test','a:0:{}',1);

INSERT INTO `#__campaign_leadlist_xref` (`campaign_id`,`leadlist_id`)
VALUES
Expand Down
1 change: 1 addition & 0 deletions app/bundles/CampaignBundle/Translations/en_US/messages.ini
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ mautic.campaign.event.timed.choice.custom="Custom"
mautic.campaign.event.leadchange="contact changed campaigns"
mautic.campaign.event.leadchange_descr="Trigger actions when a contact is added/removed from a campaign."
mautic.campaign.event.reschedule="Reschedule this event."
mautic.campaign.event.save="Save"
mautic.campaign.event.cancel="Cancel this event (it can be rescheduled later)."
mautic.campaign.event.cancelled="This event has been cancelled. Reschedule it to restore."
mautic.campaign.event.cancelled.time="This event was scheduled for %date% but has been cancelled."
Expand Down
2 changes: 1 addition & 1 deletion app/bundles/CampaignBundle/Views/Campaign/events.html.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
<?php echo $event['noPercent'].'%'; ?>
</span>
<?php endif; ?>
<span class="mt-xs label label-warning" data-toggle="tooltip" title="<?php echo $view['translator']->trans('mautic.report.campaign.completed.actions'); ?>"><?= $event['logCount']; ?></span> <span class="mt-xs label label-default" data-toggle="tooltip" title="<?php echo $view['translator']->trans('mautic.report.campaign.pending.actions'); ?>"><?= $event['leadCount'] - $event['logCount']; ?></span>
<span class="mt-xs label label-warning" data-toggle="tooltip" title="<?php echo $view['translator']->trans('mautic.report.campaign.completed.actions'); ?>"><?= $event['logCount']; ?></span> <span class="mt-xs label label-default" data-toggle="tooltip" title="<?php echo $view['translator']->trans('mautic.report.campaign.pending.actions'); ?>"><?= $event['leadCount'] - $event['logCountForPending']; ?></span>
</div>
<div class="col-md-5 va-m">
<h5 class="fw-sb text-primary mb-xs">
Expand Down

0 comments on commit c9ac87b

Please sign in to comment.