diff --git a/Classes/ApiWrapper.php b/Classes/ApiWrapper.php index 5fcb285..236c088 100644 --- a/Classes/ApiWrapper.php +++ b/Classes/ApiWrapper.php @@ -12,7 +12,7 @@ * of the License, or any later version. */ -use SendinBlue\Client\Configuration; +use Brevo\Client\Configuration; use StudioMitte\Sendinblue\Configuration as ExtensionConfiguration; /** diff --git a/Classes/Command/TestCommand.php b/Classes/Command/TestCommand.php index 526dc6f..7ea6c66 100644 --- a/Classes/Command/TestCommand.php +++ b/Classes/Command/TestCommand.php @@ -12,7 +12,7 @@ * of the License, or any later version. */ -use SendinBlue\Client\Api\ContactsApi; +use Brevo\Client\Api\ContactsApi; use StudioMitte\Sendinblue\ApiWrapper; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; diff --git a/Classes/Finishers/SendinblueFinisher.php b/Classes/Finishers/SendinblueFinisher.php index bdbd783..0a0c0cd 100644 --- a/Classes/Finishers/SendinblueFinisher.php +++ b/Classes/Finishers/SendinblueFinisher.php @@ -14,9 +14,9 @@ use Psr\Log\LoggerAwareInterface; use Psr\Log\LoggerAwareTrait; -use SendinBlue\Client\Api\ContactsApi; -use SendinBlue\Client\Model\CreateContact; -use SendinBlue\Client\Model\CreateDoiContact; +use Brevo\Client\Api\ContactsApi; +use Brevo\Client\Model\CreateContact; +use Brevo\Client\Model\CreateDoiContact; use StudioMitte\Sendinblue\ApiWrapper; use StudioMitte\Sendinblue\Configuration; use TYPO3\CMS\Core\Utility\GeneralUtility; @@ -30,36 +30,33 @@ class SendinblueFinisher extends AbstractFinisher implements LoggerAwareInterfac use LoggerAwareTrait; /** @var Configuration */ - protected $extensionConfiguration; + protected Configuration $extensionConfiguration; public function __construct(string $finisherIdentifier = '') { - parent::__construct($finisherIdentifier); $this->extensionConfiguration = new Configuration(); } - protected function executeInternal() + protected function executeInternal(): void { if (!$this->newsletterSubscriptionIsEnabled()) { - $this->finisherContext->getFinisherVariableProvider()->add( - 'sendinblue', - 'subsribed', - 0 - ); - return null; + $this->setFinisherSubscribedVariable(0); + return; } - $this->addEntryToSendInBlue(); + $this->addEntryToSendInBlue() ? $this->setFinisherSubscribedVariable(1) : $this->setFinisherSubscribedVariable(0); + } + + protected function setFinisherSubscribedVariable(int $returnValue): void + { $this->finisherContext->getFinisherVariableProvider()->add( 'sendinblue', 'data.subscribed', - 1 + $returnValue ); - - return null; } - protected function addEntryToSendInBlue(): void + protected function addEntryToSendInBlue(): bool { try { $apiInstance = $this->getApi(); @@ -81,9 +78,11 @@ protected function addEntryToSendInBlue(): void ->setAttributes($this->getAttributes()); $apiInstance->createContact($createContact); } + return true; } catch (\Exception $exception) { // todo: should we forward it to the user? $this->logger->error($exception->getMessage()); + return false; } } @@ -96,9 +95,18 @@ protected function getDoiTemplateId(): int return $this->extensionConfiguration->getDoiTemplateId(); } + protected function getDoiRedirectPageId(): int + { + $doiRedirectPageId = (int)$this->parseOption('doiRedirectPageId'); + if ($doiRedirectPageId) { + return $doiRedirectPageId; + } + return $this->extensionConfiguration->getDoiRedirectPageId(); + } + protected function newsletterSubscriptionIsEnabled(): bool { - return (bool)$this->parseOption('enabled'); + return $this->isEnabled(); } protected function getEnrichedListIds(): array @@ -142,13 +150,19 @@ protected function getAttributes(): object if ($trackingAttribute = $this->extensionConfiguration->getAttributeTracking()) { $attributes[$trackingAttribute] = $this->parseOption('tracking'); } + + // additional attribute mappings + $additionalAttributes = $this->parseOption('additionalAttributes'); + foreach ($additionalAttributes as $key => $value) { + $attributes[$key] = $value; + } return (object)$attributes; } protected function getRedirectionUrl(): string { $typolinkConfiguration = [ - 'parameter' => $this->extensionConfiguration->getDoiRedirectPageId(), + 'parameter' => $this->getDoiRedirectPageId(), 'forceAbsoluteUrl' => true, ]; return $this->getTypoScriptFrontendController()->cObj->typoLink_URL($typolinkConfiguration); diff --git a/Classes/Report/IntegrationReport.php b/Classes/Report/IntegrationReport.php index a9cf42e..cb1bf9e 100644 --- a/Classes/Report/IntegrationReport.php +++ b/Classes/Report/IntegrationReport.php @@ -12,11 +12,11 @@ * of the License, or any later version. */ -use SendinBlue\Client\Api\AccountApi; -use SendinBlue\Client\Api\ContactsApi; -use SendinBlue\Client\Api\TransactionalEmailsApi; -use SendinBlue\Client\ApiException; -use SendinBlue\Client\Model\GetAccount; +use Brevo\Client\Api\AccountApi; +use Brevo\Client\Api\ContactsApi; +use Brevo\Client\Api\TransactionalEmailsApi; +use Brevo\Client\ApiException; +use Brevo\Client\Model\GetAccount; use StudioMitte\Sendinblue\ApiWrapper; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Extbase\Mvc\Exception\InvalidExtensionNameException; @@ -36,11 +36,10 @@ class IntegrationReport implements ReportInterface * @throws ApiException * @throws InvalidExtensionNameException */ - public function getReport() + public function getReport(): string { // Rendering of the output via fluid $view = GeneralUtility::makeInstance(StandaloneView::class); - $view->getRequest()->setControllerExtensionName('Sendinblue'); $view->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName( 'EXT:sendinblue/Resources/Private/Templates/IntegrationReport.html' )); @@ -91,4 +90,24 @@ protected function getAccountInformation(): GetAccount $api = new AccountApi(null, ApiWrapper::getConfig()); return $api->getAccount(); } + + public function getIdentifier(): string + { + return 'general'; + } + + public function getTitle(): string + { + return 'LLL:EXT:sendinblue/Resources/Private/Language/locallang_report.xlf:report.title'; + } + + public function getDescription(): string + { + return 'LLL:EXT:sendinblue/Resources/Private/Language/locallang_report.xlf:report.description'; + } + + public function getIconIdentifier(): string + { + return 'module-reports'; + } } diff --git a/Configuration/Services.yaml b/Configuration/Services.yaml index f09076a..baaeea8 100644 --- a/Configuration/Services.yaml +++ b/Configuration/Services.yaml @@ -9,3 +9,7 @@ services: - name: 'console.command' command: 'sendinblue:test' schedulable: false + + StudioMitte\Sendinblue\Report\IntegrationReport: + tags: + - name: reports.report diff --git a/Configuration/Yaml/SendinblueBackend.yaml b/Configuration/Yaml/FormSetup.yaml similarity index 87% rename from Configuration/Yaml/SendinblueBackend.yaml rename to Configuration/Yaml/FormSetup.yaml index 0ab3ab6..363752b 100644 --- a/Configuration/Yaml/SendinblueBackend.yaml +++ b/Configuration/Yaml/FormSetup.yaml @@ -3,26 +3,28 @@ TYPO3: Form: prototypes: standard: + formEditor: + translationFiles: + 1483353712: 'EXT:sendinblue/Resources/Private/Language/Form.xlf' formElementsDefinition: Form: formEditor: editors: 900: - # Extend finisher drop down selectOptions: - 35: + 1483353712: value: 'Sendinblue' label: 'finisher.Sendinblue.label' propertyCollections: finishers: # add finisher fields - 25: + 1483353712: identifier: 'Sendinblue' editors: - __inheritances: - 10: 'TYPO3.CMS.Form.mixins.formElementMixins.BaseCollectionEditorsMixin' 100: + identifier: header label: 'finisher.Sendinblue.label' + templateName: 'Inspector-CollectionElementHeaderEditor' 110: identifier: 'enabled' templateName: 'Inspector-TextEditor' @@ -48,7 +50,6 @@ TYPO3: propertyPath: 'options.firstName' enableFormelementSelectionButton: true propertyValidators: - 10: 'NotEmpty' 20: 'FormElementIdentifierWithinCurlyBracesInclusive' 131: identifier: 'lastName' @@ -57,7 +58,6 @@ TYPO3: propertyPath: 'options.lastName' enableFormelementSelectionButton: true propertyValidators: - 10: 'NotEmpty' 20: 'FormElementIdentifierWithinCurlyBracesInclusive' 135: identifier: 'additionalListIds' @@ -72,11 +72,15 @@ TYPO3: templateName: 'Inspector-TextEditor' label: 'finisher.Sendinblue.field.tracking' propertyPath: 'options.tracking' + 9999: + identifier: 'removeButton' + templateName: 'Inspector-RemoveElementEditor' finishersDefinition: Sendinblue: + implementationClassName: 'StudioMitte\Sendinblue\Finishers\SendinblueFinisher' formEditor: iconIdentifier: 'form-finisher' - label: 'Sendinblue Finisher' + label: 'finisher.Sendinblue.label' predefinedDefaults: options: enabled: '' @@ -85,7 +89,7 @@ TYPO3: email: '' additionalListIds: '' tracking: 'trackingvalue' - # displayed when overriding finisher settings + # displayed when overriding finisher settings FormEngine: label: 'finisher.Sendinblue.label' elements: @@ -104,7 +108,7 @@ TYPO3: firstName: label: 'finisher.Sendinblue.field.firstName' config: - type: 'text' + type: 'text' lastName: label: 'finisher.Sendinblue.field.lastName' config: @@ -113,8 +117,3 @@ TYPO3: label: 'finisher.Sendinblue.field.additionalListIds' config: type: 'text' - formEditor: - translationFile: - 91818: 'EXT:sendinblue/Resources/Private/Language/Form.xlf' - translationFiles: - 91818: 'EXT:sendinblue/Resources/Private/Language/Form.xlf' diff --git a/Configuration/Yaml/SendinblueFrontend.yaml b/Configuration/Yaml/SendinblueFrontend.yaml deleted file mode 100644 index 46211c5..0000000 --- a/Configuration/Yaml/SendinblueFrontend.yaml +++ /dev/null @@ -1,8 +0,0 @@ -TYPO3: - CMS: - Form: - prototypes: - standard: - finishersDefinition: - Sendinblue: - implementationClassName: 'StudioMitte\Sendinblue\Finishers\SendinblueFinisher' diff --git a/Resources/Private/Example/sendinblue-example.form.yaml b/Resources/Private/Example/sendinblue-example.form.yaml index c72617e..474afe7 100644 --- a/Resources/Private/Example/sendinblue-example.form.yaml +++ b/Resources/Private/Example/sendinblue-example.form.yaml @@ -7,13 +7,16 @@ label: sendinblue prototypeName: standard finishers: - - options: + renderingOptions: enabled: '{checkbox-1}' + options: firstName: '{text-1}' lastName: '{text-3}' email: '{text-2}' tracking: trackingvalue additionalListIds: '{multicheckbox-1}' + additionalAttributes: + salutation: '{salutation}' # override global settings # doiTemplateId: '14' @@ -33,6 +36,14 @@ renderables: identifier: page-1 label: Step renderables: + - + properties: + options: + '1': 'Mr.' + '2': 'Mrs.' + type: SingleSelect + identifier: salutation + label: Salutation - defaultValue: '' type: Text @@ -40,22 +51,11 @@ renderables: label: Vorname properties: elementDescription: '' - fluidAdditionalAttributes: - required: required - validators: - - - identifier: NotEmpty - defaultValue: '' type: Text identifier: text-3 label: Nachname - properties: - fluidAdditionalAttributes: - required: required - validators: - - - identifier: NotEmpty - defaultValue: '' type: Text diff --git a/Resources/Private/Language/locallang_report.xlf b/Resources/Private/Language/locallang_report.xlf index 7f1725c..bd2b2dc 100644 --- a/Resources/Private/Language/locallang_report.xlf +++ b/Resources/Private/Language/locallang_report.xlf @@ -14,7 +14,7 @@ Contacts - + Lists @@ -26,6 +26,9 @@ Total Subscriber + + Unique Subscriber + Total Blacklisted @@ -73,4 +76,4 @@ - \ No newline at end of file + diff --git a/Resources/Private/Templates/IntegrationReport.html b/Resources/Private/Templates/IntegrationReport.html index ea86d4a..750ca0b 100644 --- a/Resources/Private/Templates/IntegrationReport.html +++ b/Resources/Private/Templates/IntegrationReport.html @@ -3,86 +3,91 @@

{f:translate(key:'{lll}report.title')}

{f:translate(key:'{lll}report.description')}

- -

{f:translate(key:'{lll}account')}

+

{f:translate(key:'{lll}account')}

{account}

{f:translate(key:'{lll}contacts')}

{f:translate(key:'{lll}contacts.lists')}
- - - - - - - - - - - +
+
{f:translate(key:'{lll}contacts.attribute.id')}{f:translate(key:'{lll}contacts.attribute.name')}{f:translate(key:'{lll}contacts.attribute.totalSubscriber')}Total Subscriber{f:translate(key:'{lll}contacts.attribute.totalBlacklisted')}Total Blacklisted
+ - - - - + + + + - - -
{list.id}{list.name}{list.totalSubscribers}{list.totalBlacklisted}{f:translate(key:'{lll}contacts.attribute.id')}{f:translate(key:'{lll}contacts.attribute.name')}{f:translate(key:'{lll}contacts.attribute.uniqueSubscribers')}{f:translate(key:'{lll}contacts.attribute.totalBlacklisted')}
+ + + + + {list.id} + {list.name} + {list.uniqueSubscribers} + {list.totalBlacklisted} + + + + +
{f:translate(key:'{lll}attributes')}
- - - - - - - - - - - +
+
{f:translate(key:'{lll}attributes.attribute.name')}{f:translate(key:'{lll}attributes.attribute.type')}{f:translate(key:'{lll}attributes.attribute.category')}{f:translate(key:'{lll}attributes.attribute.info')}
+ - - - - + + + + - - -
{attribute.name}{attribute.type}{attribute.category} - - {f:translate(key:'{lll}attributes.attribute.calculatedValue')}: {attribute.calculatedValue} - - {f:translate(key:'{lll}attributes.attribute.name')}{f:translate(key:'{lll}attributes.attribute.type')}{f:translate(key:'{lll}attributes.attribute.category')}{f:translate(key:'{lll}attributes.attribute.info')}
+ + + + + {attribute.name} + {attribute.type} + {attribute.category} + + + {f:translate(key:'{lll}attributes.attribute.calculatedValue')}: {attribute.calculatedValue} + + + + + + +

{f:translate(key:'{lll}templates')}

- - - - - - - - - - - - - - +
+
{f:translate(key:'{lll}templates.attribute.id')}{f:translate(key:'{lll}templates.attribute.name')}{f:translate(key:'{lll}templates.attribute.active')}{f:translate(key:'{lll}templates.attribute.testSent')}{f:translate(key:'{lll}templates.attribute.sender')}{f:translate(key:'{lll}templates.attribute.createdAt')}{f:translate(key:'{lll}templates.attribute.modifiedAt')}
+ - - - - - - - + + + + + + + - - -
{template.id}{template.name}{template.sender.name} ({template.sender.email}) [{template.sender.id}]{template.createdAt -> f:format.date()}{template.modifiedAt -> f:format.date()}{f:translate(key:'{lll}templates.attribute.id')}{f:translate(key:'{lll}templates.attribute.name')}{f:translate(key:'{lll}templates.attribute.active')}{f:translate(key:'{lll}templates.attribute.testSent')}{f:translate(key:'{lll}templates.attribute.sender')}{f:translate(key:'{lll}templates.attribute.createdAt')}{f:translate(key:'{lll}templates.attribute.modifiedAt')}
+ + + + + {template.id} + {template.name} + + + {template.sender.name} ({template.sender.email}) [{template.sender.id}] + {template.createdAt -> f:format.date()} + {template.modifiedAt -> f:format.date()} + + + + + diff --git a/composer.json b/composer.json index a93d32c..30fc18a 100644 --- a/composer.json +++ b/composer.json @@ -17,9 +17,9 @@ "GPL-2.0-or-later" ], "require": { - "typo3/cms-core": "^10.4", - "typo3/cms-form": "^10.4", - "sendinblue/api-v3-sdk": "^7.3" + "typo3/cms-core": "^11.5||^12.4", + "typo3/cms-form": "^11.5||^12.4", + "getbrevo/brevo-php": "^1" }, "require-dev": { "typo3/testing-framework": "^6.4", diff --git a/ext_emconf.php b/ext_emconf.php index 28c14cf..3d7d4db 100644 --- a/ext_emconf.php +++ b/ext_emconf.php @@ -12,7 +12,7 @@ 'version' => '1.1.0', 'constraints' => [ 'depends' => [ - 'typo3' => '10.4.0-10.4.99', + 'typo3' => '11.5.0-12.4.99', ], 'conflicts' => [], 'suggests' => [], diff --git a/ext_localconf.php b/ext_localconf.php index 9e7e955..0270f17 100644 --- a/ext_localconf.php +++ b/ext_localconf.php @@ -1,32 +1,10 @@ 'LLL:EXT:sendinblue/Resources/Private/Language/locallang_report.xlf:report.title', 'description' => 'LLL:EXT:sendinblue/Resources/Private/Language/locallang_report.xlf:report.description', diff --git a/ext_typoscript_setup.typoscript b/ext_typoscript_setup.typoscript new file mode 100644 index 0000000..424c6f9 --- /dev/null +++ b/ext_typoscript_setup.typoscript @@ -0,0 +1,15 @@ +module.tx_form { + settings { + yamlConfigurations { + 1483353712 = EXT:sendinblue/Configuration/Yaml/FormSetup.yaml + } + } +} + +plugin.tx_form { + settings { + yamlConfigurations { + 1483353712 = EXT:sendinblue/Configuration/Yaml/FormSetup.yaml + } + } +}