From 1ff44d616d6d382766527c4187021861f599088b Mon Sep 17 00:00:00 2001 From: nithinga Date: Mon, 26 Sep 2016 17:16:26 +0530 Subject: [PATCH 1/3] Campaign action: timed action based on a contact field --- .../Translations/en_US/messages.ini | 4 ++ .../LeadBundle/Controller/AjaxController.php | 7 ++- .../LeadBundle/Entity/LeadFieldRepository.php | 58 +++++++++++++++++++ .../EventListener/CampaignSubscriber.php | 54 ++++++++++++++--- .../Type/CampaignEventLeadFieldValueType.php | 7 ++- .../LeadBundle/Helper/FormFieldHelper.php | 31 ++++++++++ app/bundles/LeadBundle/Model/LeadModel.php | 6 ++ .../Translations/en_US/messages.ini | 1 + 8 files changed, 159 insertions(+), 9 deletions(-) diff --git a/app/bundles/CampaignBundle/Translations/en_US/messages.ini b/app/bundles/CampaignBundle/Translations/en_US/messages.ini index 3ead1082e4a..d3938718de7 100644 --- a/app/bundles/CampaignBundle/Translations/en_US/messages.ini +++ b/app/bundles/CampaignBundle/Translations/en_US/messages.ini @@ -32,6 +32,10 @@ mautic.campaign.event.intervalunit.h="{0} hours|{1} hour|[2,Inf] hours" mautic.campaign.event.intervalunit.i="{0} minutes|{1} minute|[2,Inf] minutes" mautic.campaign.event.intervalunit.m="{0} months|{1} month|[2,Inf] months" mautic.campaign.event.intervalunit.y="{0} years|{1} year|[2,Inf] years" +mautic.campaign.event.timed.choice.today="Is Today" +mautic.campaign.event.timed.choice.yesterday="Is Yesterday" +mautic.campaign.event.timed.choice.tomorrow="Is Tomorrow" +mautic.campaign.event.timed.choice.anniversary="Anniversary" 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.systemchanges.header="System Changes" diff --git a/app/bundles/LeadBundle/Controller/AjaxController.php b/app/bundles/LeadBundle/Controller/AjaxController.php index 3b4c3b3ae42..5bdf58f313a 100644 --- a/app/bundles/LeadBundle/Controller/AjaxController.php +++ b/app/bundles/LeadBundle/Controller/AjaxController.php @@ -697,7 +697,7 @@ protected function updateLeadFieldValuesAction(Request $request) $alias = InputHelper::clean($request->request->get('alias')); $dataArray = ['success' => 0, 'options' => null]; $leadField = $this->getModel('lead.field')->getRepository()->findOneBy(['alias' => $alias]); - $choiceTypes = ['boolean', 'locale', 'country', 'region', 'lookup', 'timezone', 'select', 'radio']; + $choiceTypes = ['boolean', 'locale', 'country', 'region', 'lookup', 'timezone', 'select', 'radio', 'date']; if ($leadField && in_array($leadField->getType(), $choiceTypes)) { $properties = $leadField->getProperties(); @@ -726,6 +726,11 @@ protected function updateLeadFieldValuesAction(Request $request) case 'locale': $options = FormFieldHelper::getLocaleChoices(); break; + case 'date': + $fieldHelper = new FormFieldHelper(); + $fieldHelper->setTranslator($this->get('translator')); + $options = $fieldHelper->getDateChoices(); + break; default: $options = (!empty($properties)) ? $properties : []; } diff --git a/app/bundles/LeadBundle/Entity/LeadFieldRepository.php b/app/bundles/LeadBundle/Entity/LeadFieldRepository.php index 4dd2040e8cf..b404dc9bf0b 100644 --- a/app/bundles/LeadBundle/Entity/LeadFieldRepository.php +++ b/app/bundles/LeadBundle/Entity/LeadFieldRepository.php @@ -143,4 +143,62 @@ public function compareValue($lead, $field, $value, $operatorExpr) return !empty($result['id']); } + /** + * Compare a form result value with defined date value for defined lead. + * + * @param integer $lead ID + * @param integer $field alias + * @param string $value to compare with + * + * @return boolean + */ + public function compareDateValue($lead, $field, $value) + { + $q = $this->_em->getConnection()->createQueryBuilder(); + $q->select('l.id') + ->from(MAUTIC_TABLE_PREFIX . 'leads', 'l') + ->where( + $q->expr()->andX( + $q->expr()->eq('l.id', ':lead'), + $q->expr()->eq('l.' . $field, ':value') + ) + ) + ->setParameter('lead', (int) $lead) + ->setParameter('value', $value); + + $result = $q->execute()->fetch(); + + return !empty($result['id']); + } + + /** + * Compare a form result value with defined date value ( only day and month compare for + * events such as anniversary) for defined lead. + * + * @param integer $lead ID + * @param integer $field alias + * @param object $value Date object to compare with + * + * @return boolean + */ + public function compareDateMonthValue($lead, $field, $value) + { + $q = $this->_em->getConnection()->createQueryBuilder(); + $q->select('l.id') + ->from(MAUTIC_TABLE_PREFIX . 'leads', 'l') + ->where( + $q->expr()->andX( + $q->expr()->eq('l.id', ':lead'), + $q->expr()->eq("MONTH(l. $field)", ':month'), + $q->expr()->eq("DAY(l. $field)", ':day') + ) + ) + ->setParameter('lead', (int) $lead) + ->setParameter('month', $value->format('m')) + ->setParameter('day', $value->format('d')); + + $result = $q->execute()->fetch(); + + return !empty($result['id']); + } } diff --git a/app/bundles/LeadBundle/EventListener/CampaignSubscriber.php b/app/bundles/LeadBundle/EventListener/CampaignSubscriber.php index f56e26cf1b3..9326aaf09e7 100644 --- a/app/bundles/LeadBundle/EventListener/CampaignSubscriber.php +++ b/app/bundles/LeadBundle/EventListener/CampaignSubscriber.php @@ -242,15 +242,55 @@ public function onCampaignTriggerCondition(CampaignExecutionEvent $event) return $event->setResult(false); } - $operators = $this->leadModel->getFilterExpressionFunctions(); + if ($event->getConfig()['operator'] === 'date') { + $triggerDate = new \DateTime(); + $interval = substr($event->getConfig()['value'], 1); // remove 1st character + or - + + if (strpos($event->getConfig()['value'], '+P') !== FALSE) { //add date + $triggerDate->sub(new \DateInterval($interval)); //sub the today date with interval + $result = $this->compareDateValue($lead, $event, $triggerDate); + } else if (strpos($event->getConfig()['value'], '-P') !== FALSE) { //subtract date + $triggerDate->add(new \DateInterval($interval)); + $result = $this->compareDateValue($lead, $event, $triggerDate); + } else if ($event->getConfig()['value'] === 'anniversary') { + /** + * note: currently mautic campaign only one time execution + * ( to integrate with: recursive campaign (future)) + */ + $result = $this->leadFieldModel->getRepository()->compareDateMonthValue( + $lead->getId(), $event->getConfig()['field'], $triggerDate); + } + } else { + $operators = $this->leadModel->getFilterExpressionFunctions(); + + $result = $this->leadFieldModel->getRepository()->compareValue( + $lead->getId(), + $event->getConfig()['field'], + $event->getConfig()['value'], + $operators[$event->getConfig()['operator']]['expr'] + ); + } - $result = $this->leadFieldModel->getRepository()->compareValue( - $lead->getId(), - $event->getConfig()['field'], - $event->getConfig()['value'], - $operators[$event->getConfig()['operator']]['expr'] + return $event->setResult($result); + } + + /** + * Function to compare date value. + * + * @param obj $lead + * @param obj $event + * @param obj $triggerDate + * + * @return type + */ + private function compareDateValue($lead, $event, $triggerDate) + { + $result = $this->leadFieldModel->getRepository()->compareDateValue( + $lead->getId(), + $event->getConfig()['field'], + $triggerDate->format('Y-m-d') ); - return $event->setResult($result); + return $result; } } diff --git a/app/bundles/LeadBundle/Form/Type/CampaignEventLeadFieldValueType.php b/app/bundles/LeadBundle/Form/Type/CampaignEventLeadFieldValueType.php index 2e42605d8ec..297205946a7 100644 --- a/app/bundles/LeadBundle/Form/Type/CampaignEventLeadFieldValueType.php +++ b/app/bundles/LeadBundle/Form/Type/CampaignEventLeadFieldValueType.php @@ -84,7 +84,7 @@ public function buildForm(FormBuilderInterface $builder, array $options) $fieldValues = null; $fieldType = null; - $choiceTypes = ['boolean', 'locale', 'country', 'region', 'lookup', 'timezone', 'select', 'radio']; + $choiceTypes = ['boolean', 'locale', 'country', 'region', 'lookup', 'timezone', 'select', 'radio', 'date']; if (isset($data['field'])) { $field = $fieldModel->getRepository()->findOneBy(['alias' => $data['field']]); @@ -116,6 +116,11 @@ public function buildForm(FormBuilderInterface $builder, array $options) case 'locale': $fieldValues = FormFieldHelper::getLocaleChoices(); break; + case 'date': + $fieldHelper = new FormFieldHelper(); + $fieldHelper->setTranslator($this->factory->getTranslator()); + $fieldValues = $fieldHelper->getDateChoices(); + break; default: if (!empty($properties)) { $fieldValues = $properties; diff --git a/app/bundles/LeadBundle/Helper/FormFieldHelper.php b/app/bundles/LeadBundle/Helper/FormFieldHelper.php index cee9dcf9a62..cc9f6941f64 100644 --- a/app/bundles/LeadBundle/Helper/FormFieldHelper.php +++ b/app/bundles/LeadBundle/Helper/FormFieldHelper.php @@ -223,6 +223,37 @@ static function getLocaleChoices() return Intl::getLocaleBundle()->getLocaleNames(); } + /** + * Get date field choices + * + * @return array + */ + public function getDateChoices() + { + $options = [ + 'anniversary' => $this->translator->trans('mautic.campaign.event.timed.choice.anniversary'), + '+P0D' => $this->translator->trans('mautic.campaign.event.timed.choice.today'), + '-P1D' => $this->translator->trans('mautic.campaign.event.timed.choice.yesterday'), + '+P1D' => $this->translator->trans('mautic.campaign.event.timed.choice.tomorrow'), + ]; + + $daysOptions = []; + for ($dayInterval = 2; $dayInterval <= 31; $dayInterval++) { + $daysOptions['+P'.$dayInterval.'D'] = '+ '.$dayInterval.' days'; + } + + $options = array_merge($options, $daysOptions); + + $beforeDaysOptions = []; + for ($dayInterval = 2; $dayInterval <= 31; $dayInterval++) { + $beforeDaysOptions['-P'.$dayInterval.'D'] = $dayInterval.' days before'; + } + + $options = array_merge($options, $beforeDaysOptions); + + return $options; + } + /** * @param $list * diff --git a/app/bundles/LeadBundle/Model/LeadModel.php b/app/bundles/LeadBundle/Model/LeadModel.php index dc3997e6966..0a7fe8c3c96 100644 --- a/app/bundles/LeadBundle/Model/LeadModel.php +++ b/app/bundles/LeadBundle/Model/LeadModel.php @@ -1727,6 +1727,12 @@ public function getFilterExpressionFunctions($operator = null) 'expr' => 'notLike', 'negate_expr' => 'like' ), + 'date' => + array( + 'label' => 'mautic.lead.list.form.operator.date', + 'expr' => 'date', + 'negate_expr' => 'date' + ), ); return ($operator === null) ? $operatorOptions : $operatorOptions[$operator]; diff --git a/app/bundles/LeadBundle/Translations/en_US/messages.ini b/app/bundles/LeadBundle/Translations/en_US/messages.ini index 8e9a34606eb..719eb92df9b 100644 --- a/app/bundles/LeadBundle/Translations/en_US/messages.ini +++ b/app/bundles/LeadBundle/Translations/en_US/messages.ini @@ -281,6 +281,7 @@ mautic.lead.list.form.operator.notbetween="not between" mautic.lead.list.form.operator.notequals="not equal" mautic.lead.list.form.operator.notin="excluding" mautic.lead.list.frequency.number="Do not contact more than" +mautic.lead.list.form.operator.date="date" mautic.lead.list.frequency.rules.msg="Frequency Rules have changed" mautic.lead.list.frequency.times="time(s) every" mautic.lead.list.header.edit="Edit Segment - %name%" From 9ffbd482880da7a3975176935ff9346a83a27a4f Mon Sep 17 00:00:00 2001 From: nithinga Date: Wed, 12 Oct 2016 11:49:59 +0530 Subject: [PATCH 2/3] correcting the logic error --- app/bundles/LeadBundle/EventListener/CampaignSubscriber.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/bundles/LeadBundle/EventListener/CampaignSubscriber.php b/app/bundles/LeadBundle/EventListener/CampaignSubscriber.php index 90fbb6ae6b7..e5e7fc60657 100644 --- a/app/bundles/LeadBundle/EventListener/CampaignSubscriber.php +++ b/app/bundles/LeadBundle/EventListener/CampaignSubscriber.php @@ -267,10 +267,10 @@ public function onCampaignTriggerCondition(CampaignExecutionEvent $event) $interval = substr($event->getConfig()['value'], 1); // remove 1st character + or - if (strpos($event->getConfig()['value'], '+P') !== FALSE) { //add date - $triggerDate->sub(new \DateInterval($interval)); //sub the today date with interval + $triggerDate->add(new \DateInterval($interval)); //add the today date with interval $result = $this->compareDateValue($lead, $event, $triggerDate); } else if (strpos($event->getConfig()['value'], '-P') !== FALSE) { //subtract date - $triggerDate->add(new \DateInterval($interval)); + $triggerDate->sub(new \DateInterval($interval)); //subtract the today date with interval $result = $this->compareDateValue($lead, $event, $triggerDate); } else if ($event->getConfig()['value'] === 'anniversary') { /** From c7dc4a5c71bf4a8658b5712fdbf78c02e576c797 Mon Sep 17 00:00:00 2001 From: Alan Hartless Date: Mon, 2 Jan 2017 00:33:04 -0600 Subject: [PATCH 3/3] Removed inherited deprecated method --- ...namic_content_filter_entry_widget.html.php | 2 +- .../LeadBundle/Helper/FormFieldHelper.php | 46 +++---------------- 2 files changed, 8 insertions(+), 40 deletions(-) diff --git a/app/bundles/EmailBundle/Views/FormTheme/Email/dynamic_content_filter_entry_widget.html.php b/app/bundles/EmailBundle/Views/FormTheme/Email/dynamic_content_filter_entry_widget.html.php index d5b4e64ef57..45564c4cbe2 100644 --- a/app/bundles/EmailBundle/Views/FormTheme/Email/dynamic_content_filter_entry_widget.html.php +++ b/app/bundles/EmailBundle/Views/FormTheme/Email/dynamic_content_filter_entry_widget.html.php @@ -38,7 +38,7 @@ $params): $list = (!empty($params['properties']['list'])) ? $params['properties']['list'] : []; - $choices = \Mautic\LeadBundle\Helper\FormFieldHelper::parseListStringIntoArray($list); + $choices = \Mautic\LeadBundle\Helper\FormFieldHelper::parseList($list); $list = json_encode($choices); $callback = (!empty($params['properties']['callback'])) ? $params['properties']['callback'] : ''; $operators = (!empty($params['operators'])) ? $view->escape(json_encode($params['operators'])) : '{}'; diff --git a/app/bundles/LeadBundle/Helper/FormFieldHelper.php b/app/bundles/LeadBundle/Helper/FormFieldHelper.php index 50cc569182f..9342de83525 100644 --- a/app/bundles/LeadBundle/Helper/FormFieldHelper.php +++ b/app/bundles/LeadBundle/Helper/FormFieldHelper.php @@ -230,7 +230,7 @@ public static function getLocaleChoices() } /** - * Get date field choices + * Get date field choices. * * @return array */ @@ -238,20 +238,20 @@ public function getDateChoices() { $options = [ 'anniversary' => $this->translator->trans('mautic.campaign.event.timed.choice.anniversary'), - '+P0D' => $this->translator->trans('mautic.campaign.event.timed.choice.today'), - '-P1D' => $this->translator->trans('mautic.campaign.event.timed.choice.yesterday'), - '+P1D' => $this->translator->trans('mautic.campaign.event.timed.choice.tomorrow'), + '+P0D' => $this->translator->trans('mautic.campaign.event.timed.choice.today'), + '-P1D' => $this->translator->trans('mautic.campaign.event.timed.choice.yesterday'), + '+P1D' => $this->translator->trans('mautic.campaign.event.timed.choice.tomorrow'), ]; $daysOptions = []; - for ($dayInterval = 2; $dayInterval <= 31; $dayInterval++) { + for ($dayInterval = 2; $dayInterval <= 31; ++$dayInterval) { $daysOptions['+P'.$dayInterval.'D'] = '+ '.$dayInterval.' days'; } $options = array_merge($options, $daysOptions); $beforeDaysOptions = []; - for ($dayInterval = 2; $dayInterval <= 31; $dayInterval++) { + for ($dayInterval = 2; $dayInterval <= 31; ++$dayInterval) { $beforeDaysOptions['-P'.$dayInterval.'D'] = $dayInterval.' days before'; } @@ -259,36 +259,4 @@ public function getDateChoices() return $options; } - - /** - * @param $list - * - * @return array - */ - static function parseListStringIntoArray($list) - { - if (!is_array($list) && strpos($list, '|') !== false) { - $parts = explode('||', $list); - if (count($parts) > 1) { - $labels = explode('|', $parts[0]); - $values = explode('|', $parts[1]); - $list = array_combine($values, $labels); - } else { - $labels = explode('|', $list); - $values = $labels; - $list = array_combine($values, $labels); - } - } - if (!empty($list) && !is_array($list)) { - $list = [$list => $list]; - } - - // Handle special chars so that validation doesn't fail - $choices = []; - foreach ($list as $val => $label) { - $choices[html_entity_decode($val, ENT_QUOTES)] = $label; - } - - return $choices; - } -} \ No newline at end of file +}