Issues (3627)

Integration/PipedriveIntegration.php (1 issue)

1
<?php
2
3
namespace MauticPlugin\MauticCrmBundle\Integration;
4
5
use Doctrine\ORM\EntityManager;
6
use Mautic\CoreBundle\Helper\CacheStorageHelper;
7
use Mautic\CoreBundle\Helper\EncryptionHelper;
8
use Mautic\CoreBundle\Helper\PathsHelper;
9
use Mautic\CoreBundle\Model\NotificationModel;
10
use Mautic\LeadBundle\Model\CompanyModel;
11
use Mautic\LeadBundle\Model\DoNotContact;
12
use Mautic\LeadBundle\Model\FieldModel;
13
use Mautic\LeadBundle\Model\LeadModel;
14
use Mautic\PluginBundle\Model\IntegrationEntityModel;
15
use MauticPlugin\MauticCrmBundle\Api\CrmApi;
16
use MauticPlugin\MauticCrmBundle\Integration\Pipedrive\Export\LeadExport;
17
use MauticPlugin\MauticCrmBundle\Services\Transport;
18
use Monolog\Logger;
19
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
20
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
21
use Symfony\Component\HttpFoundation\RequestStack;
22
use Symfony\Component\HttpFoundation\Session\Session;
23
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
24
use Symfony\Component\Routing\Router;
25
use Symfony\Component\Translation\TranslatorInterface;
26
27
class PipedriveIntegration extends CrmAbstractIntegration
28
{
29
    const INTEGRATION_NAME         = 'Pipedrive';
30
    const PERSON_ENTITY_TYPE       = 'person';
31
    const LEAD_ENTITY_TYPE         = 'lead';
32
    const ORGANIZATION_ENTITY_TYPE = 'organization';
33
    const COMPANY_ENTITY_TYPE      = 'company';
34
35
    /**
36
     * @var Transport
37
     */
38
    private $transport;
39
40
    /**
41
     * @var LeadExport
42
     */
43
    private $leadExport;
44
45
    /**
46
     * @var CrmApi
47
     */
48
    private $apiHelper;
49
50
    private $requiredFields = [
51
        'person'        => ['firstname', 'lastname', 'email'],
52
        'organization'  => ['name'],
53
    ];
54
55
    public function __construct(
56
        EventDispatcherInterface $eventDispatcher,
57
        CacheStorageHelper $cacheStorageHelper,
58
        EntityManager $entityManager,
59
        Session $session,
60
        RequestStack $requestStack,
61
        Router $router,
62
        TranslatorInterface $translator,
63
        Logger $logger,
64
        EncryptionHelper $encryptionHelper,
65
        LeadModel $leadModel,
66
        CompanyModel $companyModel,
67
        PathsHelper $pathsHelper,
68
        NotificationModel $notificationModel,
69
        FieldModel $fieldModel,
70
        IntegrationEntityModel $integrationEntityModel,
71
        DoNotContact $doNotContact,
72
        Transport $transport,
73
        LeadExport $leadExport
74
    ) {
75
        parent::__construct(
76
            $eventDispatcher,
77
            $cacheStorageHelper,
78
            $entityManager,
79
            $session,
80
            $requestStack,
81
            $router,
82
            $translator,
83
            $logger,
84
            $encryptionHelper,
85
            $leadModel,
86
            $companyModel,
87
            $pathsHelper,
88
            $notificationModel,
89
            $fieldModel,
90
            $integrationEntityModel,
91
            $doNotContact
92
        );
93
94
        $this->transport  = $transport;
95
        $this->leadExport = $leadExport;
96
    }
97
98
    /**
99
     * @return string
100
     */
101
    public function getName()
102
    {
103
        return self::INTEGRATION_NAME;
104
    }
105
106
    /**
107
     * @return array
108
     */
109
    public function getSupportedFeatures()
110
    {
111
        return ['push_lead'];
112
    }
113
114
    /**
115
     * Return's authentication method such as oauth2, oauth1a, key, etc.
116
     *
117
     * @return string
118
     */
119
    public function getAuthenticationType()
120
    {
121
        return 'key';
122
    }
123
124
    /**
125
     * Get the array key for client secret.
126
     *
127
     * @return string
128
     */
129
    public function getClientSecretKey()
130
    {
131
        return 'token';
132
    }
133
134
    /**
135
     * {@inheritdoc}
136
     *
137
     * @return array
138
     */
139
    public function getSecretKeys()
140
    {
141
        return [
142
            'token',
143
            'password',
144
        ];
145
    }
146
147
    /**
148
     * Get the array key for the auth token.
149
     *
150
     * @return string
151
     */
152
    public function getAuthTokenKey()
153
    {
154
        return 'token';
155
    }
156
157
    /**
158
     * {@inheritdoc}
159
     *
160
     * @return array
161
     */
162
    public function getRequiredKeyFields()
163
    {
164
        return [
165
            'url'      => 'mautic.pipedrive.api_url',
166
            'token'    => 'mautic.pipedrive.token',
167
            'user'     => 'mautic.pipedrive.webhook_user',
168
            'password' => 'mautic.pipedrive.webhook_password',
169
        ];
170
    }
171
172
    public function getApiUrl()
173
    {
174
        if (isset($this->getKeys()['url'])) {
175
            return $this->getKeys()['url'];
176
        }
177
    }
178
179
    /**
180
     * {@inheritdoc}
181
     *
182
     * @return bool
183
     */
184
    public function isAuthorized()
185
    {
186
        $keys = $this->getKeys();
187
188
        return isset($keys[$this->getClientSecretKey()]);
189
    }
190
191
    /**
192
     * Get available company fields for choices in the config UI.
193
     *
194
     * @param array $settings
195
     *
196
     * @return array
197
     */
198
    public function getFormCompanyFields($settings = [])
199
    {
200
        return $this->getAvailableLeadFields(self::ORGANIZATION_ENTITY_TYPE);
201
    }
202
203
    /**
204
     * @param array $settings
205
     *
206
     * @return array|mixed
207
     */
208
    public function getFormLeadFields($settings = [])
209
    {
210
        $fields = $this->getAvailableLeadFields(self::PERSON_ENTITY_TYPE);
211
212
        if (empty($fields)) {
213
            return [];
214
        }
215
216
        if (isset($fields['org_id'])) {
217
            unset($fields['org_id']);
218
        }
219
220
        // handle fields with are available in Pipedrive, but not listed
221
        return array_merge($fields, [
222
            'last_name' => [
223
                'label'    => 'Last Name',
224
                'required' => true,
225
            ],
226
            'first_name' => [
227
                'label'    => 'First Name',
228
                'required' => true,
229
            ],
230
        ]);
231
    }
232
233
    /**
234
     * @return array|mixed
235
     */
236
    public function getAvailableLeadFields($object = null)
237
    {
238
        $integrationFields = [];
239
240
        /**
241
         * $object as Array comes from clicking "Apply" button on Plugins Configuration form.
242
         * I dont't know why its calling again pipedrive API to get fields which are already inside form...
243
         * Also i have no idea why is trying to pass some strange object...
244
         */
245
        if (!$this->isAuthorized() || !$object || is_array($object)) {
246
            return $integrationFields;
247
        }
248
249
        try {
250
            $leadFields = $this->getApiHelper()->getFields($object);
251
252
            if (!isset($leadFields)) {
253
                return $integrationFields;
254
            }
255
256
            foreach ($leadFields as $fieldInfo) {
257
                $integrationFields[$fieldInfo['key']] = [
258
                    'label'    => $fieldInfo['name'],
259
                    'required' => isset($this->requiredFields[$object]) && in_array($fieldInfo['key'], $this->requiredFields[$object]),
260
                ];
261
            }
262
        } catch (\Exception $e) {
263
            $this->logIntegrationError($e);
264
        }
265
266
        return $integrationFields;
267
    }
268
269
    /**
270
     * Get the API helper.
271
     *
272
     * @return object
273
     */
274
    public function getApiHelper()
275
    {
276
        if (empty($this->apiHelper)) {
277
            $class           = '\\MauticPlugin\\MauticCrmBundle\\Api\\'.$this->getName().'Api'; //TODO replace with service
278
            $this->apiHelper = new $class($this, $this->transport);
279
        }
280
281
        return $this->apiHelper;
282
    }
283
284
    /**
285
     * @param \Mautic\PluginBundle\Integration\Form|FormBuilder $builder
286
     * @param array                                             $data
287
     * @param string                                            $formArea
288
     */
289
    public function appendToForm(&$builder, $data, $formArea)
290
    {
291
        if ('features' == $formArea) {
292
            $builder->add(
293
                'objects',
294
                ChoiceType::class,
295
                [
296
                    'choices'     => [
297
                        'mautic.pipedrive.object.organization'  => 'company',
298
                    ],
299
                    'expanded'          => true,
300
                    'multiple'          => true,
301
                    'label'             => 'mautic.pipedrive.form.objects_to_pull_from',
302
                    'label_attr'        => ['class' => ''],
303
                    'placeholder'       => false,
304
                    'required'          => false,
305
                ]
306
            );
307
308
            $builder->add(
309
                'import',
310
                ChoiceType::class,
311
                [
312
                    'choices'     => [
313
                        'mautic.pipedrive.add.edit.contact.import.enabled' => 'enabled',
314
                    ],
315
                    'expanded'          => true,
316
                    'multiple'          => true,
317
                    'label'             => 'mautic.pipedrive.add.edit.contact.import',
318
                    'label_attr'        => ['class' => ''],
319
                    'placeholder'       => false,
320
                    'required'          => false,
321
                ]
322
            );
323
        }
324
    }
325
326
    /**
327
     * @param array|\Mautic\LeadBundle\Entity\Lead $lead
328
     * @param array                                $config
329
     *
330
     * @return mixed
331
     */
332
    public function pushLead($lead, $config = [])
333
    {
334
        $this->leadExport->setIntegration($this);
335
336
        return $this->leadExport->create($lead);
337
    }
338
339
    /**
340
     * {@inheritdoc}
341
     *
342
     * @param $section
343
     *
344
     * @return string
345
     */
346
    public function getFormNotes($section)
347
    {
348
        $router     = $this->router;
349
        $translator = $this->getTranslator();
350
351
        if ('authorization' == $section) {
352
            return [
0 ignored issues
show
Bug Best Practice introduced by
The expression return array($translator...:ABSOLUTE_URL), 'info') returns the type array<integer,string> which is incompatible with the documented return type string.
Loading history...
353
                $translator->trans('mautic.pipedrive.webhook_callback').$router->generate(
354
                    'mautic_integration.pipedrive.webhook',
355
                    [],
356
                    UrlGeneratorInterface::ABSOLUTE_URL
357
                ),
358
                'info',
359
            ];
360
        }
361
362
        return parent::getFormNotes($section);
363
    }
364
365
    /**
366
     * @return bool
367
     */
368
    public function isCompanySupportEnabled()
369
    {
370
        $supportedFeatures = $this->getIntegrationSettings()->getFeatureSettings();
371
372
        return isset($supportedFeatures['objects']) && in_array('company', $supportedFeatures['objects']);
373
    }
374
375
    /**
376
     * @return bool
377
     */
378
    public function shouldImportDataToPipedrive()
379
    {
380
        if (!$this->getIntegrationSettings()->getIsPublished() || empty($this->getIntegrationSettings()->getFeatureSettings()['import'])) {
381
            return false;
382
        }
383
384
        return true;
385
    }
386
387
    /**
388
     * @return \Doctrine\DBAL\Driver\Statement|int
389
     */
390
    public function removeIntegrationEntities()
391
    {
392
        $qb = $this->em->getConnection()->createQueryBuilder();
393
394
        return $qb->delete(MAUTIC_TABLE_PREFIX.'integration_entity')
395
            ->where(
396
                $qb->expr()->andX(
397
                    $qb->expr()->eq('integration', ':integration')
398
                )
399
            )
400
            ->setParameter('integration', $this->getName())
401
            ->execute();
402
    }
403
}
404