/** * @param object $entity * @param \Symfony\Component\Form\FormFactory $formFactory * @param null $action * @param array $options * * @return \Symfony\Component\Form\FormInterface */ public function createForm($entity, $formFactory, $action = null, $options = []) { $fields = $this->leadFieldModel->getFieldListWithProperties(); $choices = []; foreach ($fields as $alias => $field) { if (!isset($choices[$field['group_label']])) { $choices[$field['group_label']] = []; } $choices[$field['group_label']][$alias] = $field['label']; } // Only show the lead fields not already used $usedLeadFields = $this->session->get('mautic.form.' . $entity['formId'] . '.fields.leadfields', []); $testLeadFields = array_flip($usedLeadFields); $currentLeadField = isset($entity['leadField']) ? $entity['leadField'] : null; if (!empty($currentLeadField) && isset($testLeadFields[$currentLeadField])) { unset($testLeadFields[$currentLeadField]); } foreach ($choices as &$group) { $group = array_diff_key($group, $testLeadFields); } $options['leadFields'] = $choices; $options['leadFieldProperties'] = $fields; if ($action) { $options['action'] = $action; } return $formFactory->create('formfield', $entity, $options); }
/** * @param GenerateSchemaEventArgs $args */ public function postGenerateSchema(GenerateSchemaEventArgs $args) { $schema = $args->getSchema(); try { if (!$schema->hasTable(MAUTIC_TABLE_PREFIX . 'lead_fields')) { return; } $objects = ['lead' => 'leads', 'company' => 'companies']; foreach ($objects as $object => $tableName) { $table = $schema->getTable(MAUTIC_TABLE_PREFIX . $tableName); //get a list of fields $fields = $args->getEntityManager()->getConnection()->createQueryBuilder()->select('f.alias, f.is_unique_identifer as is_unique, f.type, f.object')->from(MAUTIC_TABLE_PREFIX . 'lead_fields', 'f')->where("f.object = '{$object}'")->orderBy('f.field_order', 'ASC')->execute()->fetchAll(); // Compile which ones are unique identifiers // Email will always be included first $uniqueFields = 'lead' === $object ? ['email' => 'email'] : ['companyemail' => 'companyemail']; foreach ($fields as $f) { if ($f['is_unique'] && $f['alias'] != 'email') { $uniqueFields[$f['alias']] = $f['alias']; } $columnDef = FieldModel::getSchemaDefinition($f['alias'], $f['type'], !empty($f['is_unique'])); $table->addColumn($columnDef['name'], $columnDef['type'], $columnDef['options']); if ('text' != $columnDef['type']) { $table->addIndex([$columnDef['name']], MAUTIC_TABLE_PREFIX . $f['alias'] . '_search'); } } // Only allow indexes for string types $columns = $table->getColumns(); /** @var \Doctrine\DBAL\Schema\Column $column */ foreach ($columns as $column) { $type = $column->getType(); $name = $column->getName(); if (!$type instanceof StringType) { unset($uniqueFields[$name]); } elseif (isset($uniqueFields[$name])) { $uniqueFields[$name] = $uniqueFields[$name]; } } if (count($uniqueFields) > 1) { // Only use three to prevent max key length errors $uniqueFields = array_slice($uniqueFields, 0, 3); $table->addIndex($uniqueFields, MAUTIC_TABLE_PREFIX . 'unique_identifier_search'); } switch ($object) { case 'lead': $table->addIndex(['attribution', 'attribution_date'], MAUTIC_TABLE_PREFIX . 'contact_attribution'); break; case 'company': $table->addIndex(['companyname', 'companyemail'], MAUTIC_TABLE_PREFIX . 'company_filter'); $table->addIndex(['companyname', 'companycity', 'companycountry', 'companystate'], MAUTIC_TABLE_PREFIX . 'company_match'); break; } } } catch (\Exception $e) { //table doesn't exist or something bad happened so oh well $this->logger->addError('SCHEMA ERROR: ' . $e->getMessage()); } }
/** * @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); }
/** * @param ObjectManager $manager */ public function load(ObjectManager $manager) { $fields = FieldModel::$coreFields; $translator = $this->container->get('translator'); $indexesToAdd = []; /** @var ColumnSchemaHelper $leadsSchema */ $leadsSchema = $this->container->get('mautic.schema.helper.factory')->getSchemaHelper('column', 'leads'); $order = 1; foreach ($fields as $alias => $field) { $type = isset($field['type']) ? $field['type'] : 'text'; $entity = new LeadField(); $entity->setLabel($translator->trans('mautic.lead.field.' . $alias, [], 'fixtures')); $entity->setGroup(isset($field['group']) ? $field['group'] : 'core'); $entity->setOrder($order); $entity->setAlias($alias); $entity->setType($type); $entity->setIsUniqueIdentifer(!empty($field['unique'])); $entity->setProperties(isset($field['properties']) ? $field['properties'] : []); $entity->setIsFixed(!empty($field['fixed'])); $entity->setIsListable(!empty($field['listable'])); $entity->setIsShortVisible(!empty($field['short'])); $manager->persist($entity); $manager->flush(); //add the column to the leads table $leadsSchema->addColumn(FieldModel::getSchemaDefinition($alias, $type, $entity->getIsUniqueIdentifier())); $indexesToAdd[] = $alias; $this->addReference('leadfield-' . $alias, $entity); $order++; } $leadsSchema->executeChanges(); /** @var IndexSchemaHelper $indexHelper */ $indexHelper = $this->container->get('mautic.schema.helper.factory')->getSchemaHelper('index', 'leads'); foreach ($indexesToAdd as $name) { $type = isset($fields[$name]['type']) ? $fields[$name]['type'] : 'text'; if ('textarea' != $type) { $indexHelper->addIndex([$name], MAUTIC_TABLE_PREFIX . $name . '_search'); } } // Add an attribution index $indexHelper->addIndex(['attribution', 'attribution_date'], MAUTIC_TABLE_PREFIX . '_contact_attribution'); $indexHelper->executeChanges(); }
/** * @param ObjectManager $manager */ public function load(ObjectManager $manager) { $fieldGroups['lead'] = FieldModel::$coreFields; $fieldGroups['company'] = FieldModel::$coreCompanyFields; $translator = $this->container->get('translator'); $indexesToAdd = []; foreach ($fieldGroups as $object => $fields) { if ($object == 'company') { /** @var ColumnSchemaHelper $companiesSchema */ $schema = $this->container->get('mautic.schema.helper.factory')->getSchemaHelper('column', 'companies'); } else { /** @var ColumnSchemaHelper $companiesSchema */ $schema = $this->container->get('mautic.schema.helper.factory')->getSchemaHelper('column', 'leads'); } $order = 1; foreach ($fields as $alias => $field) { $type = isset($field['type']) ? $field['type'] : 'text'; $entity = new LeadField(); $entity->setLabel($translator->trans('mautic.lead.field.' . $alias, [], 'fixtures')); $entity->setGroup(isset($field['group']) ? $field['group'] : 'core'); $entity->setOrder($order); $entity->setAlias($alias); $entity->setIsRequired(isset($field['required']) ? $field['required'] : false); $entity->setType($type); $entity->setObject($field['object']); $entity->setIsUniqueIdentifer(!empty($field['unique'])); $entity->setProperties(isset($field['properties']) ? $field['properties'] : []); $entity->setIsFixed(!empty($field['fixed'])); $entity->setIsListable(!empty($field['listable'])); $entity->setIsShortVisible(!empty($field['short'])); $manager->persist($entity); $manager->flush(); $schema->addColumn(FieldModel::getSchemaDefinition($alias, $type, $entity->getIsUniqueIdentifier())); $indexesToAdd[$object][] = $alias; $this->addReference('leadfield-' . $alias, $entity); ++$order; } $schema->executeChanges(); } foreach ($indexesToAdd as $object => $indexes) { if ($object == 'company') { /** @var IndexSchemaHelper $indexHelper */ $indexHelper = $this->container->get('mautic.schema.helper.factory')->getSchemaHelper('index', 'companies'); } else { /** @var IndexSchemaHelper $indexHelper */ $indexHelper = $this->container->get('mautic.schema.helper.factory')->getSchemaHelper('index', 'leads'); } foreach ($indexes as $name) { $type = isset($fields[$name]['type']) ? $fields[$name]['type'] : 'text'; if ('textarea' != $type) { $indexHelper->addIndex([$name], $name . '_search'); } } if ($object == 'lead') { // Add an attribution index $indexHelper->addIndex(['attribution', 'attribution_date'], 'contact_attribution'); } else { $indexHelper->addIndex(['companyname', 'companyemail'], 'company_filter'); $indexHelper->addIndex(['companyname', 'companycity', 'companycountry', 'companystate'], 'company_match'); } $indexHelper->executeChanges(); } }
/** * Create/update lead from form submit. * * @param $form * @param array $leadFieldMatches * * @return Lead */ protected function createLeadFromSubmit($form, array $leadFieldMatches, $leadFields) { //set the mapped data $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 = []; foreach ($leadFields as $alias => $properties) { $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 : [$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 = []; foreach ($potentialConflicts as $field) { if (!empty($fieldSet1[$field]) && !empty($fieldSet2[$field])) { if (strtolower($fieldSet1[$field]) !== strtolower($fieldSet2[$field])) { $conflicts[] = $field; } } } return [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) : []; $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; }
/** * Generate the form's html. * * @param Form $entity * @param bool $persist * * @return string */ public function generateHtml(Form $entity, $persist = true) { //generate cached HTML $theme = $entity->getTemplate(); $submissions = null; $lead = $this->leadModel->getCurrentLead(); $style = ''; if (!empty($theme)) { $theme .= '|'; } if ($entity->usesProgressiveProfiling()) { $submissions = $this->getRepository()->getFormResults($entity, ['leadId' => $lead->getId(), 'limit' => 200]); } if ($entity->getRenderStyle()) { $templating = $this->templatingHelper->getTemplating(); $styleTheme = $theme . 'MauticFormBundle:Builder:style.html.php'; $style = $templating->render($this->themeHelper->checkForTwigTemplate($styleTheme)); } // Determine pages $fields = $entity->getFields()->toArray(); // Ensure the correct order in case this is generated right after a form save with new fields uasort($fields, function ($a, $b) { if ($a->getOrder() === $b->getOrder()) { return 0; } return $a->getOrder() < $b->getOrder() ? -1 : 1; }); $pages = ['open' => [], 'close' => []]; $openFieldId = $closeFieldId = $previousId = $lastPage = false; $pageCount = 1; foreach ($fields as $fieldId => $field) { if ('pagebreak' == $field->getType() && $openFieldId) { // Open the page $pages['open'][$openFieldId] = $pageCount; $openFieldId = false; $lastPage = $fieldId; // Close the page at the next page break if ($previousId) { $pages['close'][$previousId] = $pageCount; ++$pageCount; } } else { if (!$openFieldId) { $openFieldId = $fieldId; } } $previousId = $fieldId; } if (!empty($pages)) { if ($openFieldId) { $pages['open'][$openFieldId] = $pageCount; } if ($previousId !== $lastPage) { $pages['close'][$previousId] = $pageCount; } } $html = $this->templatingHelper->getTemplating()->render($theme . 'MauticFormBundle:Builder:form.html.php', ['fieldSettings' => $this->getCustomComponents()['fields'], 'fields' => $fields, 'contactFields' => $this->leadFieldModel->getFieldListWithProperties(), 'form' => $entity, 'theme' => $theme, 'submissions' => $submissions, 'lead' => $lead, 'formPages' => $pages, 'lastFormPage' => $lastPage, 'style' => $style]); if (!$entity->usesProgressiveProfiling()) { $entity->setCachedHtml($html); if ($persist) { //bypass model function as events aren't needed for this $this->getRepository()->saveEntity($entity); } } return $html; }
/** * @param $fields * @param $data * @param null $owner * @param null $list * @param null $tags * @param bool $persist Persist to the database; otherwise return entity * * @return bool * @throws \Doctrine\ORM\ORMException * @throws \Swift_RfcComplianceException */ public function importLead($fields, $data, $owner = null, $list = null, $tags = null, $persist = true) { // Let's check for an existing lead by email $hasEmail = !empty($fields['email']) && !empty($data[$fields['email']]); if ($hasEmail) { // Validate the email MailHelper::validateEmail($data[$fields['email']]); $leadFound = $this->getRepository()->getLeadByEmail($data[$fields['email']]); $lead = $leadFound ? $this->em->getReference('MauticLeadBundle:Lead', $leadFound['id']) : new Lead(); $merged = $leadFound; } else { $lead = new Lead(); $merged = false; } if (!empty($fields['dateAdded']) && !empty($data[$fields['dateAdded']])) { $dateAdded = new DateTimeHelper($data[$fields['dateAdded']]); $lead->setDateAdded($dateAdded->getUtcDateTime()); } unset($fields['dateAdded']); if (!empty($fields['dateModified']) && !empty($data[$fields['dateModified']])) { $dateModified = new DateTimeHelper($data[$fields['dateModified']]); $lead->setDateModified($dateModified->getUtcDateTime()); } unset($fields['dateModified']); if (!empty($fields['lastActive']) && !empty($data[$fields['lastActive']])) { $lastActive = new DateTimeHelper($data[$fields['lastActive']]); $lead->setLastActive($lastActive->getUtcDateTime()); } unset($fields['lastActive']); if (!empty($fields['dateIdentified']) && !empty($data[$fields['dateIdentified']])) { $dateIdentified = new DateTimeHelper($data[$fields['dateIdentified']]); $lead->setDateIdentified($dateIdentified->getUtcDateTime()); } unset($fields['dateIdentified']); if (!empty($fields['createdByUser']) && !empty($data[$fields['createdByUser']])) { $userRepo = $this->em->getRepository('MauticUserBundle:User'); $createdByUser = $userRepo->findByIdentifier($data[$fields['createdByUser']]); if ($createdByUser !== null) { $lead->setCreatedBy($createdByUser); } } unset($fields['createdByUser']); if (!empty($fields['modifiedByUser']) && !empty($data[$fields['modifiedByUser']])) { $userRepo = $this->em->getRepository('MauticUserBundle:User'); $modifiedByUser = $userRepo->findByIdentifier($data[$fields['modifiedByUser']]); if ($modifiedByUser !== null) { $lead->setModifiedBy($modifiedByUser); } } unset($fields['modifiedByUser']); if (!empty($fields['ip']) && !empty($data[$fields['ip']])) { $addresses = explode(',', $data[$fields['ip']]); foreach ($addresses as $address) { $ipAddress = new IpAddress(); $ipAddress->setIpAddress(trim($address)); $lead->addIpAddress($ipAddress); } } unset($fields['ip']); if (!empty($fields['points']) && !empty($data[$fields['points']]) && $lead->getId() === null) { // Add points only for new leads $lead->setPoints($data[$fields['points']]); //add a lead point change log $log = new PointsChangeLog(); $log->setDelta($data[$fields['points']]); $log->setLead($lead); $log->setType('lead'); $log->setEventName($this->translator->trans('mautic.lead.import.event.name')); $log->setActionName($this->translator->trans('mautic.lead.import.action.name', array('%name%' => $this->user->getUsername()))); $log->setIpAddress($this->ipLookupHelper->getIpAddress()); $log->setDateAdded(new \DateTime()); $lead->addPointsChangeLog($log); } if (!empty($fields['stage']) && !empty($data[$fields['stage']])) { static $stages = []; $stageName = $data[$fields['stage']]; if (!array_key_exists($stageName, $stages)) { // Set stage for contact $stage = $this->em->getRepository('MauticStageBundle:Stage')->getStageByName($stageName); if (empty($stage)) { $stage = new Stage(); $stage->setName($stageName); $stages[$stageName] = $stage; } } else { $stage = $stages[$stageName]; } $lead->setStage($stage); //add a contact stage change log $log = new StagesChangeLog(); $log->setEventName($stage->getId() . ":" . $stage->getName()); $log->setLead($lead); $log->setActionName($this->translator->trans('mautic.lead.import.action.name', ['%name%' => $this->user->getUsername()])); $log->setDateAdded(new \DateTime()); $lead->stageChangeLog($log); } unset($fields['stage']); // Set unsubscribe status if (!empty($fields['doNotEmail']) && !empty($data[$fields['doNotEmail']]) && $hasEmail) { $doNotEmail = filter_var($data[$fields['doNotEmail']], FILTER_VALIDATE_BOOLEAN); if ($doNotEmail) { $reason = $this->translator->trans('mautic.lead.import.by.user', array("%user%" => $this->user->getUsername())); // The email must be set for successful unsubscribtion $lead->addUpdatedField('email', $data[$fields['email']]); $this->addDncForLead($lead, 'email', $reason, DoNotContact::MANUAL); } } unset($fields['doNotEmail']); if ($owner !== null) { $lead->setOwner($this->em->getReference('MauticUserBundle:User', $owner)); } if ($tags !== null) { $this->modifyTags($lead, $tags, null, false); } // Set profile data using the form so that values are validated $fieldData = []; foreach ($fields as $leadField => $importField) { // Prevent overwriting existing data with empty data if (array_key_exists($importField, $data) && !is_null($data[$importField]) && $data[$importField] != '') { $fieldData[$leadField] = $data[$importField]; } } static $leadFields; if (null === $leadFields) { $leadFields = $this->leadFieldModel->getEntities(array('force' => array(array('column' => 'f.isPublished', 'expr' => 'eq', 'value' => true)), 'hydration_mode' => 'HYDRATE_ARRAY')); } $form = $this->createForm($lead, $this->formFactory, null, ['fields' => $leadFields, 'csrf_protection' => false]); // Unset stage and owner from the form because it's already been handled unset($form['stage'], $form['owner']); $form->submit($fieldData); if (!$form->isValid()) { $fieldErrors = []; foreach ($form as $formField) { $errors = $formField->getErrors(true); if (count($errors)) { $errorString = $formField->getConfig()->getOption('label') . ": "; foreach ($errors as $error) { $errorString .= " {$error->getMessage()}"; } $fieldErrors[] = $errorString; } } $fieldErrors = implode("\n", $fieldErrors); throw new \Exception($fieldErrors); } else { // All clear foreach ($fieldData as $field => $value) { $lead->addUpdatedField($field, $value); } } $lead->imported = true; if ($persist) { $this->saveEntity($lead); if ($list !== null) { $this->addToLists($lead, array($list)); } } return $merged; }
/** * Get lead fields used in selects/matching */ public function getLeadFields() { return $this->leadFieldModel->getFieldList(); }
/** 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); }