1 | <?php |
||||||
2 | |||||||
3 | /* |
||||||
4 | * @copyright 2014 Mautic Contributors. All rights reserved |
||||||
5 | * @author Mautic |
||||||
6 | * |
||||||
7 | * @link http://mautic.org |
||||||
8 | * |
||||||
9 | * @license GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html |
||||||
10 | */ |
||||||
11 | |||||||
12 | namespace Mautic\LeadBundle\Model; |
||||||
13 | |||||||
14 | use Doctrine\DBAL\Query\Expression\ExpressionBuilder; |
||||||
15 | use Mautic\CoreBundle\Form\RequestTrait; |
||||||
16 | use Mautic\CoreBundle\Helper\DateTimeHelper; |
||||||
17 | use Mautic\CoreBundle\Helper\InputHelper; |
||||||
18 | use Mautic\CoreBundle\Model\AjaxLookupModelInterface; |
||||||
19 | use Mautic\CoreBundle\Model\FormModel as CommonFormModel; |
||||||
20 | use Mautic\EmailBundle\Helper\EmailValidator; |
||||||
21 | use Mautic\LeadBundle\Entity\Company; |
||||||
22 | use Mautic\LeadBundle\Entity\CompanyLead; |
||||||
23 | use Mautic\LeadBundle\Entity\Lead; |
||||||
24 | use Mautic\LeadBundle\Entity\LeadEventLog; |
||||||
25 | use Mautic\LeadBundle\Entity\LeadField; |
||||||
26 | use Mautic\LeadBundle\Event\CompanyEvent; |
||||||
27 | use Mautic\LeadBundle\Event\LeadChangeCompanyEvent; |
||||||
28 | use Mautic\LeadBundle\Form\Type\CompanyType; |
||||||
29 | use Mautic\LeadBundle\LeadEvents; |
||||||
30 | use Symfony\Component\EventDispatcher\Event; |
||||||
31 | use Symfony\Component\HttpFoundation\Session\Session; |
||||||
32 | use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException; |
||||||
33 | |||||||
34 | /** |
||||||
35 | * Class CompanyModel. |
||||||
36 | */ |
||||||
37 | class CompanyModel extends CommonFormModel implements AjaxLookupModelInterface |
||||||
38 | { |
||||||
39 | use DefaultValueTrait; |
||||||
40 | use RequestTrait; |
||||||
41 | |||||||
42 | /** |
||||||
43 | * @var Session |
||||||
44 | */ |
||||||
45 | protected $session; |
||||||
46 | |||||||
47 | /** |
||||||
48 | * @var FieldModel |
||||||
49 | */ |
||||||
50 | protected $leadFieldModel; |
||||||
51 | |||||||
52 | /** |
||||||
53 | * @var array |
||||||
54 | */ |
||||||
55 | protected $companyFields; |
||||||
56 | |||||||
57 | /** |
||||||
58 | * @var EmailValidator |
||||||
59 | */ |
||||||
60 | protected $emailValidator; |
||||||
61 | |||||||
62 | /** |
||||||
63 | * @var array |
||||||
64 | */ |
||||||
65 | private $fields = []; |
||||||
66 | |||||||
67 | /** |
||||||
68 | * CompanyModel constructor. |
||||||
69 | */ |
||||||
70 | public function __construct(FieldModel $leadFieldModel, Session $session, EmailValidator $validator) |
||||||
71 | { |
||||||
72 | $this->leadFieldModel = $leadFieldModel; |
||||||
73 | $this->session = $session; |
||||||
74 | $this->emailValidator = $validator; |
||||||
75 | } |
||||||
76 | |||||||
77 | /** |
||||||
78 | * @param Company $entity |
||||||
79 | * @param bool $unlock |
||||||
80 | */ |
||||||
81 | public function saveEntity($entity, $unlock = true) |
||||||
82 | { |
||||||
83 | // Update leads primary company name |
||||||
84 | $this->setEntityDefaultValues($entity, 'company'); |
||||||
85 | $this->getCompanyLeadRepository()->updateLeadsPrimaryCompanyName($entity); |
||||||
86 | |||||||
87 | parent::saveEntity($entity, $unlock); |
||||||
88 | } |
||||||
89 | |||||||
90 | /** |
||||||
91 | * Save an array of entities. |
||||||
92 | * |
||||||
93 | * @param array $entities |
||||||
94 | * @param bool $unlock |
||||||
95 | * |
||||||
96 | * @return array |
||||||
97 | */ |
||||||
98 | public function saveEntities($entities, $unlock = true) |
||||||
99 | { |
||||||
100 | // Update leads primary company name |
||||||
101 | foreach ($entities as $entity) { |
||||||
102 | $this->setEntityDefaultValues($entity, 'company'); |
||||||
103 | $this->getCompanyLeadRepository()->updateLeadsPrimaryCompanyName($entity); |
||||||
104 | } |
||||||
105 | parent::saveEntities($entities, $unlock); |
||||||
106 | } |
||||||
107 | |||||||
108 | /** |
||||||
109 | * {@inheritdoc} |
||||||
110 | * |
||||||
111 | * @return \Mautic\LeadBundle\Entity\CompanyRepository |
||||||
112 | */ |
||||||
113 | public function getRepository() |
||||||
114 | { |
||||||
115 | return $this->em->getRepository('MauticLeadBundle:Company'); |
||||||
116 | } |
||||||
117 | |||||||
118 | /** |
||||||
119 | * {@inheritdoc} |
||||||
120 | * |
||||||
121 | * @return \Mautic\LeadBundle\Entity\CompanyLeadRepository |
||||||
122 | */ |
||||||
123 | public function getCompanyLeadRepository() |
||||||
124 | { |
||||||
125 | return $this->em->getRepository('MauticLeadBundle:CompanyLead'); |
||||||
126 | } |
||||||
127 | |||||||
128 | /** |
||||||
129 | * {@inheritdoc} |
||||||
130 | */ |
||||||
131 | public function getPermissionBase() |
||||||
132 | { |
||||||
133 | // We are using lead:leads in the CompanyController so this should match to prevent a BC break |
||||||
134 | return 'lead:leads'; |
||||||
135 | } |
||||||
136 | |||||||
137 | /** |
||||||
138 | * {@inheritdoc} |
||||||
139 | * |
||||||
140 | * @return string |
||||||
141 | */ |
||||||
142 | public function getNameGetter() |
||||||
143 | { |
||||||
144 | return 'getPrimaryIdentifier'; |
||||||
145 | } |
||||||
146 | |||||||
147 | /** |
||||||
148 | * {@inheritdoc} |
||||||
149 | * |
||||||
150 | * @throws MethodNotAllowedHttpException |
||||||
151 | */ |
||||||
152 | public function createForm($entity, $formFactory, $action = null, $options = []) |
||||||
153 | { |
||||||
154 | if (!$entity instanceof Company) { |
||||||
155 | throw new MethodNotAllowedHttpException(['Company']); |
||||||
156 | } |
||||||
157 | if (!empty($action)) { |
||||||
158 | $options['action'] = $action; |
||||||
159 | } |
||||||
160 | |||||||
161 | return $formFactory->create(CompanyType::class, $entity, $options); |
||||||
162 | } |
||||||
163 | |||||||
164 | /** |
||||||
165 | * {@inheritdoc} |
||||||
166 | * |
||||||
167 | * @return Company|null |
||||||
168 | */ |
||||||
169 | public function getEntity($id = null) |
||||||
170 | { |
||||||
171 | if (null === $id) { |
||||||
172 | return new Company(); |
||||||
173 | } |
||||||
174 | |||||||
175 | return parent::getEntity($id); |
||||||
176 | } |
||||||
177 | |||||||
178 | /** |
||||||
179 | * @return mixed |
||||||
180 | */ |
||||||
181 | public function getUserCompanies() |
||||||
182 | { |
||||||
183 | $user = (!$this->security->isGranted('lead:leads:viewother')) ? |
||||||
184 | $this->userHelper->getUser() : false; |
||||||
185 | |||||||
186 | return $this->em->getRepository('MauticLeadBundle:Company')->getCompanies($user); |
||||||
187 | } |
||||||
188 | |||||||
189 | /** |
||||||
190 | * Reorganizes a field list to be keyed by field's group then alias. |
||||||
191 | * |
||||||
192 | * @param $fields |
||||||
193 | * |
||||||
194 | * @return array |
||||||
195 | */ |
||||||
196 | public function organizeFieldsByGroup($fields) |
||||||
197 | { |
||||||
198 | $array = []; |
||||||
199 | |||||||
200 | foreach ($fields as $field) { |
||||||
201 | if ($field instanceof LeadField) { |
||||||
202 | $alias = $field->getAlias(); |
||||||
203 | if ('company' === $field->getObject()) { |
||||||
204 | $group = $field->getGroup(); |
||||||
205 | $array[$group][$alias]['id'] = $field->getId(); |
||||||
206 | $array[$group][$alias]['group'] = $group; |
||||||
207 | $array[$group][$alias]['label'] = $field->getLabel(); |
||||||
208 | $array[$group][$alias]['alias'] = $alias; |
||||||
209 | $array[$group][$alias]['type'] = $field->getType(); |
||||||
210 | } |
||||||
211 | } else { |
||||||
212 | $alias = $field['alias']; |
||||||
213 | $field[] = $alias; |
||||||
214 | if ('company' === $field['object']) { |
||||||
215 | $group = $field['group']; |
||||||
216 | $array[$group][$alias]['id'] = $field['id']; |
||||||
217 | $array[$group][$alias]['group'] = $group; |
||||||
218 | $array[$group][$alias]['label'] = $field['label']; |
||||||
219 | $array[$group][$alias]['alias'] = $alias; |
||||||
220 | $array[$group][$alias]['type'] = $field['type']; |
||||||
221 | } |
||||||
222 | } |
||||||
223 | } |
||||||
224 | |||||||
225 | //make sure each group key is present |
||||||
226 | $groups = ['core', 'social', 'personal', 'professional']; |
||||||
227 | foreach ($groups as $g) { |
||||||
228 | if (!isset($array[$g])) { |
||||||
229 | $array[$g] = []; |
||||||
230 | } |
||||||
231 | } |
||||||
232 | |||||||
233 | return $array; |
||||||
234 | } |
||||||
235 | |||||||
236 | /** |
||||||
237 | * Populates custom field values for updating the company. |
||||||
238 | * |
||||||
239 | * @param bool|false $overwriteWithBlank |
||||||
240 | */ |
||||||
241 | public function setFieldValues(Company $company, array $data, $overwriteWithBlank = false) |
||||||
242 | { |
||||||
243 | //save the field values |
||||||
244 | $fieldValues = $company->getFields(); |
||||||
245 | |||||||
246 | if (empty($fieldValues)) { |
||||||
247 | // Lead is new or they haven't been populated so let's build the fields now |
||||||
248 | if (empty($this->fields)) { |
||||||
249 | $this->fields = $this->leadFieldModel->getEntities( |
||||||
250 | [ |
||||||
251 | 'filter' => ['object' => 'company'], |
||||||
252 | 'hydration_mode' => 'HYDRATE_ARRAY', |
||||||
253 | ] |
||||||
254 | ); |
||||||
255 | $this->fields = $this->organizeFieldsByGroup($this->fields); |
||||||
256 | } |
||||||
257 | $fieldValues = $this->fields; |
||||||
258 | } |
||||||
259 | |||||||
260 | //update existing values |
||||||
261 | foreach ($fieldValues as &$groupFields) { |
||||||
262 | foreach ($groupFields as $alias => &$field) { |
||||||
263 | if (!isset($field['value'])) { |
||||||
264 | $field['value'] = null; |
||||||
265 | } |
||||||
266 | // Only update fields that are part of the passed $data array |
||||||
267 | if (array_key_exists($alias, $data)) { |
||||||
268 | $curValue = $field['value']; |
||||||
269 | $newValue = $data[$alias]; |
||||||
270 | |||||||
271 | if (is_array($newValue)) { |
||||||
272 | $newValue = implode('|', $newValue); |
||||||
273 | } |
||||||
274 | |||||||
275 | if ($curValue !== $newValue && (strlen($newValue) > 0 || (0 === strlen($newValue) && $overwriteWithBlank))) { |
||||||
276 | $field['value'] = $newValue; |
||||||
277 | $company->addUpdatedField($alias, $newValue, $curValue); |
||||||
278 | } |
||||||
279 | } |
||||||
280 | } |
||||||
281 | } |
||||||
282 | $company->setFields($fieldValues); |
||||||
283 | } |
||||||
284 | |||||||
285 | /** |
||||||
286 | * Add lead to company. |
||||||
287 | * |
||||||
288 | * @param array|Company $companies |
||||||
289 | * @param array|Lead $lead |
||||||
290 | * |
||||||
291 | * @return bool |
||||||
292 | * |
||||||
293 | * @throws \Doctrine\ORM\ORMException |
||||||
294 | */ |
||||||
295 | public function addLeadToCompany($companies, $lead) |
||||||
296 | { |
||||||
297 | // Primary company name to be persisted to the lead's contact company field |
||||||
298 | $companyName = ''; |
||||||
299 | $companyLeadAdd = []; |
||||||
300 | $searchForCompanies = []; |
||||||
301 | |||||||
302 | $dateManipulated = new \DateTime(); |
||||||
303 | |||||||
304 | if (!$lead instanceof Lead) { |
||||||
305 | $leadId = (is_array($lead) && isset($lead['id'])) ? $lead['id'] : $lead; |
||||||
306 | $lead = $this->em->getReference('MauticLeadBundle:Lead', $leadId); |
||||||
307 | } |
||||||
308 | |||||||
309 | if ($companies instanceof Company) { |
||||||
310 | $companyLeadAdd[$companies->getId()] = $companies; |
||||||
311 | $companies = [$companies->getId()]; |
||||||
312 | } elseif (!is_array($companies)) { |
||||||
313 | $companies = [$companies]; |
||||||
314 | } |
||||||
315 | |||||||
316 | //make sure they are ints |
||||||
317 | foreach ($companies as &$l) { |
||||||
318 | $l = (int) $l; |
||||||
319 | |||||||
320 | if (!isset($companyLeadAdd[$l])) { |
||||||
321 | $searchForCompanies[] = $l; |
||||||
322 | } |
||||||
323 | } |
||||||
324 | |||||||
325 | if (!empty($searchForCompanies)) { |
||||||
326 | $companyEntities = $this->getEntities([ |
||||||
327 | 'filter' => [ |
||||||
328 | 'force' => [ |
||||||
329 | [ |
||||||
330 | 'column' => 'comp.id', |
||||||
331 | 'expr' => 'in', |
||||||
332 | 'value' => $searchForCompanies, |
||||||
333 | ], |
||||||
334 | ], |
||||||
335 | ], |
||||||
336 | ]); |
||||||
337 | |||||||
338 | foreach ($companyEntities as $company) { |
||||||
339 | $companyLeadAdd[$company->getId()] = $company; |
||||||
340 | } |
||||||
341 | } |
||||||
342 | |||||||
343 | unset($companyEntities, $searchForCompanies); |
||||||
344 | |||||||
345 | $persistCompany = []; |
||||||
346 | $dispatchEvents = []; |
||||||
347 | $contactAdded = false; |
||||||
348 | foreach ($companies as $companyId) { |
||||||
349 | if (!isset($companyLeadAdd[$companyId])) { |
||||||
350 | // List no longer exists in the DB so continue to the next |
||||||
351 | continue; |
||||||
352 | } |
||||||
353 | |||||||
354 | $companyLead = $this->getCompanyLeadRepository()->findOneBy( |
||||||
355 | [ |
||||||
356 | 'lead' => $lead, |
||||||
357 | 'company' => $companyLeadAdd[$companyId], |
||||||
358 | ] |
||||||
359 | ); |
||||||
360 | |||||||
361 | if (null != $companyLead) { |
||||||
362 | // Detach from Doctrine |
||||||
363 | $this->em->detach($companyLead); |
||||||
364 | |||||||
365 | continue; |
||||||
366 | } else { |
||||||
367 | $companyLead = new CompanyLead(); |
||||||
368 | $companyLead->setCompany($companyLeadAdd[$companyId]); |
||||||
369 | $companyLead->setLead($lead); |
||||||
370 | $companyLead->setDateAdded($dateManipulated); |
||||||
371 | $contactAdded = true; |
||||||
372 | $persistCompany[] = $companyLead; |
||||||
373 | $dispatchEvents[] = $companyId; |
||||||
374 | $companyName = $companyLeadAdd[$companyId]->getName(); |
||||||
375 | } |
||||||
376 | } |
||||||
377 | |||||||
378 | if (!empty($persistCompany)) { |
||||||
379 | $this->getCompanyLeadRepository()->saveEntities($persistCompany); |
||||||
380 | } |
||||||
381 | |||||||
382 | if (!empty($companyName)) { |
||||||
383 | $currentCompanyName = $lead->getCompany(); |
||||||
384 | if ($currentCompanyName !== $companyName) { |
||||||
385 | $lead->addUpdatedField('company', $companyName) |
||||||
386 | ->setDateModified(new \DateTime()); |
||||||
387 | $this->em->getRepository('MauticLeadBundle:Lead')->saveEntity($lead); |
||||||
388 | } |
||||||
389 | } |
||||||
390 | |||||||
391 | if (!empty($dispatchEvents) && ($this->dispatcher->hasListeners(LeadEvents::LEAD_COMPANY_CHANGE))) { |
||||||
392 | foreach ($dispatchEvents as $companyId) { |
||||||
393 | $event = new LeadChangeCompanyEvent($lead, $companyLeadAdd[$companyId]); |
||||||
394 | $this->dispatcher->dispatch(LeadEvents::LEAD_COMPANY_CHANGE, $event); |
||||||
395 | |||||||
396 | unset($event); |
||||||
397 | } |
||||||
398 | } |
||||||
399 | |||||||
400 | // Clear CompanyLead entities from Doctrine memory |
||||||
401 | $this->em->clear(CompanyLead::class); |
||||||
402 | |||||||
403 | return $contactAdded; |
||||||
404 | } |
||||||
405 | |||||||
406 | /** |
||||||
407 | * Remove a lead from company. |
||||||
408 | * |
||||||
409 | * @param $companies |
||||||
410 | * @param $lead |
||||||
411 | * |
||||||
412 | * @throws \Doctrine\ORM\ORMException |
||||||
413 | */ |
||||||
414 | public function removeLeadFromCompany($companies, $lead) |
||||||
415 | { |
||||||
416 | if (!$lead instanceof Lead) { |
||||||
417 | $leadId = (is_array($lead) && isset($lead['id'])) ? $lead['id'] : $lead; |
||||||
418 | $lead = $this->em->getReference('MauticLeadBundle:Lead', $leadId); |
||||||
419 | } |
||||||
420 | |||||||
421 | $companyLeadRemove = []; |
||||||
422 | if (!$companies instanceof Company) { |
||||||
423 | //make sure they are ints |
||||||
424 | $searchForCompanies = []; |
||||||
425 | foreach ($companies as &$l) { |
||||||
426 | $l = (int) $l; |
||||||
427 | if (!isset($companyLeadRemove[$l])) { |
||||||
428 | $searchForCompanies[] = $l; |
||||||
429 | } |
||||||
430 | } |
||||||
431 | if (!empty($searchForCompanies)) { |
||||||
432 | $companyEntities = $this->getEntities( |
||||||
433 | [ |
||||||
434 | 'filter' => [ |
||||||
435 | 'force' => [ |
||||||
436 | [ |
||||||
437 | 'column' => 'comp.id', |
||||||
438 | 'expr' => 'in', |
||||||
439 | 'value' => $searchForCompanies, |
||||||
440 | ], |
||||||
441 | ], |
||||||
442 | ], |
||||||
443 | ] |
||||||
444 | ); |
||||||
445 | |||||||
446 | foreach ($companyEntities as $company) { |
||||||
447 | $companyLeadRemove[$company->getId()] = $company; |
||||||
448 | } |
||||||
449 | } |
||||||
450 | |||||||
451 | unset($companyEntities, $searchForCompanies); |
||||||
452 | } else { |
||||||
453 | $companyLeadRemove[$companies->getId()] = $companies; |
||||||
454 | |||||||
455 | $companies = [$companies->getId()]; |
||||||
456 | } |
||||||
457 | |||||||
458 | if (!is_array($companies)) { |
||||||
459 | $companies = [$companies]; |
||||||
460 | } |
||||||
461 | |||||||
462 | $deleteCompany = []; |
||||||
463 | $dispatchEvents = []; |
||||||
464 | |||||||
465 | foreach ($companies as $companyId) { |
||||||
466 | if (!isset($companyLeadRemove[$companyId])) { |
||||||
467 | continue; |
||||||
468 | } |
||||||
469 | |||||||
470 | $companyLead = $this->getCompanyLeadRepository()->findOneBy( |
||||||
471 | [ |
||||||
472 | 'lead' => $lead, |
||||||
473 | 'company' => $companyLeadRemove[$companyId], |
||||||
474 | ] |
||||||
475 | ); |
||||||
476 | |||||||
477 | if (null == $companyLead) { |
||||||
478 | // Lead is not part of this list |
||||||
479 | continue; |
||||||
480 | } |
||||||
481 | |||||||
482 | //lead was manually added and now manually removed or was not manually added and now being removed |
||||||
483 | $deleteCompanyLead[] = $companyLead; |
||||||
484 | $dispatchEvents[] = $companyId; |
||||||
485 | |||||||
486 | unset($companyLead); |
||||||
487 | } |
||||||
488 | |||||||
489 | if (!empty($deleteCompanyLead)) { |
||||||
490 | $this->getCompanyLeadRepository()->deleteEntities($deleteCompanyLead); |
||||||
491 | } |
||||||
492 | |||||||
493 | // Clear CompanyLead entities from Doctrine memory |
||||||
494 | $this->em->clear(CompanyLead::class); |
||||||
495 | |||||||
496 | if (!empty($dispatchEvents) && ($this->dispatcher->hasListeners(LeadEvents::LEAD_COMPANY_CHANGE))) { |
||||||
497 | foreach ($dispatchEvents as $listId) { |
||||||
498 | $event = new LeadChangeCompanyEvent($lead, $companyLeadRemove[$listId], false); |
||||||
499 | $this->dispatcher->dispatch(LeadEvents::LEAD_COMPANY_CHANGE, $event); |
||||||
500 | |||||||
501 | unset($event); |
||||||
502 | } |
||||||
503 | } |
||||||
504 | |||||||
505 | unset($lead, $deleteCompany, $companies); |
||||||
506 | } |
||||||
507 | |||||||
508 | /** |
||||||
509 | * Get list of entities for autopopulate fields. |
||||||
510 | * |
||||||
511 | * @param $type |
||||||
512 | * @param $filter |
||||||
513 | * @param $limit |
||||||
514 | * @param $start |
||||||
515 | * |
||||||
516 | * @return array |
||||||
517 | */ |
||||||
518 | public function getLookupResults($type, $filter = '', $limit = 10, $start = 0) |
||||||
519 | { |
||||||
520 | $results = []; |
||||||
521 | switch ($type) { |
||||||
522 | case 'companyfield': |
||||||
523 | case 'lead.company': |
||||||
524 | if ('lead.company' === $type) { |
||||||
525 | $column = 'companyname'; |
||||||
526 | $filterVal = $filter; |
||||||
527 | } else { |
||||||
528 | if (is_array($filter)) { |
||||||
529 | $column = $filter[0]; |
||||||
530 | $filterVal = $filter[1]; |
||||||
531 | } else { |
||||||
532 | $column = $filter; |
||||||
533 | } |
||||||
534 | } |
||||||
535 | |||||||
536 | $expr = new ExpressionBuilder($this->em->getConnection()); |
||||||
537 | $composite = $expr->andX(); |
||||||
538 | $composite->add( |
||||||
539 | $expr->like("comp.$column", ':filterVar') |
||||||
540 | ); |
||||||
541 | |||||||
542 | // Validate owner permissions |
||||||
543 | if (!$this->security->isGranted('lead:leads:viewother')) { |
||||||
544 | $composite->add( |
||||||
545 | $expr->orX( |
||||||
546 | $expr->andX( |
||||||
547 | $expr->isNull('comp.owner_id'), |
||||||
548 | $expr->eq('comp.created_by', (int) $this->userHelper->getUser()->getId()) |
||||||
549 | ), |
||||||
550 | $expr->eq('comp.owner_id', (int) $this->userHelper->getUser()->getId()) |
||||||
551 | ) |
||||||
552 | ); |
||||||
553 | } |
||||||
554 | |||||||
555 | $results = $this->getRepository()->getAjaxSimpleList($composite, ['filterVar' => $filterVal.'%'], $column); |
||||||
556 | |||||||
557 | break; |
||||||
558 | } |
||||||
559 | |||||||
560 | return $results; |
||||||
561 | } |
||||||
562 | |||||||
563 | /** |
||||||
564 | * {@inheritdoc} |
||||||
565 | * |
||||||
566 | * @param $action |
||||||
567 | * @param $event |
||||||
568 | * @param $entity |
||||||
569 | * @param $isNew |
||||||
570 | * |
||||||
571 | * @throws \Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException |
||||||
572 | */ |
||||||
573 | protected function dispatchEvent($action, &$entity, $isNew = false, Event $event = null) |
||||||
574 | { |
||||||
575 | if (!$entity instanceof Company) { |
||||||
576 | throw new MethodNotAllowedHttpException(['Email']); |
||||||
577 | } |
||||||
578 | |||||||
579 | switch ($action) { |
||||||
580 | case 'pre_save': |
||||||
581 | $name = LeadEvents::COMPANY_PRE_SAVE; |
||||||
582 | break; |
||||||
583 | case 'post_save': |
||||||
584 | $name = LeadEvents::COMPANY_POST_SAVE; |
||||||
585 | break; |
||||||
586 | case 'pre_delete': |
||||||
587 | $name = LeadEvents::COMPANY_PRE_DELETE; |
||||||
588 | break; |
||||||
589 | case 'post_delete': |
||||||
590 | $name = LeadEvents::COMPANY_POST_DELETE; |
||||||
591 | break; |
||||||
592 | default: |
||||||
593 | return null; |
||||||
594 | } |
||||||
595 | |||||||
596 | if ($this->dispatcher->hasListeners($name)) { |
||||||
597 | if (empty($event)) { |
||||||
598 | $event = new CompanyEvent($entity, $isNew); |
||||||
599 | $event->setEntityManager($this->em); |
||||||
600 | } |
||||||
601 | |||||||
602 | $this->dispatcher->dispatch($name, $event); |
||||||
603 | |||||||
604 | return $event; |
||||||
605 | } else { |
||||||
606 | return null; |
||||||
607 | } |
||||||
608 | } |
||||||
609 | |||||||
610 | /** |
||||||
611 | * Company Merge function, will merge $mainCompany with $secCompany - empty records from main company will be |
||||||
612 | * filled with secondary then secondary will be deleted. |
||||||
613 | * |
||||||
614 | * @param $mainCompany |
||||||
615 | * @param $secCompany |
||||||
616 | * |
||||||
617 | * @return mixed |
||||||
618 | */ |
||||||
619 | public function companyMerge($mainCompany, $secCompany) |
||||||
620 | { |
||||||
621 | $this->logger->debug('COMPANY: Merging companies'); |
||||||
622 | |||||||
623 | $mainCompanyId = $mainCompany->getId(); |
||||||
624 | $secCompanyId = $secCompany->getId(); |
||||||
625 | |||||||
626 | //if they are the same lead, then just return one |
||||||
627 | if ($mainCompanyId === $secCompanyId) { |
||||||
628 | return $mainCompany; |
||||||
629 | } |
||||||
630 | //merge fields |
||||||
631 | $mergeSecFields = $secCompany->getFields(); |
||||||
632 | $mainCompanyFields = $mainCompany->getFields(); |
||||||
633 | foreach ($mergeSecFields as $group => $groupFields) { |
||||||
634 | foreach ($groupFields as $alias => $details) { |
||||||
635 | //fill in empty main company fields with secondary company fields |
||||||
636 | if (empty($mainCompanyFields[$group][$alias]['value']) && !empty($details['value'])) { |
||||||
637 | $mainCompany->addUpdatedField($alias, $details['value']); |
||||||
638 | $this->logger->debug('Company: Updated '.$alias.' = '.$details['value']); |
||||||
639 | } |
||||||
640 | } |
||||||
641 | } |
||||||
642 | |||||||
643 | //merge owner |
||||||
644 | $mainCompanyOwner = $mainCompany->getOwner(); |
||||||
645 | $secCompanyOwner = $secCompany->getOwner(); |
||||||
646 | |||||||
647 | if (null === $mainCompanyOwner && null !== $secCompanyOwner) { |
||||||
648 | $mainCompany->setOwner($secCompanyOwner); |
||||||
649 | } |
||||||
650 | |||||||
651 | //move all leads from secondary company to main company |
||||||
652 | $companyLeadRepo = $this->getCompanyLeadRepository(); |
||||||
653 | $secCompanyLeads = $companyLeadRepo->getCompanyLeads($secCompanyId); |
||||||
654 | |||||||
655 | foreach ($secCompanyLeads as $lead) { |
||||||
656 | $this->addLeadToCompany($mainCompany->getId(), $lead['lead_id']); |
||||||
657 | } |
||||||
658 | //save the updated company |
||||||
659 | $this->saveEntity($mainCompany, false); |
||||||
660 | |||||||
661 | //delete the old company |
||||||
662 | $this->deleteEntity($secCompany); |
||||||
663 | |||||||
664 | //return the merged company |
||||||
665 | return $mainCompany; |
||||||
666 | } |
||||||
667 | |||||||
668 | /** |
||||||
669 | * @return array |
||||||
670 | */ |
||||||
671 | public function fetchCompanyFields() |
||||||
672 | { |
||||||
673 | if (empty($this->companyFields)) { |
||||||
674 | $this->companyFields = $this->leadFieldModel->getEntities( |
||||||
675 | [ |
||||||
676 | 'filter' => [ |
||||||
677 | 'force' => [ |
||||||
678 | [ |
||||||
679 | 'column' => 'f.isPublished', |
||||||
680 | 'expr' => 'eq', |
||||||
681 | 'value' => true, |
||||||
682 | ], |
||||||
683 | [ |
||||||
684 | 'column' => 'f.object', |
||||||
685 | 'expr' => 'eq', |
||||||
686 | 'value' => 'company', |
||||||
687 | ], |
||||||
688 | ], |
||||||
689 | ], |
||||||
690 | 'hydration_mode' => 'HYDRATE_ARRAY', |
||||||
691 | ] |
||||||
692 | ); |
||||||
693 | } |
||||||
694 | |||||||
695 | return $this->companyFields; |
||||||
696 | } |
||||||
697 | |||||||
698 | /** |
||||||
699 | * @param $mappedFields |
||||||
700 | * @param $data |
||||||
701 | * |
||||||
702 | * @return array |
||||||
703 | */ |
||||||
704 | public function extractCompanyDataFromImport(array &$mappedFields, array &$data) |
||||||
705 | { |
||||||
706 | $companyData = []; |
||||||
707 | $companyFields = []; |
||||||
708 | $internalFields = $this->fetchCompanyFields(); |
||||||
709 | |||||||
710 | foreach ($mappedFields as $mauticField => $importField) { |
||||||
711 | foreach ($internalFields as $entityField) { |
||||||
712 | if ($entityField['alias'] === $mauticField) { |
||||||
713 | $companyData[$importField] = $data[$importField]; |
||||||
714 | $companyFields[$mauticField] = $importField; |
||||||
715 | unset($data[$importField]); |
||||||
716 | unset($mappedFields[$mauticField]); |
||||||
717 | break; |
||||||
718 | } |
||||||
719 | } |
||||||
720 | } |
||||||
721 | |||||||
722 | return [$companyFields, $companyData]; |
||||||
723 | } |
||||||
724 | |||||||
725 | /** |
||||||
726 | * @param array $fields |
||||||
727 | * @param array $data |
||||||
728 | * @param null $owner |
||||||
729 | * @param null $list |
||||||
730 | * @param null $tags |
||||||
731 | * @param bool $persist |
||||||
732 | * @param LeadEventLog $eventLog |
||||||
733 | * |
||||||
734 | * @return bool|null |
||||||
735 | * |
||||||
736 | * @throws \Exception |
||||||
737 | */ |
||||||
738 | public function import($fields, $data, $owner = null, $list = null, $tags = null, $persist = true, LeadEventLog $eventLog = null) |
||||||
0 ignored issues
–
show
The parameter
$list is not used and could be removed.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for parameters that have been defined for a function or method, but which are not used in the method body. ![]() The parameter
$eventLog is not used and could be removed.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for parameters that have been defined for a function or method, but which are not used in the method body. ![]() |
|||||||
739 | { |
||||||
740 | $fields = array_flip($fields); |
||||||
741 | |||||||
742 | // Let's check for an existing company by name |
||||||
743 | $hasName = (!empty($fields['companyname']) && !empty($data[$fields['companyname']])); |
||||||
744 | $hasEmail = (!empty($fields['companyemail']) && !empty($data[$fields['companyemail']])); |
||||||
745 | |||||||
746 | if ($hasEmail) { |
||||||
747 | $this->emailValidator->validate($data[$fields['companyemail']], false); |
||||||
748 | } |
||||||
749 | |||||||
750 | if ($hasName) { |
||||||
751 | $companyName = isset($fields['companyname']) ? $data[$fields['companyname']] : null; |
||||||
752 | $companyCity = isset($fields['companycity']) ? $data[$fields['companycity']] : null; |
||||||
753 | $companyCountry = isset($fields['companycountry']) ? $data[$fields['companycountry']] : null; |
||||||
754 | $companyState = isset($fields['companystate']) ? $data[$fields['companystate']] : null; |
||||||
755 | |||||||
756 | $found = $companyName ? $this->getRepository()->identifyCompany($companyName, $companyCity, $companyCountry, $companyState) : false; |
||||||
757 | $company = ($found) ? $this->em->getReference('MauticLeadBundle:Company', $found['id']) : new Company(); |
||||||
758 | $merged = $found; |
||||||
759 | } else { |
||||||
760 | return null; |
||||||
761 | } |
||||||
762 | |||||||
763 | if (!empty($fields['dateAdded']) && !empty($data[$fields['dateAdded']])) { |
||||||
764 | $dateAdded = new DateTimeHelper($data[$fields['dateAdded']]); |
||||||
765 | $company->setDateAdded($dateAdded->getUtcDateTime()); |
||||||
766 | } |
||||||
767 | unset($fields['dateAdded']); |
||||||
768 | |||||||
769 | if (!empty($fields['dateModified']) && !empty($data[$fields['dateModified']])) { |
||||||
770 | $dateModified = new DateTimeHelper($data[$fields['dateModified']]); |
||||||
771 | $company->setDateModified($dateModified->getUtcDateTime()); |
||||||
772 | } |
||||||
773 | unset($fields['dateModified']); |
||||||
774 | |||||||
775 | if (!empty($fields['createdByUser']) && !empty($data[$fields['createdByUser']])) { |
||||||
776 | $userRepo = $this->em->getRepository('MauticUserBundle:User'); |
||||||
777 | $createdByUser = $userRepo->findByIdentifier($data[$fields['createdByUser']]); |
||||||
778 | if (null !== $createdByUser) { |
||||||
779 | $company->setCreatedBy($createdByUser); |
||||||
780 | } |
||||||
781 | } |
||||||
782 | unset($fields['createdByUser']); |
||||||
783 | |||||||
784 | if (!empty($fields['modifiedByUser']) && !empty($data[$fields['modifiedByUser']])) { |
||||||
785 | $userRepo = $this->em->getRepository('MauticUserBundle:User'); |
||||||
786 | $modifiedByUser = $userRepo->findByIdentifier($data[$fields['modifiedByUser']]); |
||||||
787 | if (null !== $modifiedByUser) { |
||||||
788 | $company->setModifiedBy($modifiedByUser); |
||||||
789 | } |
||||||
790 | } |
||||||
791 | unset($fields['modifiedByUser']); |
||||||
792 | |||||||
793 | if (null !== $owner) { |
||||||
794 | $company->setOwner($this->em->getReference('MauticUserBundle:User', $owner)); |
||||||
795 | } |
||||||
796 | |||||||
797 | // Set profile data using the form so that values are validated |
||||||
798 | $fieldData = []; |
||||||
799 | foreach ($fields as $entityField => $importField) { |
||||||
800 | // Prevent overwriting existing data with empty data |
||||||
801 | if (array_key_exists($importField, $data) && !is_null($data[$importField]) && '' != $data[$importField]) { |
||||||
802 | $fieldData[$entityField] = $data[$importField]; |
||||||
803 | } |
||||||
804 | } |
||||||
805 | |||||||
806 | $fieldErrors = []; |
||||||
807 | |||||||
808 | foreach ($this->fetchCompanyFields() as $entityField) { |
||||||
809 | if (isset($fieldData[$entityField['alias']])) { |
||||||
810 | $fieldData[$entityField['alias']] = InputHelper::_($fieldData[$entityField['alias']], 'string'); |
||||||
811 | |||||||
812 | if ('NULL' === $fieldData[$entityField['alias']]) { |
||||||
813 | $fieldData[$entityField['alias']] = null; |
||||||
814 | |||||||
815 | continue; |
||||||
816 | } |
||||||
817 | |||||||
818 | try { |
||||||
819 | $this->cleanFields($fieldData, $entityField); |
||||||
820 | } catch (\Exception $exception) { |
||||||
821 | $fieldErrors[] = $entityField['alias'].': '.$exception->getMessage(); |
||||||
822 | } |
||||||
823 | |||||||
824 | // Skip if the value is in the CSV row |
||||||
825 | continue; |
||||||
826 | } elseif ($company->isNew() && $entityField['defaultValue']) { |
||||||
827 | // Fill in the default value if any |
||||||
828 | $fieldData[$entityField['alias']] = ('multiselect' === $entityField['type']) ? [$entityField['defaultValue']] : $entityField['defaultValue']; |
||||||
829 | } |
||||||
830 | } |
||||||
831 | |||||||
832 | if ($fieldErrors) { |
||||||
833 | $fieldErrors = implode("\n", $fieldErrors); |
||||||
834 | |||||||
835 | throw new \Exception($fieldErrors); |
||||||
836 | } |
||||||
837 | |||||||
838 | // All clear |
||||||
839 | foreach ($fieldData as $field => $value) { |
||||||
840 | $company->addUpdatedField($field, $value); |
||||||
841 | } |
||||||
842 | |||||||
843 | if ($persist) { |
||||||
844 | $this->saveEntity($company); |
||||||
845 | } |
||||||
846 | |||||||
847 | return $merged; |
||||||
848 | } |
||||||
849 | } |
||||||
850 |
This check looks for parameters that have been defined for a function or method, but which are not used in the method body.