1 | <?php |
||
2 | |||
3 | declare(strict_types=1); |
||
4 | |||
5 | /* |
||
6 | * @copyright 2018 Mautic Inc. All rights reserved |
||
7 | * @author Mautic, Inc. |
||
8 | * |
||
9 | * @link https://www.mautic.com |
||
10 | * |
||
11 | * @license GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html |
||
12 | */ |
||
13 | |||
14 | namespace Mautic\IntegrationsBundle\EventListener; |
||
15 | |||
16 | use Mautic\IntegrationsBundle\Entity\FieldChange; |
||
17 | use Mautic\IntegrationsBundle\Entity\FieldChangeRepository; |
||
18 | use Mautic\IntegrationsBundle\Entity\ObjectMappingRepository; |
||
19 | use Mautic\IntegrationsBundle\Exception\IntegrationNotFoundException; |
||
20 | use Mautic\IntegrationsBundle\Helper\SyncIntegrationsHelper; |
||
21 | use Mautic\IntegrationsBundle\Sync\Exception\ObjectNotFoundException; |
||
22 | use Mautic\IntegrationsBundle\Sync\SyncDataExchange\Internal\Object\Contact; |
||
23 | use Mautic\IntegrationsBundle\Sync\SyncDataExchange\MauticSyncDataExchange; |
||
24 | use Mautic\IntegrationsBundle\Sync\VariableExpresser\VariableExpresserHelperInterface; |
||
25 | use Mautic\LeadBundle\Entity\Company; |
||
26 | use Mautic\LeadBundle\Entity\Lead; |
||
27 | use Mautic\LeadBundle\Event as Events; |
||
28 | use Mautic\LeadBundle\LeadEvents; |
||
29 | use Symfony\Component\EventDispatcher\EventSubscriberInterface; |
||
30 | |||
31 | class LeadSubscriber implements EventSubscriberInterface |
||
32 | { |
||
33 | /** |
||
34 | * @var FieldChangeRepository |
||
35 | */ |
||
36 | private $fieldChangeRepo; |
||
37 | |||
38 | /** |
||
39 | * @var ObjectMappingRepository |
||
40 | */ |
||
41 | private $objectMappingRepository; |
||
42 | |||
43 | /** |
||
44 | * @var VariableExpresserHelperInterface |
||
45 | */ |
||
46 | private $variableExpressor; |
||
47 | |||
48 | /** |
||
49 | * @var SyncIntegrationsHelper |
||
50 | */ |
||
51 | private $syncIntegrationsHelper; |
||
52 | |||
53 | public function __construct( |
||
54 | FieldChangeRepository $fieldChangeRepo, |
||
55 | ObjectMappingRepository $objectMappingRepository, |
||
56 | VariableExpresserHelperInterface $variableExpressor, |
||
57 | SyncIntegrationsHelper $syncIntegrationsHelper |
||
58 | ) { |
||
59 | $this->fieldChangeRepo = $fieldChangeRepo; |
||
60 | $this->objectMappingRepository = $objectMappingRepository; |
||
61 | $this->variableExpressor = $variableExpressor; |
||
62 | $this->syncIntegrationsHelper = $syncIntegrationsHelper; |
||
63 | } |
||
64 | |||
65 | public static function getSubscribedEvents(): array |
||
66 | { |
||
67 | return [ |
||
68 | LeadEvents::LEAD_POST_SAVE => ['onLeadPostSave', 0], |
||
69 | LeadEvents::LEAD_POST_DELETE => ['onLeadPostDelete', 255], |
||
70 | LeadEvents::COMPANY_POST_SAVE => ['onCompanyPostSave', 0], |
||
71 | LeadEvents::COMPANY_POST_DELETE => ['onCompanyPostDelete', 255], |
||
72 | LeadEvents::LEAD_COMPANY_CHANGE => ['onLeadCompanyChange', 128], |
||
73 | ]; |
||
74 | } |
||
75 | |||
76 | /** |
||
77 | * @throws IntegrationNotFoundException |
||
78 | * @throws ObjectNotFoundException |
||
79 | */ |
||
80 | public function onLeadPostSave(Events\LeadEvent $event): void |
||
81 | { |
||
82 | $lead = $event->getLead(); |
||
83 | if ($lead->isAnonymous()) { |
||
84 | // Do not track visitor changes |
||
85 | return; |
||
86 | } |
||
87 | |||
88 | if (defined('MAUTIC_INTEGRATION_SYNC_IN_PROGRESS')) { |
||
89 | // Don't track changes just made by an active sync |
||
90 | return; |
||
91 | } |
||
92 | |||
93 | if (!$this->syncIntegrationsHelper->hasObjectSyncEnabled(Contact::NAME)) { |
||
94 | // Only track if an integration is syncing with contacts |
||
95 | return; |
||
96 | } |
||
97 | |||
98 | $changes = $lead->getChanges(true); |
||
99 | |||
100 | if (!empty($changes['owner'])) { |
||
101 | // Force record of owner change if present in changelist |
||
102 | $changes['fields']['owner_id'] = $changes['owner']; |
||
103 | } |
||
104 | |||
105 | if (!empty($changes['points'])) { |
||
106 | // Add ability to update points custom field in target |
||
107 | $changes['fields']['points'] = $changes['points']; |
||
108 | } |
||
109 | |||
110 | if (isset($changes['fields'])) { |
||
111 | $this->recordFieldChanges($changes['fields'], $lead->getId(), Lead::class); |
||
112 | } |
||
113 | |||
114 | if (isset($changes['dnc_channel_status'])) { |
||
115 | $dncChanges = []; |
||
116 | foreach ($changes['dnc_channel_status'] as $channel => $change) { |
||
117 | $oldValue = $change['old_reason'] ?? ''; |
||
118 | $newValue = $change['reason']; |
||
119 | |||
120 | $dncChanges['mautic_internal_dnc_'.$channel] = [$oldValue, $newValue]; |
||
121 | } |
||
122 | |||
123 | $this->recordFieldChanges($dncChanges, $lead->getId(), Lead::class); |
||
124 | } |
||
125 | } |
||
126 | |||
127 | public function onLeadPostDelete(Events\LeadEvent $event): void |
||
128 | { |
||
129 | $this->fieldChangeRepo->deleteEntitiesForObject((int) $event->getLead()->deletedId, MauticSyncDataExchange::OBJECT_CONTACT); |
||
130 | $this->objectMappingRepository->deleteEntitiesForObject((int) $event->getLead()->deletedId, MauticSyncDataExchange::OBJECT_CONTACT); |
||
131 | } |
||
132 | |||
133 | /** |
||
134 | * @throws IntegrationNotFoundException |
||
135 | * @throws ObjectNotFoundException |
||
136 | */ |
||
137 | public function onCompanyPostSave(Events\CompanyEvent $event): void |
||
138 | { |
||
139 | if (defined('MAUTIC_INTEGRATION_SYNC_IN_PROGRESS')) { |
||
140 | // Don't track changes just made by an active sync |
||
141 | return; |
||
142 | } |
||
143 | |||
144 | if (!$this->syncIntegrationsHelper->hasObjectSyncEnabled(MauticSyncDataExchange::OBJECT_COMPANY)) { |
||
145 | // Only track if an integration is syncing with companies |
||
146 | return; |
||
147 | } |
||
148 | |||
149 | $company = $event->getCompany(); |
||
150 | $changes = $company->getChanges(true); |
||
151 | |||
152 | if (!empty($changes['owner'])) { |
||
153 | // Force record of owner change if present in changelist |
||
154 | $changes['fields']['owner_id'] = $changes['owner']; |
||
155 | } |
||
156 | |||
157 | if (!isset($changes['fields'])) { |
||
158 | return; |
||
159 | } |
||
160 | |||
161 | $this->recordFieldChanges($changes['fields'], $company->getId(), Company::class); |
||
162 | } |
||
163 | |||
164 | public function onCompanyPostDelete(Events\CompanyEvent $event): void |
||
165 | { |
||
166 | $this->fieldChangeRepo->deleteEntitiesForObject((int) $event->getCompany()->deletedId, MauticSyncDataExchange::OBJECT_COMPANY); |
||
167 | $this->objectMappingRepository->deleteEntitiesForObject((int) $event->getCompany()->deletedId, MauticSyncDataExchange::OBJECT_COMPANY); |
||
168 | } |
||
169 | |||
170 | public function onLeadCompanyChange(Events\LeadChangeCompanyEvent $event): void |
||
171 | { |
||
172 | $lead = $event->getLead(); |
||
173 | |||
174 | // This mechanism is not able to record multiple company changes. |
||
175 | $changes['company'] = [ |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
Loading history...
|
|||
176 | 0 => '', |
||
177 | 1 => $lead->getCompany(), |
||
178 | ]; |
||
179 | |||
180 | $this->recordFieldChanges($changes, $lead->getId(), Lead::class); |
||
181 | } |
||
182 | |||
183 | /** |
||
184 | * @param int $objectId |
||
185 | * |
||
186 | * @throws IntegrationNotFoundException |
||
187 | */ |
||
188 | private function recordFieldChanges(array $fieldChanges, $objectId, string $objectType): void |
||
189 | { |
||
190 | $toPersist = []; |
||
191 | $changedFields = []; |
||
192 | $objectId = (int) $objectId; |
||
193 | foreach ($fieldChanges as $key => [$oldValue, $newValue]) { |
||
194 | $valueDAO = $this->variableExpressor->encodeVariable($newValue); |
||
195 | $changedFields[] = $key; |
||
196 | $fieldChangeEntity = (new FieldChange()) |
||
197 | ->setObjectType($objectType) |
||
198 | ->setObjectId($objectId) |
||
199 | ->setModifiedAt(new \DateTime()) |
||
200 | ->setColumnName($key) |
||
201 | ->setColumnType($valueDAO->getType()) |
||
202 | ->setColumnValue($valueDAO->getValue()); |
||
203 | |||
204 | foreach ($this->syncIntegrationsHelper->getEnabledIntegrations() as $integrationName) { |
||
205 | $integrationFieldChangeEntity = clone $fieldChangeEntity; |
||
206 | $integrationFieldChangeEntity->setIntegration($integrationName); |
||
207 | |||
208 | $toPersist[] = $integrationFieldChangeEntity; |
||
209 | } |
||
210 | } |
||
211 | |||
212 | $this->fieldChangeRepo->deleteEntitiesForObjectByColumnName($objectId, $objectType, $changedFields); |
||
213 | $this->fieldChangeRepo->saveEntities($toPersist); |
||
214 | |||
215 | $this->fieldChangeRepo->clear(); |
||
216 | } |
||
217 | } |
||
218 |