diff --git a/src/Controllers/ChimpleController.php b/src/Controllers/ChimpleController.php
index 09c9b9f..46b5e8c 100644
--- a/src/Controllers/ChimpleController.php
+++ b/src/Controllers/ChimpleController.php
@@ -31,20 +31,11 @@
*/
class ChimpleController extends PageController
{
- /**
- * @var string
- */
- private static $url_segment = 'mc-subscribe/v1';
+ private static string $url_segment = 'mc-subscribe/v1';
- /**
- * @var bool
- */
- private static $hide_generic_form = true;
+ private static bool $hide_generic_form = true;
- /**
- * @var array
- */
- private static $allowed_actions = [
+ private static array $allowed_actions = [
'SubscribeForm',
'XhrSubscribeForm'
];
@@ -66,14 +57,11 @@ public function index()
public function pageTitle($complete = null)
{
- switch($complete) {
- case 'y':
- return _t(__CLASS__. '.DEFAULT_TITLE_SUCCESSFUL', 'Thanks for subscribing');
- case 'n':
- return _t(__CLASS__. '.DEFAULT_TITLE_NOT_SUCCESSFUL', 'Sorry, there was an error');
- default:
- return _t(__CLASS__. '.DEFAULT_TITLE', 'Subscribe');
- }
+ return match ($complete) {
+ 'y' => _t(self::class. '.DEFAULT_TITLE_SUCCESSFUL', 'Thanks for subscribing'),
+ 'n' => _t(self::class. '.DEFAULT_TITLE_NOT_SUCCESSFUL', 'Sorry, there was an error'),
+ default => _t(self::class. '.DEFAULT_TITLE', 'Subscribe'),
+ };
}
public function Link($action = null)
@@ -120,11 +108,8 @@ public function setFormNameSuffix(string $suffix = ''): self
*/
public function getFormNameSuffix(): string
{
- if($this->formNameSuffix) {
- $suffix = "_{$this->formNameSuffix}";
- } else {
- $suffix = "";
- }
+ $suffix = $this->formNameSuffix ? "_{$this->formNameSuffix}" : "";
+
return $suffix;
}
@@ -133,11 +118,8 @@ public function getFormNameSuffix(): string
*/
public function getSubscriptionForm($useXhr = false): ?SubscribeForm
{
- if($useXhr) {
- $form = $this->XhrSubscribeForm();
- } else {
- $form = $this->SubscribeForm();
- }
+ $form = $useXhr ? $this->XhrSubscribeForm() : $this->SubscribeForm();
+
return $form;
}
@@ -230,17 +212,16 @@ protected function configureForm(SubscribeForm $form): SubscribeForm
*/
protected function getFields(): FieldList
{
- $fields = FieldList::create(
- $name = TextField::create('Name', _t(__CLASS__. '.NAME', 'Name'))
- ->setAttribute('placeholder', _t(__CLASS__. '.YOUR_NAME', 'Your name'))
- ->setAttribute('title', _t(__CLASS__. '.NAME', 'Name'))
+ return FieldList::create(
+ $name = TextField::create('Name', _t(self::class. '.NAME', 'Name'))
+ ->setAttribute('placeholder', _t(self::class. '.YOUR_NAME', 'Your name'))
+ ->setAttribute('title', _t(self::class. '.NAME', 'Name'))
->setAttribute('required', 'required'),
- $email = EmailField::create('Email', _t(__CLASS__. '.EMAIL', 'Email'))
- ->setAttribute('placeholder', _t(__CLASS__. '.EMAIL_ADDRESS', 'Email address'))
- ->setAttribute('title', _t(__CLASS__. '.EMAIL', 'Email'))
+ $email = EmailField::create('Email', _t(self::class. '.EMAIL', 'Email'))
+ ->setAttribute('placeholder', _t(self::class. '.EMAIL_ADDRESS', 'Email address'))
+ ->setAttribute('title', _t(self::class. '.EMAIL', 'Email'))
->setAttribute('required', 'required')
);
- return $fields;
}
/**
@@ -248,14 +229,13 @@ protected function getFields(): FieldList
*/
protected function getActions(): FieldList
{
- $actions = FieldList::create(
+ return FieldList::create(
FormAction::create(
'subscribe',
- _t(__CLASS__ . '.SUBSCRIBE', 'Subscribe')
+ _t(self::class . '.SUBSCRIBE', 'Subscribe')
)->setUseButtonTag(true)
->addExtraClass('signup')
);
- return $actions;
}
/**
@@ -271,14 +251,13 @@ protected function getValidator(): ?Validator
* Returns the validation callback upon errors
* A response is returned only upon errors in XHR submissions
* See FormRequestHandler::getValidationErrorResponse();
- * @return callable
*/
protected function getCallbackForXhrValidation(): callable
{
return function (ValidationResult $result) {
// Fail, using the first message returned from the validation result
$messages = $result->getMessages();
- $message = (!empty($messages[0]['message']) ? $messages[0]['message'] : '');
+ $message = (empty($messages[0]['message']) ? '' : $messages[0]['message']);
return $this->xhrError(400, $message);
};
}
@@ -308,26 +287,26 @@ private function handleError($code, $error_message, Form $form = null)
{
if($this->request->isAjax()) {
return $this->xhrError($code, $error_message);
- } elseif($form) {
+ } elseif($form instanceof \SilverStripe\Forms\Form) {
// set session error on the form
$form->sessionError($error_message, ValidationResult::TYPE_ERROR);
}
- return;
+ return null;
}
/**
* Handle successful submissions, based on the request type
*/
- private function handleSuccess($code, $message, Form $form = null)
+ private function handleSuccess(int $code, Form $form = null)
{
$success_message = Config::inst()->get(MailchimpConfig::class, 'success_message');
if($this->request->isAjax()) {
- return $this->xhrSuccess($code, $message, $success_message);
- } elseif($form) {
+ return $this->xhrSuccess($code, $success_message);
+ } elseif($form instanceof \SilverStripe\Forms\Form) {
// set session message on the form
$form->sessionMessage($success_message, ValidationResult::TYPE_GOOD);
}
- return;
+ return null;
}
/**
@@ -342,7 +321,7 @@ public function subscribe($data = [], Form $form = null)
$code = "";// MailchimpConfig.Code
$list_id = "";
- if(!$form) {
+ if(!$form instanceof \SilverStripe\Forms\Form) {
throw new RequestException("Forbidden", 403);
}
@@ -351,14 +330,14 @@ public function subscribe($data = [], Form $form = null)
if(empty($data['code'])) {
// fail with error
$error_message = _t(
- __CLASS__ . '.NO_CODE',
+ self::class . '.NO_CODE',
"No code was provided"
);
$error_code = 400;// default to invalid data
} else {
- $code = strip_tags(trim($data['code'] ?: ''));
+ $code = strip_tags(trim((string) ($data['code'] ?: '')));
$error_message = "";
$error_code = 400;// default to invalid data
$mc_config = null;
@@ -368,7 +347,7 @@ public function subscribe($data = [], Form $form = null)
$enabled = MailchimpConfig::isEnabled();
if(!$enabled) {
$error_message = _t(
- __CLASS__ . '.SUBSCRIPTIONS_NOT_AVAILABLE',
+ self::class . '.SUBSCRIPTIONS_NOT_AVAILABLE',
"Subscriptions are not available at the moment"
);
}
@@ -378,16 +357,17 @@ public function subscribe($data = [], Form $form = null)
if (empty($data['Email'])) {
// fail with error
$error_message = _t(
- __CLASS__ . '.NO_EMAIL_ADDRESS',
+ self::class . '.NO_EMAIL_ADDRESS',
"No e-mail address was provided"
);
}
+
if (!Email::is_valid_address($data['Email'])) {
$error_message = _t(
- __CLASS__ . '.INVALID_EMAIL_ADDRESS',
+ self::class . '.INVALID_EMAIL_ADDRESS',
"Please provide a valid e-mail address, '{email}' is not valid",
[
- 'email' => htmlspecialchars($data['Email'])
+ 'email' => htmlspecialchars((string) $data['Email'])
]
);
}
@@ -395,26 +375,27 @@ public function subscribe($data = [], Form $form = null)
if (!$error_message) {
// check code provided
- if (!$code) {
+ if ($code === '' || $code === '0') {
$error_message = _t(
- __CLASS__ . ".GENERIC_ERROR_1",
+ self::class . ".GENERIC_ERROR_1",
"Sorry, the sign-up could not be completed"
);
} else {
$mc_config = MailchimpConfig::getConfig('', '', $code);
if (empty($mc_config->ID)) {
$error_message = _t(
- __CLASS__ . ".GENERIC_ERROR_2",
+ self::class . ".GENERIC_ERROR_2",
"Sorry, the sign-up could not be completed"
);
}
+
$list_id = $mc_config->getMailchimpListId();
}
}
if (!$list_id) {
$error_message = _t(
- __CLASS__ . ".GENERIC_ERROR_3",
+ self::class . ".GENERIC_ERROR_3",
"Sorry, the sign-up could not be completed"
);
}
@@ -457,7 +438,7 @@ public function subscribe($data = [], Form $form = null)
}
// handle a successful subscription
- $response = $this->handleSuccess(200, "OK", $form);
+ $response = $this->handleSuccess(200, $form);
if($response && ($response instanceof HTTPResponse)) {
// handle responses for e.g XHR
return $response;
@@ -473,7 +454,7 @@ public function subscribe($data = [], Form $form = null)
} catch (RequestException $e) {
$error_message = $e->getMessage();
$error_code = $e->getCode();
- } catch (\Exception $e) {
+ } catch (\Exception) {
// general exceptin
$error_message = Config::inst()->get(MailchimpConfig::class, 'error_message');
$error_code = 500;
@@ -497,11 +478,10 @@ public function subscribe($data = [], Form $form = null)
/**
* Return error response for XHR
- * @return HTTPResponse
*/
- private function xhrError($code = 500, $message = "", $description = "")
+ private function xhrError($code = 500, $message = ""): \SilverStripe\Control\HTTPResponse
{
- $response = new HTTPResponse();
+ $response = \SilverStripe\Control\HTTPResponse::create();
$response->setStatusCode($code);
$response->addHeader('Content-Type', 'application/json');
$response->addHeader('X-Submission-OK', '0');
@@ -511,11 +491,10 @@ private function xhrError($code = 500, $message = "", $description = "")
/**
* Return success response for XHR
- * @return HTTPResponse
*/
- private function xhrSuccess($code = 200, $message = "", $description = "")
+ private function xhrSuccess(int $code = 200, $description = ""): \SilverStripe\Control\HTTPResponse
{
- $response = new HTTPResponse();
+ $response = \SilverStripe\Control\HTTPResponse::create();
$response->setStatusCode($code);
$response->addHeader('Content-Type', 'application/json');
$response->addHeader('X-Submission-OK', '1');
diff --git a/src/Controllers/MailchimpAdmin.php b/src/Controllers/MailchimpAdmin.php
index 8d40dc6..3f65815 100644
--- a/src/Controllers/MailchimpAdmin.php
+++ b/src/Controllers/MailchimpAdmin.php
@@ -13,12 +13,12 @@
*/
class MailchimpAdmin extends ModelAdmin
{
- private static $managed_models = [
+ private static array $managed_models = [
MailchimpSubscriber::class,
MailchimpConfig::class
];
- private static $menu_title = 'Mailchimp';
+ private static string $menu_title = 'Mailchimp';
- private static $url_segment = 'mailchimp';
+ private static string $url_segment = 'mailchimp';
}
diff --git a/src/Extensions/DisableSecurityTokenExtension.php b/src/Extensions/DisableSecurityTokenExtension.php
index 2321f1b..eb4bc68 100644
--- a/src/Extensions/DisableSecurityTokenExtension.php
+++ b/src/Extensions/DisableSecurityTokenExtension.php
@@ -14,6 +14,6 @@ class DisableSecurityTokenExtension extends Extension
{
public function updateChimpleSubscribeForm()
{
- $this->owner->disableSecurityToken();
+ $this->getOwner()->disableSecurityToken();
}
}
diff --git a/src/Extensions/PageExtension.php b/src/Extensions/PageExtension.php
index 562e465..fa7c50d 100644
--- a/src/Extensions/PageExtension.php
+++ b/src/Extensions/PageExtension.php
@@ -20,6 +20,7 @@ public function ChimpleGlobalSubscribeForm()
if ($config) {
return $config->SubscribeForm();
}
+
return null;
}
@@ -34,6 +35,7 @@ public function ChimpleSubscribeForm($config_code)
if($config) {
return $config->SubscribeForm();
}
+
return null;
}
}
diff --git a/src/Extensions/SiteConfigExtension.php b/src/Extensions/SiteConfigExtension.php
index d014b12..64b9d3b 100644
--- a/src/Extensions/SiteConfigExtension.php
+++ b/src/Extensions/SiteConfigExtension.php
@@ -11,14 +11,15 @@
class SiteConfigExtension extends DataExtension
{
- private static $db = [
+ private static array $db = [
'MailchimpEnabled' => 'Boolean'
];
- private static $has_one = [
+ private static array $has_one = [
'MailchimpConfig' => MailchimpConfig::class // global element for configuration
];
+ #[\Override]
public function updateCmsFields(FieldList $fields)
{
$fields->addFieldsToTab(
@@ -26,25 +27,24 @@ public function updateCmsFields(FieldList $fields)
[
CheckboxField::create(
'MailchimpEnabled',
- _t(__CLASS__. '.MAILCHIMP_ENABLED', 'Mailchimp subscriptions enabled')
+ _t(self::class. '.MAILCHIMP_ENABLED', 'Mailchimp subscriptions enabled')
),
DropdownField::create(
'MailchimpConfigID',
- _t(__CLASS__. '.DEFAULT_MAILCHIMP_CONFIG', 'Default Mailchimp configuration'),
+ _t(self::class. '.DEFAULT_MAILCHIMP_CONFIG', 'Default Mailchimp configuration'),
MailchimpConfig::get()->map('ID', 'TitleCode')
)->setEmptyString('')
]
);
}
+ #[\Override]
public function onAfterWrite()
{
parent::onAfterWrite();
- if($this->owner->MailchimpConfigID) {
- if($config = MailchimpConfig::get()->byId($this->owner->MailchimpConfigID)) {
- $config->IsGlobal = 1;
- $config->write();
- }
+ if ($this->getOwner()->MailchimpConfigID && ($config = MailchimpConfig::get()->byId($this->getOwner()->MailchimpConfigID))) {
+ $config->IsGlobal = 1;
+ $config->write();
}
}
diff --git a/src/Forms/XhrSubscribeForm.php b/src/Forms/XhrSubscribeForm.php
index d0a718c..aabfdbe 100644
--- a/src/Forms/XhrSubscribeForm.php
+++ b/src/Forms/XhrSubscribeForm.php
@@ -17,9 +17,8 @@ class XhrSubscribeForm extends SubscribeForm
{
/**
* Set to true if forms of this class will appear on a publicly cacheable page
- * @var bool
*/
- private static $disable_security_token = false;
+ private static bool $disable_security_token = false;
public function __construct(
RequestHandler $controller = null,
@@ -37,6 +36,7 @@ public function __construct(
/**
* @inheritdoc
*/
+ #[\Override]
protected function canBeCached()
{
$token = $this->getSecurityToken();
@@ -51,6 +51,7 @@ protected function canBeCached()
* @inheritdoc
* Add attributes
*/
+ #[\Override]
protected function getDefaultAttributes(): array
{
$attributes = parent::getDefaultAttributes();
diff --git a/src/Jobs/MailchimpCleanupJob.php b/src/Jobs/MailchimpCleanupJob.php
index 61f79ea..ffa38b0 100644
--- a/src/Jobs/MailchimpCleanupJob.php
+++ b/src/Jobs/MailchimpCleanupJob.php
@@ -19,7 +19,7 @@ class MailchimpCleanupJob extends AbstractQueuedJob implements QueuedJob
{
use Configurable;
- private static $run_in_minutes = 30;
+ private static int $run_in_minutes = 30;
public function __construct($minutes_ago = 30, $limit = 0, $report_only = 0)
{
@@ -28,11 +28,12 @@ public function __construct($minutes_ago = 30, $limit = 0, $report_only = 0)
$this->limit = $limit;
}
+ #[\Override]
public function getTitle()
{
return sprintf(
_t(
- __CLASS__ . '.TITLE',
+ self::class . '.TITLE',
"Mailchimp cleanup job - minutes=%s limit=%s report_only=%s"
),
$this->minutes_ago,
@@ -41,24 +42,26 @@ public function getTitle()
);
}
+ #[\Override]
public function getJobType()
{
return QueuedJob::QUEUED;
}
+ #[\Override]
public function setup()
{
$this->totalSteps = 1;
}
+ #[\Override]
public function process()
{
$this->processSubscriptions();
$this->isComplete = true;
- return;
}
- private function processSubscriptions()
+ private function processSubscriptions(): bool
{
$prune_datetime = new DateTime();
$minutes = $this->minutes_ago;
@@ -87,15 +90,16 @@ private function processSubscriptions()
$subscriber->delete();
$success_deletes++;
}
+
$this->addMessage("Deleted {$success_deletes} subscribers with status " . MailchimpSubscriber::CHIMPLE_STATUS_SUCCESS);
}
-
-
- $this->currentStep = $this->totalSteps = $success_deletes;
+ $this->currentStep = $success_deletes;
+ $this->totalSteps = $success_deletes;
// remove stale failed subscriptions older than 7 days
$fail_datetime = new DateTime();
$fail_datetime->modify('-7 days');
+
$failed = MailchimpSubscriber::get()->filter([
'Status' => MailchimpSubscriber::CHIMPLE_STATUS_FAIL,
'Created:LessThan' => $fail_datetime->format('Y-m-d H:i:s')
@@ -109,11 +113,11 @@ private function processSubscriptions()
$failed_subscriber->delete();
$failed_deletes++;
}
+
$this->addMessage("Deleted {$failed_deletes} subscribers with status " . MailchimpSubscriber::CHIMPLE_STATUS_FAIL);
}
-
-
- $this->currentStep = $this->totalSteps = ($success_deletes + $failed_deletes);
+ $this->currentStep = $success_deletes + $failed_deletes;
+ $this->totalSteps = $success_deletes + $failed_deletes;
return true;
}
@@ -121,16 +125,18 @@ private function processSubscriptions()
/**
* Get next configured run time
*/
- private function getNextRunMinutes()
+ private function getNextRunMinutes(): int
{
$minutes = (int)$this->config()->get('run_in_minutes');
if ($minutes <= 2) {
// min every 2 minutes
$minutes = 2;
}
+
return $minutes;
}
+ #[\Override]
public function afterComplete()
{
$run_datetime = new DateTime();
diff --git a/src/Jobs/MailchimpSubscribeJob.php b/src/Jobs/MailchimpSubscribeJob.php
index 5c2a6a7..ca9c0b7 100644
--- a/src/Jobs/MailchimpSubscribeJob.php
+++ b/src/Jobs/MailchimpSubscribeJob.php
@@ -14,8 +14,9 @@ class MailchimpSubscribeJob extends AbstractQueuedJob implements QueuedJob
{
use Configurable;
- private static $run_in_seconds = 60;
- private static $default_limit = 100;
+ private static int $run_in_seconds = 60;
+
+ private static int $default_limit = 100;
public function __construct($limit = 100, $report_only = 0)
{
@@ -23,37 +24,40 @@ public function __construct($limit = 100, $report_only = 0)
$this->limit = (int)$limit;
}
+ #[\Override]
public function getTitle()
{
$title = _t(
- __CLASS__ . '.TITLE',
+ self::class . '.TITLE',
"Batch subscribe emails to Mailchimp"
);
$title .= " (limit:{$this->limit})";
- $title .= ($this->report_only ? " - report only" : "");
- return $title;
+ return $title . ($this->report_only ? " - report only" : "");
}
+ #[\Override]
public function getJobType()
{
return QueuedJob::QUEUED;
}
+ #[\Override]
public function setup()
{
$this->totalSteps = 1;
}
- private function getTotalResults($results)
+ private function getTotalResults(array $results): int|float
{
$total = 0;
- foreach ($results as $key => $count) {
+ foreach ($results as $count) {
$total += $count;
}
+
return $total;
}
- private function getTotalNonFailedResults($results)
+ private function getTotalNonFailedResults(array $results)
{
$copy = $results;
unset($copy[ MailchimpSubscriber::CHIMPLE_STATUS_FAIL]);
@@ -63,29 +67,35 @@ private function getTotalNonFailedResults($results)
/**
* Process the job
*/
+ #[\Override]
public function process()
{
$results = MailchimpSubscriber::batch_subscribe($this->limit, $this->report_only);
if ($this->report_only) {
$this->addMessage("Report only: " . json_encode($results));
- $this->totalSteps = $this->currentStep = $this->getTotalResults($results);
+ $this->totalSteps = $this->getTotalResults($results);
+ $this->currentStep = $this->totalSteps;
} elseif (is_array($results)) {
foreach ($results as $status => $count) {
$message = $status . ":" . $count;
$this->addMessage($message);
}
+
$this->totalSteps = $this->getTotalResults($results);// total including failed
$this->currentStep = $this->getTotalNonFailedResults($results);
} else {
$this->addMessage("Failed completely - check logs!");
- $this->totalSteps = $this->currentStep = 0;
+ $this->totalSteps = 0;
+ $this->currentStep = 0;
}
+
$this->isComplete = true;
}
/**
* Recreate the MailchimpSubscribeJob job for the next run
*/
+ #[\Override]
public function afterComplete()
{
$run_datetime = new DateTime();
@@ -94,6 +104,7 @@ public function afterComplete()
// min every 30s
$seconds = 30;
}
+
$run_datetime->modify("+{$seconds} seconds");
singleton(QueuedJobService::class)->queueJob(
new MailchimpSubscribeJob($this->limit, $this->report_only),
diff --git a/src/Models/Elements/ElementChimpleSubscribe.php b/src/Models/Elements/ElementChimpleSubscribe.php
index 17fbe4b..10744b5 100644
--- a/src/Models/Elements/ElementChimpleSubscribe.php
+++ b/src/Models/Elements/ElementChimpleSubscribe.php
@@ -24,45 +24,48 @@
*/
class ElementChimpleSubscribe extends BaseElement
{
- private static $table_name = 'ElementChimpleSubscribe';
+ private static string $table_name = 'ElementChimpleSubscribe';
- private static $singular_name = 'Mailchimp subscribe';
- private static $plural_name = 'Mailchimp subscribe';
+ private static string $singular_name = 'Mailchimp subscribe';
- private static $icon = 'font-icon-up-circled';
+ private static string $plural_name = 'Mailchimp subscribe';
- private static $db = [
+ private static string $icon = 'font-icon-up-circled';
+
+ private static array $db = [
'UseXHR' => 'Boolean',// whether to submit without redirect
'BeforeFormContent' => 'HTMLText',
'AfterFormContent' => 'HTMLText',
'ImageAlignment' => 'Varchar(32)',
];
- private static $defaults = [
+ private static array $defaults = [
'UseXHR' => 1
];
/**
* Has_one relationship
- * @var array
*/
- private static $has_one = [
+ private static array $has_one = [
'MailchimpConfig' => MailchimpConfig::class,
'Image' => Image::class
];
- private static $owns = [
+ private static array $owns = [
'Image'
];
+ #[\Override]
public function getType()
{
- return _t(__CLASS__ . '.BlockType', 'Mailchimp Subscribe');
+ return _t(self::class . '.BlockType', 'Mailchimp Subscribe');
}
- private static $title = 'Mailchimp subscribe';
- private static $description = 'Provide a mailchimp subscription form';
+ private static string $title = 'Mailchimp subscribe';
+
+ private static string $description = 'Provide a mailchimp subscription form';
+ #[\Override]
public function getCMSFields()
{
$fields = parent::getCMSFields();
@@ -74,7 +77,7 @@ public function getCMSFields()
LiteralField::create(
'NotEnabled',
'
'
- . _t(__CLASS__ . 'NOT_ENABLED', 'Mailchimp is not enable in site configuration')
+ . _t(self::class . 'NOT_ENABLED', 'Mailchimp is not enable in site configuration')
. '
'
)
);
@@ -90,7 +93,7 @@ public function getCMSFields()
DropdownField::create(
'MailchimpConfigID',
_t(
- __CLASS__ . '.SELECT_CONFIGURATION',
+ self::class . '.SELECT_CONFIGURATION',
'Select the list configuration to use for this subscription form'
),
MailchimpConfig::get()->sort('Title ASC')->map('ID', 'TitleWithDetails')
@@ -98,30 +101,30 @@ public function getCMSFields()
CheckboxField::create(
'UseXHR',
_t(
- __CLASS__ . '.USE_XHR',
+ self::class . '.USE_XHR',
'Submit without redirecting'
),
),
HTMLEditorField::create(
'BeforeFormContent',
_t(
- __CLASS__ . '.BEFORE_CONTENT',
+ self::class . '.BEFORE_CONTENT',
'Content to show before form'
)
)->setRows(6),
HTMLEditorField::create(
'AfterFormContent',
_t(
- __CLASS__ . '.AFTER_CONTENT',
+ self::class . '.AFTER_CONTENT',
'Content to show after form'
)
)->setRows(6),
UploadField::create(
'Image',
- _t(__CLASS__ . '.IMAGE', 'Image')
+ _t(self::class . '.IMAGE', 'Image')
)->setTitle(
_t(
- __CLASS__ . '.ADD_IMAGE_TO_CONTENT_BLOCK',
+ self::class . '.ADD_IMAGE_TO_CONTENT_BLOCK',
'Add an image'
)
)->setFolderName('blocks/content/' . $this->owner->ID)
@@ -129,14 +132,14 @@ public function getCMSFields()
->setIsMultiUpload(false),
DropdownField::create(
'ImageAlignment',
- _t(__CLASS__ . '.IMAGE_ALIGNMENT', 'Image alignment'),
+ _t(self::class . '.IMAGE_ALIGNMENT', 'Image alignment'),
[
- 'left' => _t(__CLASS__ . '.LEFT', 'Left'),
- 'right' => _t(__CLASS__ . '.RIGHT', 'Right')
+ 'left' => _t(self::class . '.LEFT', 'Left'),
+ 'right' => _t(self::class . '.RIGHT', 'Right')
]
)->setEmptyString('Choose an option')
->setDescription(
- _t(__CLASS__ . '.IMAGE_ALIGNMENT_DESCRIPTION', 'Use of this option is dependent on the theme')
+ _t(self::class . '.IMAGE_ALIGNMENT_DESCRIPTION', 'Use of this option is dependent on the theme')
)
]
);
@@ -160,6 +163,7 @@ public function getSubscribeForm(): ?SubscribeForm
$form = $config->SubscribeForm($this->UseXHR == 1);
return $form;
}
+
return null;
}
}
diff --git a/src/Models/MailchimpConfig.php b/src/Models/MailchimpConfig.php
index 2603339..27b8428 100644
--- a/src/Models/MailchimpConfig.php
+++ b/src/Models/MailchimpConfig.php
@@ -31,25 +31,28 @@
*/
class MailchimpConfig extends DataObject implements TemplateGlobalProvider, PermissionProvider
{
- private static $list_id = "";// default list (audience) ID
- private static $api_key = "";// API key provided by Mailchimp
+ private static string $list_id = "";
+ // default list (audience) ID
+ private static string $api_key = "";// API key provided by Mailchimp
- private static $success_message = "Thank you for subscribing. You will receive an email to confirm your subscription shortly.";
- private static $error_message = "Sorry, we could not subscribe that email address at the current time. Please try again later.";
+ private static string $success_message = "Thank you for subscribing. You will receive an email to confirm your subscription shortly.";
- private static $table_name = 'ChimpleConfig';
+ private static string $error_message = "Sorry, we could not subscribe that email address at the current time. Please try again later.";
- private static $singular_name = 'Mailchimp Configuration';
- private static $plural_name = 'Mailchimp Configurations';
+ private static string $table_name = 'ChimpleConfig';
- private static $title = "Mailchimp Subscriber Form";
- private static $description = "Configuration for a Mailchimp subscribe form";
+ private static string $singular_name = 'Mailchimp Configuration';
+
+ private static string $plural_name = 'Mailchimp Configurations';
+
+ private static string $title = "Mailchimp Subscriber Form";
+
+ private static string $description = "Configuration for a Mailchimp subscribe form";
/**
* Database fields
- * @var array
*/
- private static $db = [
+ private static array $db = [
'Title' => 'Varchar(255)',
'Code' => 'Varchar(255)',// auto created, used to identify config
'IsGlobal' => 'Boolean',
@@ -70,9 +73,8 @@ class MailchimpConfig extends DataObject implements TemplateGlobalProvider, Perm
/**
* Defines summary fields commonly used in table columns
* as a quick overview of the data for this dataobject
- * @var array
*/
- private static $summary_fields = [
+ private static array $summary_fields = [
'Title' => 'Title',
'Code' => 'Code',
'IsGlobal.Nice' => 'Default',
@@ -81,16 +83,15 @@ class MailchimpConfig extends DataObject implements TemplateGlobalProvider, Perm
'UseXHR.Nice' => 'Submit w/o redirect'
];
- private static $indexes = [
+ private static array $indexes = [
'MailchimpListId' => true,
'Code' => ['type' => 'unique']
];
/**
* Add default values to database
- * @var array
*/
- private static $defaults = [
+ private static array $defaults = [
'UpdateExisting' => 1,// @deprecated
'SendWelcome' => 0,// @deprecated
'ReplaceInterests' => 0,// @deprecated
@@ -99,12 +100,12 @@ class MailchimpConfig extends DataObject implements TemplateGlobalProvider, Perm
'UseXHR' => 1
];
- public function TitleCode()
+ public function TitleCode(): string
{
return "{$this->Title} ({$this->Code})";
}
- public static function isEnabled()
+ public static function isEnabled(): bool
{
$site_config = SiteConfig::current_site_config();
return $site_config->MailchimpEnabled == 1;
@@ -122,38 +123,38 @@ public static function getApiKey()
/**
* Returns the data centre (dc) component based on the API key e.g us2
- * @return string
*/
public static function getDataCentre(): string
{
- $dc = '';
$key = self::getApiKey();
$parts = [];
if($key) {
- $parts = explode("-", $key);
+ $parts = explode("-", (string) $key);
}
- return !empty($parts[1]) ? $parts[1] : '';
+
+ return empty($parts[1]) ? '' : $parts[1];
}
- public function TitleWithCode()
+ public function TitleWithCode(): string
{
return $this->Title . " - (code {$this->Code})";
}
- public function TitleWithDetails()
+ public function TitleWithDetails(): string
{
$title = $this->Title;
$list_id = $this->getMailchimpListId();
- $title .= " (list {$list_id})";
- return $title;
+ return $title . " (list {$list_id})";
}
+ #[\Override]
public function onBeforeWrite()
{
parent::onBeforeWrite();
if (!$this->Code) {
$this->Code = bin2hex(random_bytes(16));
}
+
$this->Code = Convert::raw2url($this->Code);
if($this->IsGlobal == 1) {
@@ -184,10 +185,11 @@ public function getMailchimpListId()
if (!$list_id) {
$list_id = self::getDefaultMailchimpListId();
}
+
return $list_id;
}
- public function HasMailchimpListId()
+ public function HasMailchimpListId(): bool
{
return $this->getMailchimpListId() != '';
}
@@ -197,18 +199,22 @@ public static function getConfig($id = '', $list_id = '', $code = '')
if ($id) {
return MailchimpConfig::get()->byId($id);
}
+
if ($list_id) {
return MailchimpConfig::get()->filter('MailchimpListId', $list_id)->first();
}
+
if ($code) {
return MailchimpConfig::get()->filter('Code', $code)->first();
}
+
return false;
}
/**
* @inheritdoc
*/
+ #[\Override]
public function getCMSFields()
{
$fields = parent::getCMSFields();
@@ -229,7 +235,7 @@ public function getCMSFields()
'NoApiKey',
''
. _t(
- __CLASS__ . '.NO_API_KEY',
+ self::class . '.NO_API_KEY',
'Warning: no API key was found in the system configuration - subscriptions cannot occur until this is set.'
)
. '
'
@@ -243,7 +249,7 @@ public function getCMSFields()
TextField::create(
'ArchiveLink',
_t(
- __CLASS__ . '.ARCHIVE_URL',
+ self::class . '.ARCHIVE_URL',
'Newsletter archive URL'
)
)
@@ -253,14 +259,14 @@ public function getCMSFields()
$list_id = $this->getField('MailchimpListId');
$fields->dataFieldByName('MailchimpListId')
->setDescription(
- !$list_id ?
- sprintf(
+ $list_id ?
+ "" : sprintf(
_t(
- __CLASS__ . '.NO_LIST_ID',
+ self::class . '.NO_LIST_ID',
"No list Id is set, the default list id '%s' is being used."
),
$default_list_id
- ) : ""
+ )
);
// this is set from SiteConfig
@@ -271,7 +277,7 @@ public function getCMSFields()
'IsGlobalBanner',
''
. _t(
- __CLASS__. '.CONFIG_IS_GLOBAL',
+ self::class. '.CONFIG_IS_GLOBAL',
'This configuration is the default for this website'
)
. '
'
@@ -285,7 +291,7 @@ public function getCMSFields()
MultiValueTextField::create(
'Tags',
_t(
- __CLASS__ . '.TAGS_FOR_SUBSCRIPTIONS',
+ self::class . '.TAGS_FOR_SUBSCRIPTIONS',
'Tags assigned to subscribers'
)
)
@@ -296,7 +302,7 @@ public function getCMSFields()
CheckboxField::create(
'UseXHR',
_t(
- __CLASS__ . '.USE_XHR',
+ self::class . '.USE_XHR',
'Submit without redirecting'
)
),
@@ -309,14 +315,14 @@ public function getCMSFields()
HTMLEditorField::create(
'BeforeFormContent',
_t(
- __CLASS__ . '.BEFORE_CONTENT',
+ self::class . '.BEFORE_CONTENT',
'Content to show before form'
)
)->setRows(6),
HTMLEditorField::create(
'AfterFormContent',
_t(
- __CLASS__ . '.AFTER_CONTENT',
+ self::class . '.AFTER_CONTENT',
'Content to show after form'
)
)->setRows(6)
@@ -325,7 +331,7 @@ public function getCMSFields()
if($heading = $fields->dataFieldByName('Heading')) {
$heading->setDescription(_t(
- __CLASS__ . '.HEADING_DESCRIPTON',
+ self::class . '.HEADING_DESCRIPTON',
'Displayed above the form'
));
}
@@ -346,13 +352,14 @@ public function MailchimpLink()
/**
* Ensure the subscription for the global footer is added
*/
+ #[\Override]
public function requireDefaultRecords()
{
$config = MailchimpConfig::get()->filter(['IsGlobal' => 1])->first();
if (empty($config->ID)) {
$config = MailchimpConfig::create([
- 'Title' => _t(__CLASS__ . '.DEFAULT_CONFIG_TITLE', 'Default Configuration'),
- 'Heading' => _t(__CLASS__ . '.DEFAULT_CONFIG_HEADER', 'Subscribe'),
+ 'Title' => _t(self::class . '.DEFAULT_CONFIG_TITLE', 'Default Configuration'),
+ 'Heading' => _t(self::class . '.DEFAULT_CONFIG_HEADER', 'Subscribe'),
'IsGlobal' => 1,
'MailchimpListId' => null
]);
@@ -361,6 +368,7 @@ public function requireDefaultRecords()
} else {
$config_id = $config->ID;
}
+
if ($config_id) {
$site_config = SiteConfig::current_site_config();
if (!empty($site_config->ID) && empty($site_config->MailchimpConfigID)) {
@@ -403,6 +411,7 @@ public function SubscribeForm($force_xhr = null): ?SubscribeForm
if ($this->Heading) {
$form->setLegend($this->Heading);
}
+
$form->addExtraClass('form-subscribe');
return $form;
}
@@ -412,39 +421,43 @@ public function SubscribeForm($force_xhr = null): ?SubscribeForm
/**
* Return alerts for the form
- * @return string
*/
- public function Alerts()
+ public function Alerts(): string
{
return ''
- . _t(__CLASS__ . '.SUBSCRIBE_SUCCESS', htmlspecialchars($this->config()->get('success_message')))
+ . _t(self::class . '.SUBSCRIBE_SUCCESS', htmlspecialchars((string) $this->config()->get('success_message')))
. '
'
. ''
- . _t(__CLASS__ . '.SUBSCRIBE_ERROR', htmlspecialchars($this->config()->get('error_message')))
+ . _t(self::class . '.SUBSCRIBE_ERROR', htmlspecialchars((string) $this->config()->get('error_message')))
. '
'
. '';// info added by JS
}
+ #[\Override]
public function canView($member = null)
{
return Permission::checkMember($member, 'MAILCHIMP_CONFIG_VIEW');
}
+ #[\Override]
public function canCreate($member = null, $context = [])
{
return Permission::checkMember($member, 'MAILCHIMP_CONFIG_CREATE');
}
+ #[\Override]
public function canEdit($member = null)
{
return Permission::checkMember($member, 'MAILCHIMP_CONFIG_EDIT');
}
+ #[\Override]
public function canDelete($member = null)
{
return Permission::checkMember($member, 'MAILCHIMP_CONFIG_DELETE');
}
+ #[\Override]
public function providePermissions()
{
return [
@@ -474,9 +487,10 @@ public function providePermissions()
public function forTemplate($force_xhr = null)
{
$form = $this->SubscribeForm($force_xhr);
- if($form) {
+ if($form instanceof \NSWDPC\Chimple\Forms\SubscribeForm) {
return $this->customise(['Form' => $form])->renderWith(self::class);
}
+
return null;
}
@@ -490,7 +504,7 @@ public function forTemplate($force_xhr = null)
*/
public static function get_chimple_subscribe_form(...$args)
{
- $code = isset($args[0]) ? $args[0] : '';
+ $code = $args[0] ?? '';
if ($code) {
$config = self::getConfig('', '', $code);
if ($config) {
@@ -505,9 +519,11 @@ public static function get_chimple_subscribe_form(...$args)
$force_xhr = true;
}
}
+
return $config->forTemplate($force_xhr);
}
}
+
return null;
}
@@ -522,9 +538,11 @@ public static function get_chimple_global_subscribe_form()
if ($config) {
return $config->forTemplate();
}
+
return null;
}
+ #[\Override]
public static function get_template_global_variables()
{
return [
diff --git a/src/Models/MailchimpSubscriber.php b/src/Models/MailchimpSubscriber.php
index 5b2cf0f..f925586 100644
--- a/src/Models/MailchimpSubscriber.php
+++ b/src/Models/MailchimpSubscriber.php
@@ -19,71 +19,69 @@
class MailchimpSubscriber extends DataObject implements PermissionProvider
{
public const CHIMPLE_STATUS_UNKNOWN = '';
+
public const CHIMPLE_STATUS_NEW = 'NEW';
+
public const CHIMPLE_STATUS_PROCESSING = 'PROCESSING';
+
public const CHIMPLE_STATUS_BATCHED = 'BATCHED';
+
public const CHIMPLE_STATUS_SUCCESS = 'SUCCESS';
+
public const CHIMPLE_STATUS_FAIL = 'FAIL';
public const MAILCHIMP_SUBSCRIBER_PENDING = 'pending';
+
public const MAILCHIMP_SUBSCRIBER_SUBSCRIBED = 'subscribed';
+
public const MAILCHIMP_SUBSCRIBER_UNSUBSCRIBED = 'unsubscribed';
+
public const MAILCHIMP_SUBSCRIBER_CLEANED = 'cleaned';
public const MAILCHIMP_TAG_INACTIVE = 'inactive';
+
public const MAILCHIMP_TAG_ACTIVE = 'active';
public const MAILCHIMP_EMAIL_TYPE_HTML = 'html';
+
public const MAILCHIMP_EMAIL_TYPE_TEXT = 'text';
- /**
- * @var string
- */
- private static $table_name = 'ChimpleSubscriber';
+ private static string $table_name = 'ChimpleSubscriber';
/**
* Singular name for CMS
- * @var string
*/
- private static $singular_name = 'Mailchimp Subscriber';
+ private static string $singular_name = 'Mailchimp Subscriber';
/**
* Plural name for CMS
- * @var string
*/
- private static $plural_name = 'Mailchimp Subscribers';
+ private static string $plural_name = 'Mailchimp Subscribers';
/**
* Default sort ordering
- * @var array
*/
- private static $default_sort = ['Created' => 'DESC'];
+ private static array $default_sort = ['Created' => 'DESC'];
/**
* Default chr for obfuscation
- * @var string
*/
- private static $obfuscation_chr = "•";
+ private static string $obfuscation_chr = "•";
/**
* Email type, defaults to 'html', other value is 'text'
- * @var string
*/
- private static $email_type = self::MAILCHIMP_EMAIL_TYPE_HTML;
+ private static string $email_type = self::MAILCHIMP_EMAIL_TYPE_HTML;
/**
* Remove tags that do not exist in the tags list when a subscriber
* attempts to update their subscription
* This is a potentially destructive action as it will remove tags added to
* a subscriber via other means
- * @var bool
*/
- private static $remove_subscriber_tags = false;
+ private static bool $remove_subscriber_tags = false;
- /**
- * @var array
- */
- private static $db = [
+ private static array $db = [
'Name' => 'Varchar(255)',
'Surname' => 'Varchar(255)',
'Email' => 'Varchar(255)',
@@ -107,12 +105,12 @@ class MailchimpSubscriber extends DataObject implements PermissionProvider
'Tags' => 'MultiValueField'
];
- private static $sync_fields = [
+ private static array $sync_fields = [
'Name' => 'FNAME',
'Surname' => 'LNAME'
];
- private static $indexes = [
+ private static array $indexes = [
'Status' => true,
'Email' => true,
'Name' => true,
@@ -123,9 +121,8 @@ class MailchimpSubscriber extends DataObject implements PermissionProvider
/**
* Add default values to database
- * @var array
*/
- private static $defaults = [
+ private static array $defaults = [
'Status' => self::CHIMPLE_STATUS_NEW,
'UpdateExisting' => 1,// @deprecated
'SendWelcome' => 0,// @deprecated
@@ -136,9 +133,8 @@ class MailchimpSubscriber extends DataObject implements PermissionProvider
/**
* Defines summary fields commonly used in table columns
* as a quick overview of the data for this dataobject
- * @var array
*/
- private static $summary_fields = [
+ private static array $summary_fields = [
'Created.Nice' => 'Created',
'Name' => 'Name',
'Surname' => 'Surname',
@@ -151,9 +147,8 @@ class MailchimpSubscriber extends DataObject implements PermissionProvider
/**
* Defines a default list of filters for the search context
- * @var array
*/
- private static $searchable_fields = [
+ private static array $searchable_fields = [
'Name' => 'PartialMatchFilter',
'Surname' => 'PartialMatchFilter',
'Email' => 'PartialMatchFilter',
@@ -165,25 +160,26 @@ class MailchimpSubscriber extends DataObject implements PermissionProvider
* @var MailchimpApiClient
* The Mailchimp API client instance
*/
- protected static $mailchimp = null;
+ protected static $mailchimp;
/**
* List of current subscriber tags
- * @var array|null
*/
- private $_cache_tags = null;
+ private ?array $_cache_tags = null;
/**
* Return whether subscription was success
*/
- public function getSuccessful()
+ public function getSuccessful(): bool
{
return $this->Status == self::CHIMPLE_STATUS_SUCCESS;
}
+
/**
* @inheritdoc
*/
+ #[\Override]
public function getCMSFields()
{
$fields = parent::getCMSFields();
@@ -204,7 +200,7 @@ public function getCMSFields()
$fields->dataFieldByName('LastError')
->setDescription(
_t(
- __CLASS__. '.IF_ERROR_OCCURRED',
+ self::class. '.IF_ERROR_OCCURRED',
"If a subscription error occurred, this will display the last error returned by Mailchimp and can help determine the cause of the error"
)
)
@@ -214,13 +210,13 @@ public function getCMSFields()
if($this->exists()) {
$status_field = DropdownField::create(
'Status',
- _t(__CLASS__ . '.STATUS', 'Status'),
+ _t(self::class . '.STATUS', 'Status'),
[
self::CHIMPLE_STATUS_UNKNOWN => '',
- self::CHIMPLE_STATUS_NEW => _t(__CLASS__ . '.STATUS_NEW', 'NEW (the subscriber has not yet been subscribed)'),
- self::CHIMPLE_STATUS_PROCESSING => _t(__CLASS__ . '.STATUS_PROCESSING', 'PROCESSING (the subscriber is in the process of being subscribed)'),
- self::CHIMPLE_STATUS_SUCCESS => _t(__CLASS__ . '.STATUS_SUCCESS', 'SUCCESS (the subscriber was subscribed)'),
- self::CHIMPLE_STATUS_FAIL => _t(__CLASS__ . '.STATUS_FAIL', 'FAIL (the subscriber could not be subscribed - check the \'Last Error\' value)')
+ self::CHIMPLE_STATUS_NEW => _t(self::class . '.STATUS_NEW', 'NEW (the subscriber has not yet been subscribed)'),
+ self::CHIMPLE_STATUS_PROCESSING => _t(self::class . '.STATUS_PROCESSING', 'PROCESSING (the subscriber is in the process of being subscribed)'),
+ self::CHIMPLE_STATUS_SUCCESS => _t(self::class . '.STATUS_SUCCESS', 'SUCCESS (the subscriber was subscribed)'),
+ self::CHIMPLE_STATUS_FAIL => _t(self::class . '.STATUS_FAIL', "FAIL (the subscriber could not be subscribed - check the 'Last Error' value)")
]
);
@@ -234,27 +230,27 @@ public function getCMSFields()
// stuck processing - can reset to new
$status_field->setDescription(
_t(
- __CLASS__ . '.PROCESSING_RESET_NEW_STATUS',
+ self::class . '.PROCESSING_RESET_NEW_STATUS',
"If this attempt is stuck, reset to 'New' for another attempt"
)
);
// can retain failed or set to new for retry
$status_field->setSource([
- self::CHIMPLE_STATUS_NEW => _t(__CLASS__ . '.STATUS_NEW', 'NEW (the subscriber has not yet been subscribed)'),
- self::CHIMPLE_STATUS_PROCESSING => _t(__CLASS__ . '.STATUS_PROCESSING', 'PROCESSING (the subscriber is in the process of being subscribed)'),
+ self::CHIMPLE_STATUS_NEW => _t(self::class . '.STATUS_NEW', 'NEW (the subscriber has not yet been subscribed)'),
+ self::CHIMPLE_STATUS_PROCESSING => _t(self::class . '.STATUS_PROCESSING', 'PROCESSING (the subscriber is in the process of being subscribed)'),
]);
} elseif($this->Status == self::CHIMPLE_STATUS_FAIL) {
// handling when failed
$status_field->setDescription(
_t(
- __CLASS__ . '.FAIL_RESET_NEW_STATUS',
+ self::class . '.FAIL_RESET_NEW_STATUS',
"Reset this value to 'New' to retry a failed subscription attempt"
)
);
// can retain failed or set to new for retry
$status_field->setSource([
- self::CHIMPLE_STATUS_NEW => _t(__CLASS__ . '.STATUS_NEW', 'NEW (the subscriber has not yet been subscribed)'),
- self::CHIMPLE_STATUS_FAIL => _t(__CLASS__ . '.STATUS_FAIL', 'FAIL (the subscriber could not be subscribed - check the \'Last Error\' value)')
+ self::CHIMPLE_STATUS_NEW => _t(self::class . '.STATUS_NEW', 'NEW (the subscriber has not yet been subscribed)'),
+ self::CHIMPLE_STATUS_FAIL => _t(self::class . '.STATUS_FAIL', "FAIL (the subscriber could not be subscribed - check the 'Last Error' value)")
]);
}
@@ -275,8 +271,8 @@ public function getCMSFields()
'StatusForNew',
''
. _t(
- __CLASS__ . '.STATUS_NEW_MESSAGE',
- 'This subscription attempt record will be given status of \'New\' and it will enter the pending subscription queue upon save'
+ self::class . '.STATUS_NEW_MESSAGE',
+ "This subscription attempt record will be given status of 'New' and it will enter the pending subscription queue upon save"
)
. '
'
),
@@ -286,9 +282,9 @@ public function getCMSFields()
$tags = $this->getCurrentSubscriberTags();
$tag_field_description = "";
- if(!empty($tags)) {
+ if($tags !== []) {
$tag_field_description = _t(
- __CLASS__ . '.TAGS_FIELD_DESCRIPTION',
+ self::class . '.TAGS_FIELD_DESCRIPTION',
'The current tags for this subscriber are {tags}
Tags not in the tag update list will be removed. New tags will be added.',
[
'tags' => implode(", ", $tags)
@@ -302,19 +298,19 @@ public function getCMSFields()
KeyValueField::create(
'MergeFields',
_t(
- __CLASS__ . '.MERGE_FIELDS',
+ self::class . '.MERGE_FIELDS',
'Merge fields for this subscription attempt'
)
)->setDescription(
_t(
- __CLASS__ . '.MERGE_FIELDS_DESCRIPTION',
+ self::class . '.MERGE_FIELDS_DESCRIPTION',
'Keys are merge tag names, values are the values for this particular subscriber'
)
),
MultiValueTextField::create(
'Tags',
_t(
- __CLASS__ . '.TAGS_FIELD',
+ self::class . '.TAGS_FIELD',
'Tag update list'
)
)->setDescription(
@@ -332,10 +328,10 @@ public function getCMSFields()
}
$readonly_fields = [
- 'MailchimpListId' => _t(__CLASS__ . '.SUBSCRIBER_LIST_ID', "The Mailchimp List (audience) Id for this subscription record"),
- 'SubscribedUniqueEmailId' => _t(__CLASS__ . '.SUBSCRIBER_UNIQUE_EMAIL_ID', "An identifier for the address across all of Mailchimp."),
- 'SubscribedWebId' => _t(__CLASS__ . '.SUBSCRIBER_WEB_ID', "Member profile page: {link}", ['link' => $subscriber_profile_link]),
- 'SubscribedId' => _t(__CLASS__ . '.SUBSCRIBER_ID', "The MD5 hash of the lowercase version of the list member's email address.")
+ 'MailchimpListId' => _t(self::class . '.SUBSCRIBER_LIST_ID', "The Mailchimp List (audience) Id for this subscription record"),
+ 'SubscribedUniqueEmailId' => _t(self::class . '.SUBSCRIBER_UNIQUE_EMAIL_ID', "An identifier for the address across all of Mailchimp."),
+ 'SubscribedWebId' => _t(self::class . '.SUBSCRIBER_WEB_ID', "Member profile page: {link}", ['link' => $subscriber_profile_link]),
+ 'SubscribedId' => _t(self::class . '.SUBSCRIBER_ID', "The MD5 hash of the lowercase version of the list member's email address.")
];
foreach($readonly_fields as $readonly_field => $description) {
@@ -345,6 +341,7 @@ public function getCMSFields()
if($description) {
$field->setDescription($description);
}
+
$fields->addFieldToTab(
'Root.Main',
$field
@@ -355,6 +352,7 @@ public function getCMSFields()
return $fields;
}
+ #[\Override]
public function onBeforeWrite()
{
parent::onBeforeWrite();
@@ -368,7 +366,7 @@ public function onBeforeWrite()
$this->Surname = $this->getSurnameFromName();
// reset name
$parts = explode(" ", $this->Name, 2);
- $this->Name = isset($parts[0]) ? $parts[0] : '';
+ $this->Name = $parts[0] ?? '';
}
}
@@ -377,11 +375,10 @@ public function onBeforeWrite()
* Given some meta data, update the MergeFields for this subscriber
* The parameter can contain values submitted via a form
* By default MergeFields doesn't allow HTML tags as keys or as values
- * @param array $meta
*/
public function updateMergeFields(array $meta)
{
- if(empty($meta)) {
+ if($meta === []) {
return;
}
@@ -391,15 +388,17 @@ public function updateMergeFields(array $meta)
// ignore values that cannot be saved
continue;
}
+
$key = strtoupper(trim(strip_tags($k)));
$value = trim(strip_tags($v));
$data[ $key ] = $value;
}
+
$this->MergeFields = $data;
$this->write();
}
- public function HasLastError()
+ public function HasLastError(): string
{
return trim($this->LastError ?? '') !== '' ? "yes" : "no";
}
@@ -407,17 +406,17 @@ public function HasLastError()
/**
* Attempt to get a surname from the name
*/
- public function getSurnameFromName()
+ public function getSurnameFromName(): ?string
{
$parts = explode(" ", $this->Name, 2);
- if (!empty($parts[1])) {
+ if (isset($parts[1]) && ($parts[1] !== '' && $parts[1] !== '0')) {
return $parts[1];
}
+ return null;
}
/**
* Get the API client
- * @return MailchimpApiClient
*/
public static function api(): MailchimpApiClient
{
@@ -425,10 +424,12 @@ public static function api(): MailchimpApiClient
if(self::$mailchimp instanceof MailchimpApiClient) {
return self::$mailchimp;
}
+
$api_key = MailchimpConfig::getApiKey();
if (!$api_key) {
throw new Exception("No Mailchimp API Key configured!");
}
+
self::$mailchimp = new MailchimpApiClient($api_key);
return self::$mailchimp;
}
@@ -436,7 +437,7 @@ public static function api(): MailchimpApiClient
/**
* @deprecated use self::api() instead
*/
- public function getMailchimp()
+ public function getMailchimp(): \DrewM\MailChimp\MailChimp
{
return self::api();
}
@@ -450,27 +451,28 @@ public function getMailchimpListId()
if (!$list_id) {
$list_id = MailchimpConfig::getDefaultMailchimpListId();
}
+
return $list_id;
}
/**
* Applies merge fields prior to subscription attempt
- * @return array
*/
- protected function applyMergeFields()
+ protected function applyMergeFields(): array
{
$merge_fields = [];
// get subscriber meta data
$meta = $this->MergeFields->getValue();
- if(is_array($meta) && !empty($meta)) {
+ if(is_array($meta) && $meta !== []) {
foreach($meta as $k => $v) {
if($v === '') {
// do not set empty values, MailChimp does not like this
continue;
}
+
$k = strtoupper(trim($k));
- $merge_fields[$k] = trim($v);
+ $merge_fields[$k] = trim((string) $v);
}
}
@@ -482,18 +484,17 @@ protected function applyMergeFields()
// ignore non-existent fields
continue;
}
+
$value = $this->getField($field);
- if(!is_string($value)) {
- $value = '';
- } else {
- $value = trim($value);
- }
+ $value = is_string($value) ? trim($value) : '';
+
if ($value === '') {
// do not set empty values, MailChimp does not like this
// "The resource submitted could not be validated"
continue;
}
- $tag = strtoupper(trim($tag));
+
+ $tag = strtoupper(trim((string) $tag));
$merge_fields[$tag] = $value;
}
@@ -502,7 +503,6 @@ protected function applyMergeFields()
/**
* Get the default subscription record data for adding/updating member in list
- * @return array
*/
public function getSubscribeRecord(): array
{
@@ -513,18 +513,17 @@ public function getSubscribeRecord(): array
if(!$email_type || $email_type != self::MAILCHIMP_EMAIL_TYPE_HTML || $email_type != self::MAILCHIMP_EMAIL_TYPE_TEXT) {
$email_type = self::MAILCHIMP_EMAIL_TYPE_HTML;
}
- $params = [
+ return [
'email_address' => $this->Email,
'email_type' => $email_type,
'merge_fields' => $merge_fields
];
- return $params;
}
/**
* Return tags for this subscriber
*/
- public function getSubscriberTags()
+ public function getSubscriberTags(): array
{
$tags = $this->Tags->getValue();
if(!is_array($tags)) {
@@ -545,17 +544,18 @@ private function obfuscate()
if($length == 0) {
return "";
}
+
$chr = $this->config()->get('obfuscation_chr');
if($chr === "") {
// if no chr configured, do not obfuscate (e.g not require by project)
return $in;
}
+
$sub_length = $length - 2;
if($sub_length <= 0) {
return str_repeat($chr, $length);
}
- $replaced = substr_replace($in, str_repeat($chr, $sub_length), 1, $sub_length);
- return $replaced;
+ return substr_replace($in, str_repeat($chr, $sub_length), 1, $sub_length);
};
$this->Email = $obfuscate($this->Email);
$this->Name = $obfuscate($this->Name);
@@ -568,7 +568,7 @@ private function obfuscate()
*/
public static function getMailchimpSubscribedId($email)
{
- if(!is_string($email) || !$email) {
+ if(!is_string($email) || ($email === '' || $email === '0')) {
return '';
} else {
return MailchimpApiClient::subscriberHash($email);
@@ -580,25 +580,24 @@ public static function getMailchimpSubscribedId($email)
* @param string $list_id the Audience ID
* @param string $email an email address, this is hashed using the MC hashing strategy
* @param string $api_key @deprecated
- * @return boolean|array
*/
- public static function checkExistsInList(string $list_id, string $email, string $api_key = '')
+ public static function checkExistsInList(string $list_id, string $email, string $api_key = ''): array|false
{
// sanity check on input
- if(!$email) {
+ if($email === '' || $email === '0') {
throw new \Exception(
_t(
- __CLASS__ . ".EMAIL_NOT_PROVIDED",
+ self::class . ".EMAIL_NOT_PROVIDED",
"Please provide an email address"
)
);
}
- if(!$list_id) {
+ if($list_id === '' || $list_id === '0') {
throw new \Exception(
_t(
- __CLASS__ . ".AUDIENCE_NOT_PROVIDED",
+ self::class . ".AUDIENCE_NOT_PROVIDED",
"Please provide a Mailchimp audience/list ID"
)
);
@@ -621,9 +620,8 @@ public static function checkExistsInList(string $list_id, string $email, string
/**
* Subscribe *this* particular record
- * @return bool
*/
- public function subscribe()
+ public function subscribe(): bool
{
try {
@@ -682,16 +680,17 @@ public function subscribe()
$this->write();
return true;
} elseif (!empty($result['status'])) {
- $error_detail = isset($result['detail']) ? $result['detail'] : '';
+ $error_detail = $result['detail'] ?? '';
$error_status = $result['status'];
$error_title = $result['title'];
$errors = "{$error_status}|{$error_title}|{$error_detail}";
} else {
$errors = "Unhandled error for email: {$this->Email}";
}
+
throw new Exception(trim($errors));
- } catch (Exception $e) {
- $last_error = $e->getMessage();
+ } catch (Exception $exception) {
+ $last_error = $exception->getMessage();
}
// record failure
@@ -732,12 +731,12 @@ private function getCurrentSubscriberTags(bool $force = false, int $count = 10):
$operation_path = "lists/{$list_id}/members/{$subscriber_hash}/tags/?count={$count}&offset={$offset}";
$result = self::api()->get($operation_path);
- $total = isset($result['total_items']) ? $result['total_items'] : 0;
+ $total = $result['total_items'] ?? 0;
// initial set of tags
$tags = isset($result['tags']) && is_array($result['tags']) ? $result['tags'] : [];
// populate the list of tags
- $walker = function ($value, $key) use (&$list) {
+ $walker = function (array $value, $key) use (&$list): void {
$list[] = $value['name'];
};
array_walk($tags, $walker);
@@ -810,7 +809,7 @@ protected function modifySubscriberTags(): bool
$operation_path = "/lists/{$list_id}/members/{$subscriber_hash}/tags";
// submit payload to API
- $result = self::api()->post(
+ self::api()->post(
$operation_path,
$params
);
@@ -826,7 +825,6 @@ protected function modifySubscriberTags(): bool
/**
* Batch subscribe via API - hit from MailchimpSubscribeJob
* Retrieve all subscribers marked new and attempt to subscribe them
- * @return array
*/
public static function batch_subscribe($limit = 100, $report_only = false): array
{
@@ -838,11 +836,13 @@ public static function batch_subscribe($limit = 100, $report_only = false): arra
if ($limit) {
$subscribers = $subscribers->limit($limit);
}
+
if ($report_only) {
$results[ self::CHIMPLE_STATUS_PROCESSING ] = $subscribers->count();
foreach ($subscribers as $subscriber) {
Logger::log("REPORT_ONLY: would subscribe #{$subscriber->ID} to list {$subscriber->MailchimpListId}", 'DEBUG');
}
+
return $results;
}
@@ -858,22 +858,26 @@ public static function batch_subscribe($limit = 100, $report_only = false): arra
// set status to 0
$results[ $subscriber->Status ] = 0;
}
+
// increment this status
$results[ $subscriber->Status ]++;
}
+
return $results;
- } catch (Exception $e) {
- Logger::log("FAIL: could not batch_subscribe, error=" . $e->getMessage(), 'NOTICE');
+ } catch (Exception $exception) {
+ Logger::log("FAIL: could not batch_subscribe, error=" . $exception->getMessage(), 'NOTICE');
}
return [];
}
+ #[\Override]
public function canView($member = null)
{
return Permission::checkMember($member, 'MAILCHIMP_SUBSCRIBER_VIEW');
}
+ #[\Override]
public function canEdit($member = null)
{
return Permission::checkMember($member, 'MAILCHIMP_SUBSCRIBER_EDIT');
@@ -882,29 +886,32 @@ public function canEdit($member = null)
/**
* Only admin can delete subscribers
*/
+ #[\Override]
public function canDelete($member = null)
{
return Permission::checkMember($member, 'ADMIN');
}
+ #[\Override]
public function canCreate($member = null, $context = [])
{
return Permission::checkMember($member, 'MAILCHIMP_SUBSCRIBER_CREATE');
}
+ #[\Override]
public function providePermissions()
{
return [
'MAILCHIMP_SUBSCRIBER_VIEW' => [
- 'name' => _t(__CLASS__ . '.MAILCHIMP_SUBSCRIBER_VIEW', 'View Mailchimp Subscribers'),
+ 'name' => _t(self::class . '.MAILCHIMP_SUBSCRIBER_VIEW', 'View Mailchimp Subscribers'),
'category' => 'Mailchimp',
],
'MAILCHIMP_SUBSCRIBER_EDIT' => [
- 'name' => _t(__CLASS__ . '.MAILCHIMP_SUBSCRIBER_EDIT', 'Edit Mailchimp Subscribers'),
+ 'name' => _t(self::class . '.MAILCHIMP_SUBSCRIBER_EDIT', 'Edit Mailchimp Subscribers'),
'category' => 'Mailchimp',
],
'MAILCHIMP_SUBSCRIBER_CREATE' => [
- 'name' => _t(__CLASS__ . '.MAILCHIMP_SUBSCRIBER_CREATE', 'Create Mailchimp Subscribers'),
+ 'name' => _t(self::class . '.MAILCHIMP_SUBSCRIBER_CREATE', 'Create Mailchimp Subscribers'),
'category' => 'Mailchimp',
]
];
diff --git a/tests/ChimpleConfigTest.php b/tests/ChimpleConfigTest.php
index 0ccdc31..c5ea1bd 100644
--- a/tests/ChimpleConfigTest.php
+++ b/tests/ChimpleConfigTest.php
@@ -45,6 +45,7 @@ class ChimpleConfigTest extends SapphireTest
/**
* @inheritdoc
*/
+ #[\Override]
public function setUp(): void
{
parent::setUp();
@@ -95,7 +96,7 @@ protected function getMailchimpConfig()
}
- public function testConfiguration()
+ public function testConfiguration(): void
{
$forceXhr = true;
@@ -115,7 +116,7 @@ public function testConfiguration()
$email = $fields->dataFieldByName('Email');
$this->assertTrue($email instanceof EmailField, "Email field is not an email field");
- $name = $fields->dataFieldByName('Name');
+ $fields->dataFieldByName('Name');
$this->assertTrue($email instanceof TextField, "Name field is not an text field");
$token_name = SecurityToken::get_default_name();
@@ -134,12 +135,12 @@ public function testConfiguration()
$this->assertTrue($static_form instanceof DBHTMLText, "Static form for code {$code_value} was not returned");
$needle = " value=\"{$code_value}\" ";
- $this->assertTrue(strpos($static_form->forTemplate(), $needle) !== false, "Missing {$code_value} input from form HTML");
+ $this->assertTrue(str_contains($static_form->forTemplate(), $needle), "Missing {$code_value} input from form HTML");
}
- public function testCanBeCached()
+ public function testCanBeCached(): void
{
Config::modify()->set(XhrSubscribeForm::class, 'disable_security_token', true);
@@ -168,7 +169,7 @@ public function testCanBeCached()
}
- public function testSubscribeFormTemplateVariable()
+ public function testSubscribeFormTemplateVariable(): void
{
$config = $this->getMailchimpConfig();
$config->UseXHR = 0;
@@ -176,34 +177,34 @@ public function testSubscribeFormTemplateVariable()
// Use config value
$template = MailchimpConfig::get_chimple_subscribe_form($config->Code, null);
- $this->assertTrue(!str_contains($template, "data-xhr=\"1\""), "Attribute is not in template");
+ $this->assertTrue(!str_contains($template, 'data-xhr="1"'), "Attribute is not in template");
$config->UseXHR = 1;
$config->write();
$template = MailchimpConfig::get_chimple_subscribe_form($config->Code, null);
- $this->assertTrue(str_contains($template, "data-xhr=\"1\""), "Attribute is in template");
+ $this->assertTrue(str_contains($template, 'data-xhr="1"'), "Attribute is in template");
// template override
$config->UseXHR = 0;
$config->write();
$template = MailchimpConfig::get_chimple_subscribe_form($config->Code, '1');
- $this->assertTrue(str_contains($template, "data-xhr=\"1\""), "Attribute is in template");
+ $this->assertTrue(str_contains($template, 'data-xhr="1"'), "Attribute is in template");
$config->UseXHR = 0;
$config->write();
$template = MailchimpConfig::get_chimple_subscribe_form($config->Code, '0');
- $this->assertTrue(!str_contains($template, "data-xhr=\"1\""), "Attribute is not in template");
+ $this->assertTrue(!str_contains($template, 'data-xhr="1"'), "Attribute is not in template");
}
- public function testGlobalSubscribeFormTemplateVariable()
+ public function testGlobalSubscribeFormTemplateVariable(): void
{
$config = $this->getMailchimpConfig();
$config->UseXHR = 0;
$config->write();
// Use config value
$template = MailchimpConfig::get_chimple_global_subscribe_form();
- $this->assertTrue(strpos($template, "data-xhr=\"1\"") === false, "Attribute is not in template");
+ $this->assertTrue(str_contains($template, 'data-xhr="1"') === 0 || str_contains($template, 'data-xhr="1"') === false, "Attribute is not in template");
$config->UseXHR = 1;
$config->write();
$template = MailchimpConfig::get_chimple_global_subscribe_form();
- $this->assertTrue(strpos($template, "data-xhr=\"1\"") !== false, "Attribute is in template");
+ $this->assertTrue(str_contains($template, 'data-xhr="1"'), "Attribute is in template");
}
}
diff --git a/tests/ChimpleFunctionalTest.php b/tests/ChimpleFunctionalTest.php
index 4792d85..75691f9 100644
--- a/tests/ChimpleFunctionalTest.php
+++ b/tests/ChimpleFunctionalTest.php
@@ -50,6 +50,7 @@ class ChimpleFunctionalTest extends FunctionalTest
protected $test_form_code = 'functionalformcode';
+ #[\Override]
public function setUp(): void
{
parent::setUp();
@@ -57,7 +58,7 @@ public function setUp(): void
// Inject test form
Injector::inst()->registerService(
- new TestSubscribeForm(),
+ \NSWDPC\Chimple\Tests\TestSubscribeForm::create(),
SubscribeForm::class
);
@@ -91,10 +92,10 @@ public function setUp(): void
$config->write();
}
- public function testFormSubmission()
+ public function testFormSubmission(): void
{
- $this->useTestTheme(__DIR__, 'chimpletest', function () {
+ $this->useTestTheme(__DIR__, 'chimpletest', function (): void {
// request default route
$url = "/mc-subscribe/v1/";
diff --git a/tests/ChimpleSubscriberTest.php b/tests/ChimpleSubscriberTest.php
index 9d8493a..d7b57b9 100644
--- a/tests/ChimpleSubscriberTest.php
+++ b/tests/ChimpleSubscriberTest.php
@@ -22,23 +22,20 @@ class ChimpleSubscriberTest extends SapphireTest
/**
* e.g example.com
- * @var string
*/
- private static $test_email_domain = "";
+ private static string $test_email_domain = "";
/**
* e.g bob.smith
- * @var string
*/
- private static $test_email_user = "";
+ private static string $test_email_user = "";
/**
* use plus notation in email address
- * @var bool
*/
- private static $test_use_plus = true;
+ private static bool $test_use_plus = true;
- public function testSubscriber()
+ public function testSubscriber(): void
{
$fname = "Test";
$lname = "Tester";
@@ -67,6 +64,7 @@ public function testSubscriber()
if($test_use_plus) {
$email_address_for_test .= "+unittest" . bin2hex(random_bytes(2));
}
+
$email_address_for_test .= "@{$test_email_domain}";
$tags = ['TestOne','TestTwo'];
@@ -99,7 +97,7 @@ public function testSubscriber()
$this->assertTrue(is_array($subscribe_record), "Record is not an array of values");
- $this->assertTrue(!empty($subscribe_record), "Record is empty");
+ $this->assertTrue($subscribe_record !== [], "Record is empty");
$this->assertTrue(isset($subscribe_record['merge_fields']), "Record merge_fields is not set");
@@ -126,11 +124,11 @@ public function testSubscriber()
$this->assertNotEmpty($subscriber->SubscribedUniqueEmailId, "SubscribedUniqueEmailId should not be empty");
- $this->assertTrue(substr_count($subscriber->Email, $obfuscation_chr) > 0, "Email is not obfuscated, it should be");
+ $this->assertTrue(substr_count($subscriber->Email, (string) $obfuscation_chr) > 0, "Email is not obfuscated, it should be");
- $this->assertTrue(substr_count($subscriber->Name, $obfuscation_chr) > 0, "Name is not obfuscated, it should be");
+ $this->assertTrue(substr_count($subscriber->Name, (string) $obfuscation_chr) > 0, "Name is not obfuscated, it should be");
- $this->assertTrue(substr_count($subscriber->Surname, $obfuscation_chr) > 0, "Surname is not obfuscated, it should be");
+ $this->assertTrue(substr_count($subscriber->Surname, (string) $obfuscation_chr) > 0, "Surname is not obfuscated, it should be");
$mc_record = MailchimpSubscriber::checkExistsInList($list_id, $email);
@@ -141,7 +139,7 @@ public function testSubscriber()
$this->assertEquals(count($tags), count($mc_record['tags']), "Tag count mismatch");
$mc_tags_list = [];
- array_walk($mc_record['tags'], function ($value, $key) use (&$mc_tags_list) {
+ array_walk($mc_record['tags'], function (array $value, $key) use (&$mc_tags_list): void {
$mc_tags_list[] = $value['name'];
});
diff --git a/tests/TestSubscribeForm.php b/tests/TestSubscribeForm.php
index b6b43d2..0222114 100644
--- a/tests/TestSubscribeForm.php
+++ b/tests/TestSubscribeForm.php
@@ -13,7 +13,7 @@ class TestSubscribeForm extends SubscribeForm implements TestOnly
/**
* No need to spam protection on tests
*/
- public function enableSpamProtection()
+ public function enableSpamProtection(): null
{
return null;
}