/** * @param CampaignExecutionEvent $event */ public function onCampaignTriggerCondition(CampaignExecutionEvent $event) { $lead = $event->getLead(); if (!$lead || !$lead->getId()) { return $event->setResult(false); } $operators = $this->leadModel->getFilterExpressionFunctions(); $result = $this->leadFieldModel->getRepository()->compareValue($lead->getId(), $event->getConfig()['field'], $event->getConfig()['value'], $operators[$event->getConfig()['operator']]['expr']); return $event->setResult($result); }
/** * Create/update lead from form submit * * @param $form * @param array $leadFieldMatches * * @return Lead */ protected function createLeadFromSubmit($form, array $leadFieldMatches) { //set the mapped data $leadFields = $this->leadFieldModel->getRepository()->getAliases(null, true, false); $inKioskMode = $form->isInKioskMode(); if (!$inKioskMode) { // Default to currently tracked lead $lead = $this->leadModel->getCurrentLead(); $leadId = $lead->getId(); $currentFields = $this->leadModel->flattenFields($lead->getFields()); $this->logger->debug('FORM: Not in kiosk mode so using current contact ID #' . $lead->getId()); } else { // Default to a new lead in kiosk mode $lead = new Lead(); $lead->setNewlyCreated(true); $currentFields = $leadFieldMatches; $leadId = null; $this->logger->debug('FORM: In kiosk mode so assuming a new contact'); } $uniqueLeadFields = $this->leadFieldModel->getUniqueIdentiferFields(); // Closure to get data and unique fields $getData = function ($currentFields, $uniqueOnly = false) use($leadFields, $uniqueLeadFields) { $uniqueFieldsWithData = $data = array(); foreach ($leadFields as $alias) { $data[$alias] = ''; if (isset($currentFields[$alias])) { $value = $currentFields[$alias]; $data[$alias] = $value; // make sure the value is actually there and the field is one of our uniques if (!empty($value) && array_key_exists($alias, $uniqueLeadFields)) { $uniqueFieldsWithData[$alias] = $value; } } } return $uniqueOnly ? $uniqueFieldsWithData : array($data, $uniqueFieldsWithData); }; // Closure to help search for a conflict $checkForIdentifierConflict = function ($fieldSet1, $fieldSet2) { // Find fields in both sets $potentialConflicts = array_keys(array_intersect_key($fieldSet1, $fieldSet2)); $this->logger->debug('FORM: Potential conflicts ' . implode(', ', array_keys($potentialConflicts)) . ' = ' . implode(', ', $potentialConflicts)); $conflicts = array(); foreach ($potentialConflicts as $field) { if (!empty($fieldSet1[$field]) && !empty($fieldSet2[$field])) { if (strtolower($fieldSet1[$field]) !== strtolower($fieldSet2[$field])) { $conflicts[] = $field; } } } return array(count($conflicts), $conflicts); }; // Get data for the form submission list($data, $uniqueFieldsWithData) = $getData($leadFieldMatches); $this->logger->debug('FORM: Unique fields submitted include ' . implode(', ', $uniqueFieldsWithData)); // Check for duplicate lead /** @var \Mautic\LeadBundle\Entity\Lead[] $leads */ $leads = !empty($uniqueFieldsWithData) ? $this->em->getRepository('MauticLeadBundle:Lead')->getLeadsByUniqueFields($uniqueFieldsWithData, $leadId) : array(); $uniqueFieldsCurrent = $getData($currentFields, true); if (count($leads)) { $this->logger->debug(count($leads) . ' found based on unique identifiers'); /** @var \Mautic\LeadBundle\Entity\Lead $foundLead */ $foundLead = $leads[0]; $this->logger->debug('FORM: Testing contact ID# ' . $foundLead->getId() . ' for conflicts'); // Check for a conflict with the currently tracked lead $foundLeadFields = $this->leadModel->flattenFields($foundLead->getFields()); // Get unique identifier fields for the found lead then compare with the lead currently tracked $uniqueFieldsFound = $getData($foundLeadFields, true); list($hasConflict, $conflicts) = $checkForIdentifierConflict($uniqueFieldsFound, $uniqueFieldsCurrent); if ($inKioskMode || $hasConflict) { // Use the found lead without merging because there is some sort of conflict with unique identifiers or in kiosk mode and thus should not merge $lead = $foundLead; if ($hasConflict) { $this->logger->debug('FORM: Conflicts found in ' . implode(', ', $conflicts) . ' so not merging'); } else { $this->logger->debug('FORM: In kiosk mode so not merging'); } } else { $this->logger->debug('FORM: Merging contacts ' . $lead->getId() . ' and ' . $foundLead->getId()); // Merge the found lead with currently tracked lead $lead = $this->leadModel->mergeLeads($lead, $foundLead); } // Update unique fields data for comparison with submitted data $currentFields = $this->leadModel->flattenFields($lead->getFields()); $uniqueFieldsCurrent = $getData($currentFields, true); } if (!$inKioskMode) { // Check for conflicts with the submitted data and the currently tracked lead list($hasConflict, $conflicts) = $checkForIdentifierConflict($uniqueFieldsWithData, $uniqueFieldsCurrent); $this->logger->debug('FORM: Current unique contact fields ' . implode(', ', array_keys($uniqueFieldsCurrent)) . ' = ' . implode(', ', $uniqueFieldsCurrent)); $this->logger->debug('FORM: Submitted unique contact fields ' . implode(', ', array_keys($uniqueFieldsWithData)) . ' = ' . implode(', ', $uniqueFieldsWithData)); if ($hasConflict) { // There's a conflict so create a new lead $lead = new Lead(); $lead->setNewlyCreated(true); $this->logger->debug('FORM: Conflicts found in ' . implode(', ', $conflicts) . ' between current tracked contact and submitted data so assuming a new contact'); } } //check for existing IP address $ipAddress = $this->ipLookupHelper->getIpAddress(); //no lead was found by a mapped email field so create a new one if ($lead->isNewlyCreated()) { if (!$inKioskMode) { $lead->addIpAddress($ipAddress); $this->logger->debug('FORM: Associating ' . $ipAddress->getIpAddress() . ' to contact'); } } elseif (!$inKioskMode) { $leadIpAddresses = $lead->getIpAddresses(); if (!$leadIpAddresses->contains($ipAddress)) { $lead->addIpAddress($ipAddress); $this->logger->debug('FORM: Associating ' . $ipAddress->getIpAddress() . ' to contact'); } } //set the mapped fields $this->leadModel->setFieldValues($lead, $data, false); if (!empty($event)) { $event->setIpAddress($ipAddress); $lead->addPointsChangeLog($event); } // last active time $lead->setLastActive(new \DateTime()); //create a new lead $this->leadModel->saveEntity($lead, false); if (!$inKioskMode) { // Set the current lead which will generate tracking cookies $this->leadModel->setCurrentLead($lead); } else { // Set system current lead which will still allow execution of events without generating tracking cookies $this->leadModel->setSystemCurrentLead($lead); } return $lead; }
/** Add lead to company * @param array|Company $companies * @param array|Lead $lead * @param bool $manuallyAdded * @param bool $batchProcess * @param int $searchCompanyLead 0 = reference, 1 = yes, -1 = known to not exist * @param \DateTime $dateManipulated * * @throws \Doctrine\ORM\ORMException */ public function addLeadToCompany($companies, $lead, $manuallyAdded = false, $searchCompanyLead = 1, $dateManipulated = null) { // Primary company name to be peristed to the lead's contact company field $companyName = ''; if ($dateManipulated == null) { $dateManipulated = new \DateTime(); } if (!$lead instanceof Lead) { $leadId = is_array($lead) && isset($lead['id']) ? $lead['id'] : $lead; $lead = $this->em->getReference('MauticLeadBundle:Lead', $leadId); } else { $leadId = $lead->getId(); } if (!is_array($companies)) { $companies = [$companies]; } /** @var Company[] $companyLeadAdd */ $companyLeadAdd = []; if (!$companies instanceof Company) { //make sure they are ints $searchForCompanies = []; foreach ($companies as $k => &$l) { $l = (int) $l; if (!isset($companyLeadAdd[$l])) { $searchForCompanies[] = $l; } } if (!empty($searchForCompanies)) { $companyEntities = $this->getEntities(['filter' => ['force' => [['column' => 'comp.id', 'expr' => 'in', 'value' => $searchForCompanies]]]]); foreach ($companyEntities as $company) { $companyLeadAdd[$company->getId()] = $company; } } unset($companyEntities, $searchForCompanies); } else { $companyLeadAdd[$companies->getId()] = $companies; $companies = [$companies->getId()]; } $persistCompany = []; $dispatchEvents = []; foreach ($companies as $companyId) { if (!isset($companyLeadAdd[$companyId])) { // List no longer exists in the DB so continue to the next continue; } if ($searchCompanyLead == -1) { $companyLead = null; } elseif ($searchCompanyLead) { $companyLead = $this->getCompanyLeadRepository()->findOneBy(['lead' => $lead, 'company' => $companyLeadAdd[$companyId]]); } else { $companyLead = $this->em->getReference('MauticLeadBundle:CompanyLead', ['lead' => $leadId, 'company' => $companyId]); } if ($companyLead != null) { if ($manuallyAdded && $companyLead->wasManuallyRemoved()) { $companyLead->setManuallyRemoved(false); $companyLead->setManuallyAdded($manuallyAdded); $persistLists[] = $companyLead; $dispatchEvents[] = $companyId; $companyName = $companyLeadAdd[$companyId]->getName(); } else { // Detach from Doctrine $this->em->detach($companyLead); continue; } } else { $companyLead = new CompanyLead(); $companyLead->setCompany($companyLeadAdd[$companyId]); $companyLead->setLead($lead); $companyLead->setManuallyAdded($manuallyAdded); $companyLead->setDateAdded($dateManipulated); $persistCompany[] = $companyLead; $dispatchEvents[] = $companyId; $companyName = $companyLeadAdd[$companyId]->getName(); } } if (!empty($persistCompany)) { $this->leadFieldModel->getRepository()->saveEntities($persistCompany); } // Clear CompanyLead entities from Doctrine memory $this->em->clear('Mautic\\CompanyBundle\\Entity\\CompanyLead'); if (!empty($companyName)) { $currentCompanyName = $lead->getCompany(); if ($currentCompanyName !== $companyName) { $lead->addUpdatedField('company', $companyName); $this->em->getRepository('MauticLeadBundle:Lead')->saveEntity($lead); } } if (!empty($dispatchEvents) && $this->dispatcher->hasListeners(LeadEvents::LEAD_COMPANY_CHANGE)) { foreach ($dispatchEvents as $companyId) { $event = new LeadChangeCompanyEvent($lead, $companyLeadAdd[$companyId]); $this->dispatcher->dispatch(LeadEvents::LEAD_COMPANY_CHANGE, $event); unset($event); } } unset($lead, $persistCompany, $companies); }