Skip to content

Commit

Permalink
Add sendinblue integration (sulu#310)
Browse files Browse the repository at this point in the history
  • Loading branch information
luca-rath authored Jan 24, 2022
1 parent a3e1665 commit 3e68c0f
Show file tree
Hide file tree
Showing 15 changed files with 409 additions and 13 deletions.
3 changes: 0 additions & 3 deletions Command/FormGeneratorCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -267,9 +267,6 @@ private function loadTestForm(): ?Form
}
}

/**
* @return string
*/
private function getChoices(): string
{
return
Expand Down
1 change: 1 addition & 0 deletions DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public function getConfigTreeBuilder()
$rootNode = $treeBuilder->getRootNode();

$rootNode->children()
->scalarNode('sendinblue_api_key')->defaultValue(null)->end()
->scalarNode('mailchimp_api_key')->defaultValue(null)->end()
->scalarNode('mailchimp_subscribe_status')->defaultValue('subscribed')->end()
->enumNode('media_collection_strategy')
Expand Down
9 changes: 9 additions & 0 deletions DependencyInjection/SuluFormExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ public function load(array $configs, ContainerBuilder $container): void
$container->setParameter('sulu_form.ajax_templates', $config['ajax_templates']);
$container->setParameter('sulu_form.dynamic_widths', $config['dynamic_widths']);
$container->setParameter('sulu_form.dynamic_auto_title', $config['dynamic_auto_title']);
$container->setParameter('sulu_form.sendinblue_api_key', $config['sendinblue_api_key']);
$container->setParameter('sulu_form.mailchimp_api_key', $config['mailchimp_api_key']);
$container->setParameter('sulu_form.mailchimp_subscribe_status', $config['mailchimp_subscribe_status']);
$container->setParameter('sulu_form.dynamic_lists.config', $config['dynamic_lists']);
Expand Down Expand Up @@ -188,6 +189,14 @@ public function load(array $configs, ContainerBuilder $container): void
$loader->load('types.xml');
$loader->load('title-providers.xml');

if ($config['sendinblue_api_key']) {
if (!class_exists(\SendinBlue\Client\Configuration::class)) {
throw new \LogicException('You need to install the "sendinblue/api-v3-sdk" package to use the sendinblue type.');
}

$loader->load('type_sendinblue.xml');
}

if ($config['mailchimp_api_key']) {
if (!class_exists(\DrewM\MailChimp\MailChimp::class)) {
throw new \LogicException('You need to install the "drewm/mailchimp-api" package to use the mailchimp type.');
Expand Down
55 changes: 55 additions & 0 deletions Dynamic/Helper/SendinblueListSelect.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php

/*
* This file is part of Sulu.
*
* (c) Sulu GmbH
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/

namespace Sulu\Bundle\FormBundle\Dynamic\Helper;

use SendinBlue\Client\Api\ContactsApi;
use SendinBlue\Client\Configuration;

/**
* @final
* @internal
*/
class SendinblueListSelect
{
/**
* @var ContactsApi
*/
private $contactsApi;

public function __construct(?string $apiKey)
{
$config = new Configuration();
$config->setApiKey('api-key', $apiKey);

$this->contactsApi = new ContactsApi(null, $config);
}

/**
* Returns array of Sendinblue lists of given account defined by the API key.
*
* @return mixed[]
*/
public function getValues(): array
{
$lists = [];

$listObjects = $this->contactsApi->getLists()->getLists();
foreach ($listObjects as $list) {
$lists[] = [
'name' => $list['id'],
'title' => $list['name'],
];
}

return $lists;
}
}
59 changes: 59 additions & 0 deletions Dynamic/Helper/SendinblueMailTemplateSelect.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php

/*
* This file is part of Sulu.
*
* (c) Sulu GmbH
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/

namespace Sulu\Bundle\FormBundle\Dynamic\Helper;

use SendinBlue\Client\Api\TransactionalEmailsApi;
use SendinBlue\Client\Configuration;

/**
* @final
* @internal
*/
class SendinblueMailTemplateSelect
{
/**
* @var TransactionalEmailsApi
*/
private $transactionalEmailsApi;

public function __construct(?string $apiKey)
{
$config = new Configuration();
$config->setApiKey('api-key', $apiKey);

$this->transactionalEmailsApi = new TransactionalEmailsApi(null, $config);
}

/**
* Returns array of Sendinblue mail templates of given account defined by the API key.
*
* @return mixed[]
*/
public function getValues(): array
{
$mailTemplates = [];

$mailTemplateObjects = $this->transactionalEmailsApi->getSmtpTemplates('true')->getTemplates();
foreach ($mailTemplateObjects as $template) {
if (($template['tag'] ?? null) !== 'optin') {
continue;
}

$mailTemplates[] = [
'name' => $template['id'],
'title' => $template['name'],
];
}

return $mailTemplates;
}
}
53 changes: 53 additions & 0 deletions Dynamic/Types/SendinblueType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php

/*
* This file is part of Sulu.
*
* (c) Sulu GmbH
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/

namespace Sulu\Bundle\FormBundle\Dynamic\Types;

use Sulu\Bundle\FormBundle\Dynamic\FormFieldTypeConfiguration;
use Sulu\Bundle\FormBundle\Dynamic\FormFieldTypeInterface;
use Sulu\Bundle\FormBundle\Entity\FormField;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType as TypeCheckboxType;
use Symfony\Component\Form\FormBuilderInterface;

/**
* The Sendinblue form field type.
*/
class SendinblueType implements FormFieldTypeInterface
{
/**
* {@inheritdoc}
*/
public function getConfiguration(): FormFieldTypeConfiguration
{
return new FormFieldTypeConfiguration(
'sulu_form.type.sendinblue',
__DIR__ . '/../../Resources/config/form-fields/field_sendinblue.xml',
'special'
);
}

/**
* {@inheritdoc}
*/
public function build(FormBuilderInterface $builder, FormField $field, string $locale, array $options): void
{
$type = TypeCheckboxType::class;
$builder->add($field->getKey(), $type, $options);
}

/**
* {@inheritdoc}
*/
public function getDefaultValue(FormField $field, string $locale)
{
return $field->getTranslation($locale)->getDefaultValue();
}
}
114 changes: 114 additions & 0 deletions Event/SendinblueListSubscriber.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
<?php

/*
* This file is part of Sulu.
*
* (c) Sulu GmbH
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/

namespace Sulu\Bundle\FormBundle\Event;

use SendinBlue\Client\Api\ContactsApi;
use SendinBlue\Client\Configuration;
use SendinBlue\Client\Model\CreateDoiContact;
use Sulu\Bundle\FormBundle\Entity\Dynamic;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RequestStack;

/**
* @final
* @internal
*/
class SendinblueListSubscriber implements EventSubscriberInterface
{
/**
* @var RequestStack
*/
private $requestStack;

/**
* @var ContactsApi
*/
private $contactsApi;

public function __construct(RequestStack $requestStack, ?string $apiKey)
{
$this->requestStack = $requestStack;

$config = new Configuration();
$config->setApiKey('api-key', $apiKey);

$this->contactsApi = new ContactsApi(null, $config);
}

/**
* {@inheritdoc}
*/
public static function getSubscribedEvents()
{
return [
FormSavePostEvent::NAME => 'listSubscribe',
];
}

public function listSubscribe(FormSavePostEvent $event): void
{
$dynamic = $event->getData();
$request = $this->requestStack->getCurrentRequest();

if (!$dynamic instanceof Dynamic) {
return;
}

if (!$request) {
return;
}

$form = $dynamic->getForm()->serializeForLocale($dynamic->getLocale(), $dynamic);

$email = '';
$firstName = '';
$lastName = '';
$redirectionUrl = $request->getUriForPath('') . '?subscribe=true';
$listIdsByMailTemplate = [];

foreach ($form['fields'] as $field) {
if ('firstName' === $field['type'] && !$firstName) {
$firstName = $field['value'];
} elseif ('lastName' === $field['type'] && !$lastName) {
$lastName = $field['value'];
} elseif ('email' === $field['type'] && !$email) {
$email = $field['value'];
} elseif ('sendinblue' == $field['type'] && $field['value']) {
$mailTemplateId = $field['options']['mailTemplateId'] ?? null;
$listId = $field['options']['listId'] ?? null;

if (!$mailTemplateId || !$listId) {
continue;
}

$listIdsByMailTemplate[$mailTemplateId][] = $listId;
}
}

if ($email && count($listIdsByMailTemplate) > 0) {
foreach ($listIdsByMailTemplate as $mailTemplateId => $listIds) {
$createDoiContact = new CreateDoiContact([
'email' => $email,
'templateId' => $mailTemplateId,
'includeListIds' => $listIds,
'redirectionUrl' => $redirectionUrl,
'attributes' => [
'FIRST_NAME' => $firstName,
'LAST_NAME' => $firstName,
],
]);

$this->contactsApi->createDoiContact($createDoiContact);
}
}
}
}
1 change: 0 additions & 1 deletion Repository/FormRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
use Sulu\Bundle\FormBundle\Entity\Form;

/**
*
* @template-extends EntityRepository<Form>
*/
class FormRepository extends EntityRepository
Expand Down
31 changes: 31 additions & 0 deletions Resources/config/form-fields/field_sendinblue.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<properties xmlns="http://schemas.sulu.io/template/template"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xi="http://www.w3.org/2001/XInclude"
xsi:schemaLocation="http://schemas.sulu.io/template/template http://schemas.sulu.io/template/properties-1.0.xsd">
<xi:include href="default_field.xml" xpointer="xmlns(sulu=http://schemas.sulu.io/template/template)
xpointer(//sulu:property)"/>
<property name="options/listId" type="single_select" mandatory="true">
<meta>
<title>sulu_form.sendinblue_list</title>
</meta>
<params>
<param
name="values"
type="expression"
value="service('sulu_form.dynamic.sendinblue_list_select').getValues()"
/>
</params>
</property>
<property name="options/mailTemplateId" type="single_select" mandatory="true">
<meta>
<title>sulu_form.sendinblue_mail_template</title>
</meta>
<params>
<param
name="values"
type="expression"
value="service('sulu_form.dynamic.sendinblue_mail_template_select').getValues()"
/>
</params>
</property>
</properties>
25 changes: 25 additions & 0 deletions Resources/config/type_sendinblue.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?xml version="1.0" ?>

<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<services>
<service id="sulu_form.subscriber.sendinblue_list_subscriber" class="Sulu\Bundle\FormBundle\Event\SendinblueListSubscriber">
<argument type="service" id="request_stack"/>
<argument>%sulu_form.sendinblue_api_key%</argument>
<tag name="kernel.event_subscriber" />
</service>

<service id="sulu_form.dynamic.type_sendinblue" class="Sulu\Bundle\FormBundle\Dynamic\Types\SendinblueType">
<tag name="sulu_form.dynamic.type" alias="sendinblue"/>
</service>

<service id="sulu_form.dynamic.sendinblue_list_select" class="Sulu\Bundle\FormBundle\Dynamic\Helper\SendinblueListSelect" public="true">
<argument>%sulu_form.sendinblue_api_key%</argument>
</service>

<service id="sulu_form.dynamic.sendinblue_mail_template_select" class="Sulu\Bundle\FormBundle\Dynamic\Helper\SendinblueMailTemplateSelect" public="true">
<argument>%sulu_form.sendinblue_api_key%</argument>
</service>
</services>
</container>
1 change: 1 addition & 0 deletions Resources/doc/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ Make sure you've set the correct permissions in the Sulu backend for this bundle
## Additional form fields

- [Mailchimp](mailchimp.md "Mailchimp Form Field")
- [Sendinblue](sendinblue.md "Sendinblue Form Field")
- [Recaptcha](recaptcha.md "Recaptcha Form Field")
- [Dropzone](dropzone.md "Dropzone Form Field")

Expand Down
Loading

0 comments on commit 3e68c0f

Please sign in to comment.