Initial commit: CloudOps infrastructure platform
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
# Workflow name:
|
||||
name: Close Pull Requests
|
||||
|
||||
# Workflow triggers:
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [opened]
|
||||
|
||||
# Workflow jobs:
|
||||
jobs:
|
||||
run:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: superbrothers/close-pull-request@v3
|
||||
with:
|
||||
comment: |
|
||||
Thank you for submitting a pull request. :raised_hands:
|
||||
|
||||
We greatly appreciate your willingness to submit a contribution. However, we are not accepting pull requests against this repository, as all development happens on the [main project repository](https://github.com/mautic/mautic).
|
||||
|
||||
We kindly request that you submit this pull request against the [respective directory](https://github.com/mautic/mautic/blob/head/plugins/MauticEmailMarketingBundle) of the main repository where we'll review and provide feedback. If this is your first Mautic contribution, be sure to read the [contributing guide](https://github.com/mautic/mautic/blob/4.x/.github/CONTRIBUTING.md) which provides guidelines and instructions for submitting contributions.
|
||||
|
||||
Thank you again, and we look forward to receiving your contribution! :smiley:
|
||||
|
||||
Best,
|
||||
The Mautic team
|
||||
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
namespace MauticPlugin\MauticEmailMarketingBundle\Api;
|
||||
|
||||
use Mautic\PluginBundle\Exception\ApiErrorException;
|
||||
|
||||
class ConstantContactApi extends EmailMarketingApi
|
||||
{
|
||||
private string $version = 'v2';
|
||||
|
||||
protected function request($endpoint, $parameters = [], $method = 'GET', $query = [])
|
||||
{
|
||||
$url = sprintf('https://api.constantcontact.com/%s/%s?api_key=%s', $this->version, $endpoint, $this->keys['client_id']);
|
||||
|
||||
$response = $this->integration->makeRequest($url, $parameters, $method, [
|
||||
'encode_parameters' => 'json',
|
||||
'append_auth_token' => true,
|
||||
'query' => $query,
|
||||
]);
|
||||
|
||||
if (is_array($response) && !empty($response[0]['error_message'])) {
|
||||
$errors = [];
|
||||
foreach ($response as $error) {
|
||||
$errors[] = $error['error_message'];
|
||||
}
|
||||
|
||||
throw new ApiErrorException(implode(' ', $errors));
|
||||
} else {
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed|string
|
||||
*
|
||||
* @throws ApiErrorException
|
||||
*/
|
||||
public function getLists()
|
||||
{
|
||||
return $this->request('lists');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $fields
|
||||
* @param array $config
|
||||
*
|
||||
* @return mixed|string
|
||||
*
|
||||
* @throws ApiErrorException
|
||||
*/
|
||||
public function subscribeLead($email, $listId, $fields = [], $config = [])
|
||||
{
|
||||
$parameters = array_merge($fields, [
|
||||
'lists' => [
|
||||
['id' => "$listId"],
|
||||
],
|
||||
'email_addresses' => [
|
||||
['email_address' => $email],
|
||||
],
|
||||
]);
|
||||
|
||||
$query = [
|
||||
'action_by' => $config['action_by'],
|
||||
];
|
||||
|
||||
return $this->request('contacts', $parameters, 'POST', $query);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace MauticPlugin\MauticEmailMarketingBundle\Api;
|
||||
|
||||
use Mautic\PluginBundle\Integration\AbstractIntegration;
|
||||
use Mautic\PluginBundle\Integration\UnifiedIntegrationInterface;
|
||||
|
||||
class EmailMarketingApi
|
||||
{
|
||||
protected $keys;
|
||||
|
||||
/**
|
||||
* @param AbstractIntegration $integration
|
||||
*/
|
||||
public function __construct(
|
||||
protected UnifiedIntegrationInterface $integration,
|
||||
) {
|
||||
$this->keys = $integration->getKeys();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
namespace MauticPlugin\MauticEmailMarketingBundle\Api;
|
||||
|
||||
use Mautic\PluginBundle\Exception\ApiErrorException;
|
||||
|
||||
class IcontactApi extends EmailMarketingApi
|
||||
{
|
||||
protected function request($endpoint, $parameters = [], $method = 'GET')
|
||||
{
|
||||
$url = sprintf('%s/%s/c/%s/%s', $this->integration->getApiUrl(), $this->keys['accountId'], $this->keys['clientFolderId'], $endpoint);
|
||||
|
||||
$response = $this->integration->makeRequest($url, $parameters, $method, [
|
||||
'encode_parameters' => 'json',
|
||||
'encoding_headers_set' => true,
|
||||
]);
|
||||
|
||||
if (is_array($response) && !empty($response['errors'])) {
|
||||
throw new ApiErrorException(implode(' ', $response['errors']));
|
||||
} else {
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed|string
|
||||
*
|
||||
* @throws ApiErrorException
|
||||
*/
|
||||
public function getLists()
|
||||
{
|
||||
return $this->request('lists');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed|string
|
||||
*
|
||||
* @throws ApiErrorException
|
||||
*/
|
||||
public function getCustomFields()
|
||||
{
|
||||
return $this->request('customfields');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $fields
|
||||
*
|
||||
* @return mixed|string
|
||||
*
|
||||
* @throws ApiErrorException
|
||||
*/
|
||||
public function subscribeLead($listId, $fields)
|
||||
{
|
||||
$fields['status'] = 'normal';
|
||||
|
||||
$contacts = $this->request('contacts', [$fields], 'POST');
|
||||
|
||||
if (!empty($contacts['contacts'][0]['contactId'])) {
|
||||
$contactId = $contacts['contacts'][0]['contactId'];
|
||||
|
||||
$fields = [
|
||||
'status' => 'normal',
|
||||
'listId' => $listId,
|
||||
'contactId' => $contactId,
|
||||
];
|
||||
|
||||
return $this->request('subscriptions', [$fields], 'POST');
|
||||
}
|
||||
|
||||
return $contacts;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
namespace MauticPlugin\MauticEmailMarketingBundle\Api;
|
||||
|
||||
use Mautic\PluginBundle\Exception\ApiErrorException;
|
||||
|
||||
class MailchimpApi extends EmailMarketingApi
|
||||
{
|
||||
private string $version = '3.0';
|
||||
|
||||
/**
|
||||
* @param array $parameters
|
||||
* @param string $method
|
||||
*
|
||||
* @return mixed|string
|
||||
*
|
||||
* @throws ApiErrorException
|
||||
*/
|
||||
protected function request($endpoint, $parameters = [], $method = 'GET')
|
||||
{
|
||||
if (isset($this->keys['password'])) {
|
||||
// Extract the dc from the key
|
||||
$parts = explode('-', $this->keys['password']);
|
||||
if (2 !== count($parts)) {
|
||||
throw new ApiErrorException('Invalid key');
|
||||
}
|
||||
|
||||
$dc = $parts[1];
|
||||
$apiUrl = 'https://'.$dc.'.api.mailchimp.com';
|
||||
$parameters['apikey'] = $this->keys['password'];
|
||||
} else {
|
||||
$apiUrl = $this->keys['api_endpoint'];
|
||||
$parameters['apikey'] = $this->keys['access_token'];
|
||||
}
|
||||
$url = sprintf('%s/%s/%s', $apiUrl, $this->version, $endpoint);
|
||||
|
||||
$response = $this->integration->makeRequest($url, $parameters, $method, ['encode_parameters' => 'json']);
|
||||
|
||||
if (is_array($response) && !empty($response['status']) && 'error' == $response['status']) {
|
||||
throw new ApiErrorException($response['error']);
|
||||
} elseif (is_array($response) && !empty($response['errors'])) {
|
||||
$errors = [];
|
||||
foreach ($response['errors'] as $error) {
|
||||
$errors[] = $error['message'];
|
||||
}
|
||||
throw new ApiErrorException(implode(' ', $errors));
|
||||
} else {
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
|
||||
public function getLists()
|
||||
{
|
||||
return $this->request('lists', ['limit' => 100]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed|string
|
||||
*
|
||||
* @throws ApiErrorException
|
||||
*/
|
||||
public function getCustomFields($listId)
|
||||
{
|
||||
return $this->request('lists/'.$listId.'/merge-fields');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $fields
|
||||
* @param array $config
|
||||
*
|
||||
* @return mixed|string
|
||||
*
|
||||
* @throws ApiErrorException
|
||||
*/
|
||||
public function subscribeLead($email, $listId, $fields = [], $config = [])
|
||||
{
|
||||
$emailStruct = new \stdClass();
|
||||
$emailStruct->email = $email;
|
||||
|
||||
$parameters = array_merge($config, [
|
||||
'id' => $listId,
|
||||
]);
|
||||
if (!empty($fields)) {
|
||||
$parameters = array_merge($parameters, ['merge_fields' => $fields]);
|
||||
}
|
||||
$parameters['email_address'] = $email;
|
||||
|
||||
return $this->request('lists/'.$listId.'/members', $parameters, 'POST');
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 10 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 4.3 KiB |
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'name' => 'Email Marketing',
|
||||
'description' => 'Enables integration with Mautic supported email marketing services.',
|
||||
'version' => '1.0',
|
||||
'author' => 'Mautic',
|
||||
|
||||
'services' => [
|
||||
'integrations' => [
|
||||
'mautic.integration.constantcontact' => [
|
||||
'class' => MauticPlugin\MauticEmailMarketingBundle\Integration\ConstantContactIntegration::class,
|
||||
'arguments' => [
|
||||
'event_dispatcher',
|
||||
'mautic.helper.cache_storage',
|
||||
'doctrine.orm.entity_manager',
|
||||
'request_stack',
|
||||
'router',
|
||||
'translator',
|
||||
'monolog.logger.mautic',
|
||||
'mautic.helper.encryption',
|
||||
'mautic.lead.model.lead',
|
||||
'mautic.lead.model.company',
|
||||
'mautic.helper.paths',
|
||||
'mautic.core.model.notification',
|
||||
'mautic.lead.model.field',
|
||||
'mautic.plugin.model.integration_entity',
|
||||
'mautic.lead.model.dnc',
|
||||
'mautic.lead.field.fields_with_unique_identifier',
|
||||
],
|
||||
],
|
||||
'mautic.integration.icontact' => [
|
||||
'class' => MauticPlugin\MauticEmailMarketingBundle\Integration\IcontactIntegration::class,
|
||||
'arguments' => [
|
||||
'event_dispatcher',
|
||||
'mautic.helper.cache_storage',
|
||||
'doctrine.orm.entity_manager',
|
||||
'request_stack',
|
||||
'router',
|
||||
'translator',
|
||||
'monolog.logger.mautic',
|
||||
'mautic.helper.encryption',
|
||||
'mautic.lead.model.lead',
|
||||
'mautic.lead.model.company',
|
||||
'mautic.helper.paths',
|
||||
'mautic.core.model.notification',
|
||||
'mautic.lead.model.field',
|
||||
'mautic.plugin.model.integration_entity',
|
||||
'mautic.lead.model.dnc',
|
||||
'mautic.lead.field.fields_with_unique_identifier',
|
||||
],
|
||||
],
|
||||
'mautic.integration.mailchimp' => [
|
||||
'class' => MauticPlugin\MauticEmailMarketingBundle\Integration\MailchimpIntegration::class,
|
||||
'arguments' => [
|
||||
'event_dispatcher',
|
||||
'mautic.helper.cache_storage',
|
||||
'doctrine.orm.entity_manager',
|
||||
'request_stack',
|
||||
'router',
|
||||
'translator',
|
||||
'monolog.logger.mautic',
|
||||
'mautic.helper.encryption',
|
||||
'mautic.lead.model.lead',
|
||||
'mautic.lead.model.company',
|
||||
'mautic.helper.paths',
|
||||
'mautic.core.model.notification',
|
||||
'mautic.lead.model.field',
|
||||
'mautic.plugin.model.integration_entity',
|
||||
'mautic.lead.model.dnc',
|
||||
'mautic.lead.field.fields_with_unique_identifier',
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Mautic\CoreBundle\DependencyInjection\MauticCoreExtension;
|
||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||||
|
||||
return function (ContainerConfigurator $configurator): void {
|
||||
$services = $configurator->services()
|
||||
->defaults()
|
||||
->autowire()
|
||||
->autoconfigure()
|
||||
->public();
|
||||
|
||||
$excludes = [
|
||||
'Api',
|
||||
];
|
||||
|
||||
$services->load('MauticPlugin\\MauticEmailMarketingBundle\\', '../')
|
||||
->exclude('../{'.implode(',', array_merge(MauticCoreExtension::DEFAULT_EXCLUDES, $excludes)).'}');
|
||||
};
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace MauticPlugin\MauticEmailMarketingBundle\DependencyInjection;
|
||||
|
||||
use Symfony\Component\Config\FileLocator;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Extension\Extension;
|
||||
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
|
||||
|
||||
class MauticEmailMarketingExtension extends Extension
|
||||
{
|
||||
/**
|
||||
* @param mixed[] $configs
|
||||
*/
|
||||
public function load(array $configs, ContainerBuilder $container): void
|
||||
{
|
||||
$loader = new PhpFileLoader($container, new FileLocator(__DIR__.'/../Config'));
|
||||
$loader->load('services.php');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
<?php
|
||||
|
||||
namespace MauticPlugin\MauticEmailMarketingBundle\Form\Type;
|
||||
|
||||
use Mautic\CoreBundle\Form\Type\YesNoButtonGroupType;
|
||||
use Mautic\CoreBundle\Helper\CoreParametersHelper;
|
||||
use Mautic\PluginBundle\Form\Type\FieldsType;
|
||||
use Mautic\PluginBundle\Helper\IntegrationHelper;
|
||||
use Mautic\PluginBundle\Model\PluginModel;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\Form\FormError;
|
||||
use Symfony\Component\Form\FormEvent;
|
||||
use Symfony\Component\Form\FormEvents;
|
||||
use Symfony\Component\HttpFoundation\RequestStack;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
|
||||
/**
|
||||
* @extends AbstractType<array<mixed>>
|
||||
*/
|
||||
class ConstantContactType extends AbstractType
|
||||
{
|
||||
public function __construct(
|
||||
private IntegrationHelper $integrationHelper,
|
||||
private PluginModel $pluginModel,
|
||||
protected RequestStack $requestStack,
|
||||
protected CoreParametersHelper $coreParametersHelper,
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param FormBuilderInterface<array<mixed>|null> $builder
|
||||
* @param array<string, mixed> $options
|
||||
*/
|
||||
public function buildForm(FormBuilderInterface $builder, array $options): void
|
||||
{
|
||||
/** @var \MauticPlugin\MauticEmailMarketingBundle\Integration\ConstantContactIntegration $object */
|
||||
$object = $this->integrationHelper->getIntegrationObject('ConstantContact');
|
||||
$integrationName = $object->getName();
|
||||
$session = $this->requestStack->getSession();
|
||||
$limit = $session->get(
|
||||
'mautic.plugin.'.$integrationName.'.lead.limit',
|
||||
$this->coreParametersHelper->get('default_pagelimit')
|
||||
);
|
||||
$page = $session->get('mautic.plugin.'.$integrationName.'.lead.page', 1);
|
||||
|
||||
$api = $object->getApiHelper();
|
||||
try {
|
||||
$lists = $api->getLists();
|
||||
|
||||
$choices = [];
|
||||
if (!empty($lists)) {
|
||||
foreach ($lists as $list) {
|
||||
$choices[$list['id']] = $list['name'];
|
||||
}
|
||||
|
||||
asort($choices);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$choices = [];
|
||||
$error = $e->getMessage();
|
||||
$page = 1;
|
||||
}
|
||||
|
||||
$builder->add('list', ChoiceType::class, [
|
||||
'choices' => array_flip($choices), // Choice type expects labels as keys
|
||||
'label' => 'mautic.emailmarketing.list',
|
||||
'required' => false,
|
||||
'attr' => [
|
||||
'tooltip' => 'mautic.emailmarketing.list.tooltip',
|
||||
],
|
||||
]);
|
||||
|
||||
$builder->add('sendWelcome', YesNoButtonGroupType::class, [
|
||||
'label' => 'mautic.emailmarketing.send_welcome',
|
||||
'data' => (!isset($options['data']['sendWelcome'])) ? true : $options['data']['sendWelcome'],
|
||||
]);
|
||||
|
||||
if (!empty($error)) {
|
||||
$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) use ($error): void {
|
||||
$form = $event->getForm();
|
||||
|
||||
if ($error) {
|
||||
$form['list']->addError(new FormError($error));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (isset($options['form_area']) && 'integration' == $options['form_area']) {
|
||||
$leadFields = $this->pluginModel->getLeadFields();
|
||||
|
||||
$fields = $object->getFormLeadFields();
|
||||
|
||||
[$specialInstructions, $alertType] = $object->getFormNotes('leadfield_match');
|
||||
$builder->add('leadFields', FieldsType::class, [
|
||||
'label' => 'mautic.integration.leadfield_matches',
|
||||
'required' => true,
|
||||
'mautic_fields' => $leadFields,
|
||||
'integration' => $object->getName(),
|
||||
'integration_object' => $object,
|
||||
'limit' => $limit,
|
||||
'page' => $page,
|
||||
'data' => $options['data'] ?? [],
|
||||
'integration_fields' => $fields,
|
||||
'special_instructions' => $specialInstructions,
|
||||
'mapped' => true,
|
||||
'alert_type' => $alertType,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function configureOptions(OptionsResolver $resolver): void
|
||||
{
|
||||
$resolver->setDefined(['form_area']);
|
||||
}
|
||||
|
||||
public function getBlockPrefix(): string
|
||||
{
|
||||
return 'emailmarketing_constantcontact';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
<?php
|
||||
|
||||
namespace MauticPlugin\MauticEmailMarketingBundle\Form\Type;
|
||||
|
||||
use Mautic\CoreBundle\Helper\CoreParametersHelper;
|
||||
use Mautic\PluginBundle\Form\Type\FieldsType;
|
||||
use Mautic\PluginBundle\Helper\IntegrationHelper;
|
||||
use Mautic\PluginBundle\Model\PluginModel;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\Form\FormError;
|
||||
use Symfony\Component\Form\FormEvent;
|
||||
use Symfony\Component\Form\FormEvents;
|
||||
use Symfony\Component\HttpFoundation\RequestStack;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
|
||||
/**
|
||||
* @extends AbstractType<array<mixed>>
|
||||
*/
|
||||
class IcontactType extends AbstractType
|
||||
{
|
||||
public function __construct(
|
||||
private IntegrationHelper $integrationHelper,
|
||||
private PluginModel $pluginModel,
|
||||
protected RequestStack $requestStack,
|
||||
protected CoreParametersHelper $coreParametersHelper,
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param FormBuilderInterface<array<mixed>|null> $builder
|
||||
* @param array<string, mixed> $options
|
||||
*/
|
||||
public function buildForm(FormBuilderInterface $builder, array $options): void
|
||||
{
|
||||
/** @var \MauticPlugin\MauticEmailMarketingBundle\Integration\IcontactIntegration $object */
|
||||
$object = $this->integrationHelper->getIntegrationObject('Icontact');
|
||||
$integrationName = $object->getName();
|
||||
$session = $this->requestStack->getSession();
|
||||
$limit = $session->get(
|
||||
'mautic.plugin.'.$integrationName.'.lead.limit',
|
||||
$this->coreParametersHelper->get('default_pagelimit')
|
||||
);
|
||||
$page = $session->get('mautic.plugin.'.$integrationName.'.lead.page', 1);
|
||||
|
||||
$api = $object->getApiHelper();
|
||||
try {
|
||||
$lists = $api->getLists();
|
||||
|
||||
$choices = [];
|
||||
if (!empty($lists['lists'])) {
|
||||
foreach ($lists['lists'] as $list) {
|
||||
$choices[$list['listId']] = $list['name'];
|
||||
}
|
||||
|
||||
asort($choices);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$choices = [];
|
||||
$error = $e->getMessage();
|
||||
$page = 1;
|
||||
}
|
||||
|
||||
$builder->add('list', ChoiceType::class, [
|
||||
'choices' => array_flip($choices), // Choice type expects labels as keys
|
||||
'label' => 'mautic.emailmarketing.list',
|
||||
'required' => false,
|
||||
'attr' => [
|
||||
'tooltip' => 'mautic.emailmarketing.list.tooltip',
|
||||
],
|
||||
]);
|
||||
|
||||
if (!empty($error)) {
|
||||
$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) use ($error): void {
|
||||
$form = $event->getForm();
|
||||
|
||||
if ($error) {
|
||||
$form['list']->addError(new FormError($error));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (isset($options['form_area']) && 'integration' == $options['form_area']) {
|
||||
$leadFields = $this->pluginModel->getLeadFields();
|
||||
|
||||
$fields = $object->getFormLeadFields();
|
||||
|
||||
[$specialInstructions, $alertType] = $object->getFormNotes('leadfield_match');
|
||||
$builder->add('leadFields', FieldsType::class, [
|
||||
'label' => 'mautic.integration.leadfield_matches',
|
||||
'required' => true,
|
||||
'mautic_fields' => $leadFields,
|
||||
'integration' => $object->getName(),
|
||||
'integration_object' => $object,
|
||||
'limit' => $limit,
|
||||
'page' => $page,
|
||||
'data' => $options['data'] ?? [],
|
||||
'integration_fields' => $fields,
|
||||
'special_instructions' => $specialInstructions,
|
||||
'mapped' => true,
|
||||
'error_bubbling' => false,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function configureOptions(OptionsResolver $resolver): void
|
||||
{
|
||||
$resolver->setDefined(['form_area']);
|
||||
}
|
||||
|
||||
public function getBlockPrefix(): string
|
||||
{
|
||||
return 'emailmarketing_icontact';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,173 @@
|
||||
<?php
|
||||
|
||||
namespace MauticPlugin\MauticEmailMarketingBundle\Form\Type;
|
||||
|
||||
use Mautic\CoreBundle\Form\Type\YesNoButtonGroupType;
|
||||
use Mautic\CoreBundle\Helper\CoreParametersHelper;
|
||||
use Mautic\PluginBundle\Form\Type\FieldsType;
|
||||
use Mautic\PluginBundle\Helper\IntegrationHelper;
|
||||
use Mautic\PluginBundle\Model\PluginModel;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\Form\FormError;
|
||||
use Symfony\Component\Form\FormEvent;
|
||||
use Symfony\Component\Form\FormEvents;
|
||||
use Symfony\Component\Form\FormInterface;
|
||||
use Symfony\Component\HttpFoundation\RequestStack;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
|
||||
/**
|
||||
* @extends AbstractType<array<mixed>>
|
||||
*/
|
||||
class MailchimpType extends AbstractType
|
||||
{
|
||||
public function __construct(
|
||||
private IntegrationHelper $integrationHelper,
|
||||
private PluginModel $pluginModel,
|
||||
protected RequestStack $requestStack,
|
||||
protected CoreParametersHelper $coreParametersHelper,
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param FormBuilderInterface<array<mixed>|null> $builder
|
||||
* @param array<string, mixed> $options
|
||||
*/
|
||||
public function buildForm(FormBuilderInterface $builder, array $options): void
|
||||
{
|
||||
/** @var \MauticPlugin\MauticEmailMarketingBundle\Integration\MailchimpIntegration $mailchimp */
|
||||
$mailchimp = $this->integrationHelper->getIntegrationObject('Mailchimp');
|
||||
|
||||
$api = $mailchimp->getApiHelper();
|
||||
try {
|
||||
$lists = $api->getLists();
|
||||
$choices = [];
|
||||
if (!empty($lists)) {
|
||||
if ($lists['total_items']) {
|
||||
foreach ($lists['lists'] as $list) {
|
||||
$choices[$list['id']] = $list['name'];
|
||||
}
|
||||
}
|
||||
|
||||
asort($choices);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$choices = [];
|
||||
$error = $e->getMessage();
|
||||
}
|
||||
|
||||
$builder->add('list', ChoiceType::class, [
|
||||
'choices' => array_flip($choices), // Choice type expects labels as keys
|
||||
'label' => 'mautic.emailmarketing.list',
|
||||
'required' => false,
|
||||
'attr' => [
|
||||
'tooltip' => 'mautic.emailmarketing.list.tooltip',
|
||||
'onchange' => 'Mautic.getIntegrationLeadFields(\'Mailchimp\', this, {"list": this.value});',
|
||||
],
|
||||
]);
|
||||
|
||||
$builder->add('doubleOptin', YesNoButtonGroupType::class, [
|
||||
'label' => 'mautic.mailchimp.double_optin',
|
||||
'data' => (!isset($options['data']['doubleOptin'])) ? true : $options['data']['doubleOptin'],
|
||||
]);
|
||||
|
||||
$builder->add('sendWelcome', YesNoButtonGroupType::class, [
|
||||
'label' => 'mautic.emailmarketing.send_welcome',
|
||||
'data' => (!isset($options['data']['sendWelcome'])) ? true : $options['data']['sendWelcome'],
|
||||
]);
|
||||
|
||||
if (!empty($error)) {
|
||||
$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) use ($error): void {
|
||||
$form = $event->getForm();
|
||||
|
||||
if ($error) {
|
||||
$form['list']->addError(new FormError($error));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (isset($options['form_area']) && 'integration' == $options['form_area']) {
|
||||
$leadFields = $this->pluginModel->getLeadFields();
|
||||
|
||||
$formModifier = function (FormInterface $form, $data) use ($mailchimp, $leadFields): void {
|
||||
$integrationName = $mailchimp->getName();
|
||||
$session = $this->requestStack->getSession();
|
||||
$limit = $session->get(
|
||||
'mautic.plugin.'.$integrationName.'.lead.limit',
|
||||
$this->coreParametersHelper->get('default_pagelimit')
|
||||
);
|
||||
$page = $session->get('mautic.plugin.'.$integrationName.'.lead.page', 1);
|
||||
$settings = [
|
||||
'silence_exceptions' => false,
|
||||
'feature_settings' => [
|
||||
'list_settings' => $data,
|
||||
],
|
||||
'ignore_field_cache' => (1 == $page && 'POST' !== $_SERVER['REQUEST_METHOD']) ? true : false,
|
||||
];
|
||||
try {
|
||||
$fields = $mailchimp->getFormLeadFields($settings);
|
||||
|
||||
if (!is_array($fields)) {
|
||||
$fields = [];
|
||||
}
|
||||
$error = '';
|
||||
} catch (\Exception $e) {
|
||||
$fields = [];
|
||||
$error = $e->getMessage();
|
||||
$page = 1;
|
||||
}
|
||||
|
||||
[$specialInstructions] = $mailchimp->getFormNotes('leadfield_match');
|
||||
$form->add('leadFields', FieldsType::class, [
|
||||
'label' => 'mautic.integration.leadfield_matches',
|
||||
'required' => true,
|
||||
'mautic_fields' => $leadFields,
|
||||
'integration' => $mailchimp->getName(),
|
||||
'integration_object' => $mailchimp,
|
||||
'limit' => $limit,
|
||||
'page' => $page,
|
||||
'data' => $data,
|
||||
'integration_fields' => $fields,
|
||||
'special_instructions' => $specialInstructions,
|
||||
'mapped' => true,
|
||||
'error_bubbling' => false,
|
||||
]);
|
||||
|
||||
if ($error) {
|
||||
$form->addError(new FormError($error));
|
||||
}
|
||||
};
|
||||
|
||||
$builder->addEventListener(FormEvents::PRE_SET_DATA,
|
||||
function (FormEvent $event) use ($formModifier): void {
|
||||
$data = $event->getData();
|
||||
if (isset($data['leadFields']['leadFields'])) {
|
||||
$data['leadFields'] = $data['leadFields']['leadFields'];
|
||||
}
|
||||
$formModifier($event->getForm(), $data);
|
||||
}
|
||||
);
|
||||
|
||||
$builder->addEventListener(FormEvents::PRE_SUBMIT,
|
||||
function (FormEvent $event) use ($formModifier): void {
|
||||
$data = $event->getData();
|
||||
if (isset($data['leadFields']['leadFields'])) {
|
||||
$data['leadFields'] = $data['leadFields']['leadFields'];
|
||||
}
|
||||
$formModifier($event->getForm(), $data);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public function configureOptions(OptionsResolver $resolver): void
|
||||
{
|
||||
$resolver->setDefined(['form_area']);
|
||||
}
|
||||
|
||||
public function getBlockPrefix(): string
|
||||
{
|
||||
return 'emailmarketing_mailchimp';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,169 @@
|
||||
<?php
|
||||
|
||||
namespace MauticPlugin\MauticEmailMarketingBundle\Integration;
|
||||
|
||||
use MauticPlugin\MauticEmailMarketingBundle\Form\Type\ConstantContactType;
|
||||
|
||||
class ConstantContactIntegration extends EmailAbstractIntegration
|
||||
{
|
||||
public function getName(): string
|
||||
{
|
||||
return 'ConstantContact';
|
||||
}
|
||||
|
||||
public function getDisplayName(): string
|
||||
{
|
||||
return 'Constant Contact';
|
||||
}
|
||||
|
||||
public function getAuthenticationType(): string
|
||||
{
|
||||
return 'oauth2';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the URL required to obtain an oauth2 access token.
|
||||
*/
|
||||
public function getAccessTokenUrl(): string
|
||||
{
|
||||
return 'https://oauth2.constantcontact.com/oauth2/oauth/token';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the authentication/login URL for oauth2 access.
|
||||
*/
|
||||
public function getAuthenticationUrl(): string
|
||||
{
|
||||
return 'https://oauth2.constantcontact.com/oauth2/oauth/siteowner/authorize';
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves and stores tokens returned from oAuthLogin.
|
||||
*
|
||||
* @param array $settings
|
||||
* @param array $parameters
|
||||
*
|
||||
* @return bool|string false if no error; otherwise the error string
|
||||
*/
|
||||
public function authCallback($settings = [], $parameters = [])
|
||||
{
|
||||
// Constanct Contact doesn't like POST
|
||||
$settings['method'] = 'GET';
|
||||
|
||||
return parent::authCallback($settings, $parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed[]
|
||||
*/
|
||||
public function getAvailableLeadFields($settings = []): array
|
||||
{
|
||||
if (!$this->isAuthorized()) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$fields = [
|
||||
'email',
|
||||
'prefix_name',
|
||||
'first_name',
|
||||
'last_name',
|
||||
'company_name',
|
||||
'job_title',
|
||||
'address_line1',
|
||||
'address_line2',
|
||||
'address_city',
|
||||
'address_state',
|
||||
'address_country_code',
|
||||
'address_postal_code',
|
||||
'cell_phone',
|
||||
'fax',
|
||||
'work_phone',
|
||||
'home_phone',
|
||||
];
|
||||
|
||||
$leadFields = [];
|
||||
foreach ($fields as $f) {
|
||||
$leadFields[$f] = [
|
||||
'label' => $this->translator->trans('mautic.constantcontact.field.'.$f),
|
||||
'type' => 'string',
|
||||
'required' => ('email' == $f) ? true : false,
|
||||
];
|
||||
}
|
||||
|
||||
$c = 1;
|
||||
while ($c <= 15) {
|
||||
$leadFields['customfield_'.$c] = [
|
||||
'label' => $this->translator->trans('mautic.constantcontact.customfield.'.$f),
|
||||
'type' => 'string',
|
||||
'required' => false,
|
||||
];
|
||||
++$c;
|
||||
}
|
||||
|
||||
return $leadFields;
|
||||
}
|
||||
|
||||
public function pushLead($lead, $config = []): bool
|
||||
{
|
||||
$config = $this->mergeConfigToFeatureSettings($config);
|
||||
|
||||
$mappedData = $this->populateLeadData($lead, $config);
|
||||
|
||||
if (empty($mappedData)) {
|
||||
return false;
|
||||
} elseif (empty($mappedData['email'])) {
|
||||
return false;
|
||||
} elseif (!isset($config['list_settings'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
if ($this->isAuthorized()) {
|
||||
$email = $mappedData['email'];
|
||||
unset($mappedData['email']);
|
||||
|
||||
$addresses = [];
|
||||
$customfields = [];
|
||||
foreach ($mappedData as $k => $v) {
|
||||
if (str_starts_with($v, 'address_')) {
|
||||
$addresses[str_replace('address_', '', $k)] = $v;
|
||||
unset($mappedData[$k]);
|
||||
} elseif (str_starts_with($v, 'customfield_')) {
|
||||
$key = str_replace('customfield_', 'CustomField', $k);
|
||||
$customfields[] = [
|
||||
'name' => $key,
|
||||
'value' => $v,
|
||||
];
|
||||
unset($mappedData[$k]);
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($addresses)) {
|
||||
$addresses['address_type'] = 'PERSONAL';
|
||||
$mappedData['addresses'] = $addresses;
|
||||
}
|
||||
|
||||
if (!empty($customfields)) {
|
||||
$mappedData['custom_fields'] = $customfields;
|
||||
}
|
||||
|
||||
$options = [];
|
||||
$options['action_by'] = (!empty($config['list_settings']['sendWelcome'])) ? 'ACTION_BY_VISITOR' : 'ACTION_BY_OWNER';
|
||||
$listId = $config['list_settings']['list'];
|
||||
|
||||
$this->getApiHelper()->subscribeLead($email, $listId, $mappedData, $options);
|
||||
|
||||
return true;
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$this->logIntegrationError($e);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getFormType(): string
|
||||
{
|
||||
return ConstantContactType::class;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
|
||||
namespace MauticPlugin\MauticEmailMarketingBundle\Integration;
|
||||
|
||||
use Mautic\PluginBundle\Integration\AbstractIntegration;
|
||||
use Symfony\Component\Form\Form;
|
||||
use Symfony\Component\Form\FormBuilder;
|
||||
|
||||
abstract class EmailAbstractIntegration extends AbstractIntegration
|
||||
{
|
||||
protected $pushContactLink = false;
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getSupportedFeatures()
|
||||
{
|
||||
return ['push_lead'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param FormBuilder|Form $builder
|
||||
*/
|
||||
public function appendToForm(&$builder, $data, $formArea): void
|
||||
{
|
||||
if ('features' == $formArea || 'integration' == $formArea) {
|
||||
if ($this->isAuthorized()) {
|
||||
$formType = $this->getFormType();
|
||||
|
||||
if ($formType) {
|
||||
if ('integration' == $formArea && isset($data['leadFields']) && empty($data['list_settings']['leadFields'])) {
|
||||
$data['list_settings']['leadFields'] = $data['leadFields'];
|
||||
}
|
||||
|
||||
$builder->add('list_settings', $formType, [
|
||||
'label' => false,
|
||||
'form_area' => $formArea,
|
||||
'data' => $data['list_settings'] ?? [],
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getFormTheme()
|
||||
{
|
||||
return '@MauticEmailMarketing/FormTheme/EmailMarketing/layout.html.twig';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns form type.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
abstract public function getFormType();
|
||||
|
||||
/**
|
||||
* Get the API helper.
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public function getApiHelper()
|
||||
{
|
||||
static $helper;
|
||||
if (empty($helper)) {
|
||||
$class = '\\MauticPlugin\\MauticEmailMarketingBundle\\Api\\'.$this->getName().'Api';
|
||||
$helper = new $class($this);
|
||||
}
|
||||
|
||||
return $helper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges a config from integration_list with feature settings.
|
||||
*
|
||||
* @param array $config
|
||||
*
|
||||
* @return array|mixed
|
||||
*/
|
||||
public function mergeConfigToFeatureSettings($config = [])
|
||||
{
|
||||
$featureSettings = $this->settings->getFeatureSettings();
|
||||
|
||||
if (isset($config['config']['list_settings']['leadFields'])) {
|
||||
$config['config']['leadFields'] = $this->formatMatchedFields($config['config']['list_settings']['leadFields']);
|
||||
|
||||
unset($config['config']['list_settings']['leadFields']);
|
||||
}
|
||||
|
||||
if (empty($config['integration']) || (!empty($config['integration']) && $config['integration'] == $this->getName())) {
|
||||
$featureSettings = array_merge($featureSettings, $config['config']);
|
||||
}
|
||||
|
||||
return $featureSettings;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,228 @@
|
||||
<?php
|
||||
|
||||
namespace MauticPlugin\MauticEmailMarketingBundle\Integration;
|
||||
|
||||
use MauticPlugin\MauticEmailMarketingBundle\Form\Type\IcontactType;
|
||||
|
||||
class IcontactIntegration extends EmailAbstractIntegration
|
||||
{
|
||||
public function getName(): string
|
||||
{
|
||||
return 'Icontact';
|
||||
}
|
||||
|
||||
public function getDisplayName(): string
|
||||
{
|
||||
return 'iContact';
|
||||
}
|
||||
|
||||
public function getAuthenticationType(): string
|
||||
{
|
||||
return 'rest';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of keys required to make an API call. Examples are key, clientId, clientSecret.
|
||||
*
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public function getRequiredKeyFields(): array
|
||||
{
|
||||
return [
|
||||
'API-AppId' => 'mautic.icontact.keyfield.appid',
|
||||
'API-Username' => 'mautic.icontact.keyfield.username',
|
||||
'API-Password' => 'mautic.icontact.keyfield.password',
|
||||
];
|
||||
}
|
||||
|
||||
public function getSecretKeys(): array
|
||||
{
|
||||
return [
|
||||
'API-Password',
|
||||
];
|
||||
}
|
||||
|
||||
public function getApiUrl(): string
|
||||
{
|
||||
return 'https://app.icontact.com/icp/a';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get account ID and client folder ID.
|
||||
*/
|
||||
public function authCallback($settings = [], $parameters = [])
|
||||
{
|
||||
$url = $this->getApiUrl();
|
||||
|
||||
$response = $this->makeRequest($url, $parameters);
|
||||
|
||||
// Validation kind of error
|
||||
if (isset($response['errors'][0])) {
|
||||
return $response['errors'][0];
|
||||
}
|
||||
|
||||
// Timeout kind of error
|
||||
if (isset($response['errors']['message'])) {
|
||||
return $response['errors']['message'];
|
||||
}
|
||||
|
||||
$keys = [];
|
||||
if (!empty($response['accounts'])) {
|
||||
$keys['accountId'] = $response['accounts'][0]['accountId'];
|
||||
|
||||
$url .= '/'.$keys['accountId'].'/c';
|
||||
$response = $this->makeRequest($url, $parameters);
|
||||
|
||||
if (!empty($response['clientfolders'])) {
|
||||
$keys['clientFolderId'] = $response['clientfolders'][0]['clientFolderId'];
|
||||
|
||||
return $this->extractAuthKeys($keys, 'clientFolderId');
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $parameters
|
||||
* @param string $method
|
||||
* @param array $settings
|
||||
*
|
||||
* @return mixed|string
|
||||
*/
|
||||
public function makeRequest($url, $parameters = [], $method = 'GET', $settings = [])
|
||||
{
|
||||
$settings['headers'] = [
|
||||
'Except:',
|
||||
'Accept: application/json',
|
||||
'Content-Type: application/json',
|
||||
'Api-Version: 2.2',
|
||||
'Api-AppId: '.$this->keys['API-AppId'],
|
||||
'Api-Username: '.$this->keys['API-Username'],
|
||||
'API-Password: '.$this->keys['API-Password'],
|
||||
];
|
||||
|
||||
return parent::makeRequest($url, $parameters, $method, $settings);
|
||||
}
|
||||
|
||||
public function isAuthorized(): bool
|
||||
{
|
||||
$keys = $this->getRequiredKeyFields();
|
||||
foreach ($keys as $k => $l) {
|
||||
if (empty($this->keys[$k])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($this->keys['accountId']) || empty($this->keys['clientFolderId'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed[]
|
||||
*/
|
||||
public function getAvailableLeadFields($settings = []): array
|
||||
{
|
||||
if (!$this->isAuthorized()) {
|
||||
return [];
|
||||
}
|
||||
|
||||
static $leadFields = [];
|
||||
|
||||
if (empty($leadFields)) {
|
||||
$fields = [
|
||||
'email',
|
||||
'prefix',
|
||||
'firstName',
|
||||
'lastName',
|
||||
'suffix',
|
||||
'street',
|
||||
'street2',
|
||||
'city',
|
||||
'state',
|
||||
'postalCode',
|
||||
'phone',
|
||||
'fax',
|
||||
'business',
|
||||
];
|
||||
|
||||
$leadFields = [];
|
||||
foreach ($fields as $f) {
|
||||
$leadFields[$f] = [
|
||||
'label' => $this->translator->trans('mautic.icontact.field.'.$f),
|
||||
'type' => 'string',
|
||||
'required' => ('email' == $f) ? true : false,
|
||||
];
|
||||
}
|
||||
|
||||
$customfields = $this->getApiHelper()->getCustomFields();
|
||||
|
||||
if (!empty($customfields['customfields'])) {
|
||||
foreach ($customfields['customfields'] as $field) {
|
||||
$leadFields['cf_'.$field['customFieldId']] = [
|
||||
'label' => $field['publicName'],
|
||||
'type' => 'string',
|
||||
'required' => false,
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $leadFields;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Mautic\LeadBundle\Entity\Lead $lead
|
||||
* @param array $config
|
||||
*/
|
||||
public function pushLead($lead, $config = []): bool
|
||||
{
|
||||
$config = $this->mergeConfigToFeatureSettings($config);
|
||||
|
||||
$mappedData = $this->populateLeadData($lead, $config);
|
||||
|
||||
if (empty($mappedData)) {
|
||||
return false;
|
||||
} elseif (empty($mappedData['email'])) {
|
||||
return false;
|
||||
} elseif (!isset($config['list_settings'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
if ($this->isAuthorized()) {
|
||||
$customfields = [];
|
||||
foreach ($mappedData as $k => &$v) {
|
||||
if (str_starts_with($k, 'cf_')) {
|
||||
$customfields[str_replace('cf_', '', $k)] = (string) $v;
|
||||
unset($mappedData[$k]);
|
||||
} else {
|
||||
$v = (string) $v;
|
||||
}
|
||||
}
|
||||
|
||||
$listId = $config['list_settings']['list'];
|
||||
|
||||
if (!empty($customfields)) {
|
||||
$mappedData += $customfields;
|
||||
}
|
||||
|
||||
$this->getApiHelper()->subscribeLead($listId, $mappedData);
|
||||
|
||||
return true;
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$this->logIntegrationError($e);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getFormType(): string
|
||||
{
|
||||
return IcontactType::class;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,175 @@
|
||||
<?php
|
||||
|
||||
namespace MauticPlugin\MauticEmailMarketingBundle\Integration;
|
||||
|
||||
use MauticPlugin\MauticEmailMarketingBundle\Form\Type\MailchimpType;
|
||||
|
||||
class MailchimpIntegration extends EmailAbstractIntegration
|
||||
{
|
||||
public function getName(): string
|
||||
{
|
||||
return 'Mailchimp';
|
||||
}
|
||||
|
||||
public function getDisplayName(): string
|
||||
{
|
||||
return 'MailChimp';
|
||||
}
|
||||
|
||||
public function getAuthenticationType(): string
|
||||
{
|
||||
return (empty($this->keys['client_id'])) ? 'basic' : 'oauth2';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the URL required to obtain an oauth2 access token.
|
||||
*/
|
||||
public function getAccessTokenUrl(): string
|
||||
{
|
||||
return 'https://login.mailchimp.com/oauth2/token';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the authentication/login URL for oauth2 access.
|
||||
*/
|
||||
public function getAuthenticationUrl(): string
|
||||
{
|
||||
return 'https://login.mailchimp.com/oauth2/authorize';
|
||||
}
|
||||
|
||||
public function getRequiredKeyFields(): array
|
||||
{
|
||||
return (empty($this->keys['client_id'])) ?
|
||||
[
|
||||
'username' => 'mautic.integration.keyfield.username',
|
||||
'password' => 'mautic.integration.keyfield.api',
|
||||
] :
|
||||
[
|
||||
'client_id' => 'mautic.integration.keyfield.clientid',
|
||||
'client_secret' => 'mautic.integration.keyfield.clientsecret',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $settings
|
||||
* @param array $parameters
|
||||
*
|
||||
* @return bool|string
|
||||
*/
|
||||
public function authCallback($settings = [], $parameters = [])
|
||||
{
|
||||
$error = parent::authCallback($settings, $parameters);
|
||||
|
||||
if (empty($error)) {
|
||||
// Now post to the metadata URL
|
||||
$data = $this->makeRequest('https://login.mailchimp.com/oauth2/metadata');
|
||||
|
||||
return $this->extractAuthKeys($data, 'dc');
|
||||
} else {
|
||||
return $error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $settings
|
||||
*
|
||||
* @return mixed[]
|
||||
*/
|
||||
public function getAvailableLeadFields($settings = []): array
|
||||
{
|
||||
if (isset($settings['list'])) {
|
||||
// Ajax update
|
||||
$listId = $settings['list'];
|
||||
} elseif (!empty($settings['feature_settings']['list_settings']['list'])) {
|
||||
// Form load
|
||||
$listId = $settings['feature_settings']['list_settings']['list'];
|
||||
} elseif (!empty($settings['list_settings']['list'])) {
|
||||
// Push action
|
||||
$listId = $settings['list_settings']['list'];
|
||||
}
|
||||
|
||||
if (!empty($listId)) {
|
||||
$settings['cache_suffix'] = $cacheSuffix = '.'.$listId;
|
||||
if ($fields = parent::getAvailableLeadFields($settings)) {
|
||||
return $fields;
|
||||
}
|
||||
|
||||
$fields = $this->getApiHelper()->getCustomFields($listId);
|
||||
|
||||
if (!empty($fields['merge_fields']) && count($fields['merge_fields'])) {
|
||||
foreach ($fields['merge_fields'] as $field) {
|
||||
$leadFields[$field['tag']] = [
|
||||
'label' => $field['name'],
|
||||
'type' => 'string',
|
||||
'required' => $field['required'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
$leadFields['EMAIL'] = [
|
||||
'label' => 'Email',
|
||||
'type' => 'string',
|
||||
'required' => true,
|
||||
];
|
||||
|
||||
$this->cache->set('leadFields'.$cacheSuffix, $leadFields);
|
||||
|
||||
return $leadFields;
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $config
|
||||
*/
|
||||
public function pushLead($lead, $config = []): bool
|
||||
{
|
||||
$config = $this->mergeConfigToFeatureSettings($config);
|
||||
$mappedData = $this->populateLeadData($lead, $config);
|
||||
|
||||
if (empty($mappedData)) {
|
||||
return false;
|
||||
} elseif (empty($mappedData['EMAIL'])) {
|
||||
return false;
|
||||
} elseif (!isset($config['list_settings'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
if ($this->isAuthorized()) {
|
||||
$email = $mappedData['EMAIL'];
|
||||
unset($mappedData['EMAIL']);
|
||||
|
||||
$options = [];
|
||||
$options['status'] = $config['list_settings']['doubleOptin'] ? 'pending' : 'subscribed';
|
||||
$options['send_welcome'] = $config['list_settings']['sendWelcome'];
|
||||
$listId = $config['list_settings']['list'];
|
||||
|
||||
$this->getApiHelper()->subscribeLead($email, $listId, $mappedData, $options);
|
||||
|
||||
return true;
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$this->logIntegrationError($e);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function getFormSettings(): array
|
||||
{
|
||||
$settings = parent::getFormSettings();
|
||||
$settings['dynamic_contact_fields'] = true;
|
||||
|
||||
return $settings;
|
||||
}
|
||||
|
||||
public function getFormType(): string
|
||||
{
|
||||
return MailchimpType::class;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace MauticPlugin\MauticEmailMarketingBundle;
|
||||
|
||||
use Mautic\PluginBundle\Bundle\PluginBundleBase;
|
||||
|
||||
class MauticEmailMarketingBundle extends PluginBundleBase
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
# Mautic bundle for Email Marketing plugin
|
||||
|
||||
## This plugin is managed centrally in https://github.com/mautic/mautic/blob/head/plugins/MauticEmailMarketingBundle and this is a read-only mirror repository.
|
||||
|
||||
**📣 Please make PRs and issues against Mautic Core, not here!**
|
||||
@@ -0,0 +1,30 @@
|
||||
{% block emailmarketing_constantcontact_row %}
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
{{ form_row(form.list) }}
|
||||
</div>
|
||||
</div>
|
||||
{{ form_row(form.sendWelcome) }}
|
||||
{% endblock %}
|
||||
|
||||
{% block emailmarketing_icontact_row %}
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
{{ form_row(form.list) }}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block emailmarketing_mailchimp_row %}
|
||||
<div class="alert alert-info">
|
||||
{{ 'mautic.emailmarketing.list.update'|trans }}
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
{{ form_row(form.list) }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{ form_row(form.doubleOptin) }}
|
||||
{{ form_row(form.sendWelcome) }}
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,52 @@
|
||||
mautic.constantcontact.customfield1="Custom field 1"
|
||||
mautic.constantcontact.customfield2="Custom field 2"
|
||||
mautic.constantcontact.customfield3="Custom field 3"
|
||||
mautic.constantcontact.customfield4="Custom field 4"
|
||||
mautic.constantcontact.customfield5="Custom field 5"
|
||||
mautic.constantcontact.customfield6="Custom field 6"
|
||||
mautic.constantcontact.customfield7="Custom field 7"
|
||||
mautic.constantcontact.customfield8="Custom field 8"
|
||||
mautic.constantcontact.customfield9="Custom field 9"
|
||||
mautic.constantcontact.customfield10="Custom field 10"
|
||||
mautic.constantcontact.customfield11="Custom field 11"
|
||||
mautic.constantcontact.customfield12="Custom field 12"
|
||||
mautic.constantcontact.customfield13="Custom field 13"
|
||||
mautic.constantcontact.customfield14="Custom field 14"
|
||||
mautic.constantcontact.customfield15="Custom field 15"
|
||||
mautic.constantcontact.field.address_city="City"
|
||||
mautic.constantcontact.field.address_country_code="Country code (2 characters)"
|
||||
mautic.constantcontact.field.address_line1="Address line 1"
|
||||
mautic.constantcontact.field.address_line2="Address line 2"
|
||||
mautic.constantcontact.field.address_state="State"
|
||||
mautic.constantcontact.field.address_postal_code="Postal code"
|
||||
mautic.constantcontact.field.cell_phone="Cell phone"
|
||||
mautic.constantcontact.field.company_name="Company name"
|
||||
mautic.constantcontact.field.email="Email"
|
||||
mautic.constantcontact.field.fax="Fax"
|
||||
mautic.constantcontact.field.first_name="First name"
|
||||
mautic.constantcontact.field.home_phone="Home phone"
|
||||
mautic.constantcontact.field.job_title="Job title"
|
||||
mautic.constantcontact.field.last_name="Last name"
|
||||
mautic.constantcontact.field.prefix_name="Prefix name"
|
||||
mautic.constantcontact.field.work_phone="Work phone"
|
||||
mautic.icontact.field.business="Business phone"
|
||||
mautic.icontact.field.city="City"
|
||||
mautic.icontact.field.email="Email"
|
||||
mautic.icontact.field.fax="Fax"
|
||||
mautic.icontact.field.firstName="First name"
|
||||
mautic.icontact.field.lastName="Last name"
|
||||
mautic.icontact.field.phone="Phone"
|
||||
mautic.icontact.field.postalCode="Postal code"
|
||||
mautic.icontact.field.prefix="Prefix"
|
||||
mautic.icontact.field.street="Address line 1"
|
||||
mautic.icontact.field.street2="Address line 2"
|
||||
mautic.icontact.field.suffix="Suffix"
|
||||
mautic.icontact.field.state="State"
|
||||
mautic.icontact.keyfield.appid="App ID"
|
||||
mautic.icontact.keyfield.username="App username"
|
||||
mautic.icontact.keyfield.password="App API password"
|
||||
mautic.emailmarketing.list="List"
|
||||
mautic.emailmarketing.list.tooltip="Choose the list the lead should be added to."
|
||||
mautic.emailmarketing.list.update="The Lead Field Mapping tab will appear after selecting a list and will update after changing the selected list."
|
||||
mautic.emailmarketing.send_welcome="Send welcome email"
|
||||
mautic.mailchimp.double_optin="Enable double opt in"
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"name": "mautic/plugin-emailmarketing",
|
||||
"description": "Email Marketing Plugin",
|
||||
"type": "mautic-plugin",
|
||||
"keywords": [
|
||||
"mautic",
|
||||
"plugin",
|
||||
"integration"
|
||||
],
|
||||
"extra": {
|
||||
"install-directory-name": "MauticEmailMarketingBundle"
|
||||
},
|
||||
"minimum-stability": "dev",
|
||||
"require": {
|
||||
"mautic/core-lib": "^7.0"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user