diff --git a/src/SparkPostAdmin.php b/src/SparkPostAdmin.php index b3a659a..f80790f 100644 --- a/src/SparkPostAdmin.php +++ b/src/SparkPostAdmin.php @@ -35,12 +35,14 @@ use SilverStripe\Security\PermissionProvider; use SilverStripe\Security\DefaultAdminService; use SilverStripe\Forms\GridField\GridFieldConfig; +use SilverStripe\Forms\GridField\GridFieldConfig_RecordViewer; use SilverStripe\Forms\GridField\GridFieldFooter; use SilverStripe\Forms\GridField\GridFieldDetailForm; use SilverStripe\Forms\GridField\GridFieldDataColumns; use Symbiote\GridFieldExtensions\GridFieldTitleHeader; use SilverStripe\Forms\GridField\GridFieldToolbarHeader; use SilverStripe\Forms\GridField\GridFieldSortableHeader; +use SilverStripe\Forms\GridField\GridFieldFilterHeader; /** * Allow you to see messages sent through the api key used to send messages @@ -266,6 +268,65 @@ public function getEditForm($id = null, $fields = null) $root = new TabSet('Root', $messagesTab) ]); + $suppressionsTab = new Tab('Suppressions', _t('SparkPostAdmin.Suppressions', 'Suppressions')); + + // Show the summary + $summary = $this->getCachedData('suppressionSummary'); + if ($summary) { + $callback = function ($k, $v) { + return ArrayData::create([ + 'Title' => $k, + 'Value' => $v, + ]); + }; + $summaryArray = array_map($callback, array_keys($summary), array_values($summary)); + $summaryGrid = GridField::create( + 'SuppressionSummary', + _t('SparkPostAdmin.Suppressionsummary', 'Suppression summary'), + new ArrayList($summaryArray) + ); + //@link https://docs.silverstripe.org/en/5/developer_guides/forms/using_gridfield_with_arbitrary_data/ + $summaryGrid->getConfig()->removeComponentsByType(GridFieldFilterHeader::class); + /** @var GridFieldDataColumns $columns */ + $columns = $summaryGrid->getConfig()->getComponentByType(GridFieldDataColumns::class); + $columns->setDisplayFields([ + 'Title' => _t('SparkPostAdmin.Title', 'Title'), + 'Value' => _t('SparkPostAdmin.Value', 'Value'), + ]); + $suppressionsTab->push($summaryGrid); + } + + + // Show recent suppressions + $client = SparkPostHelper::getClient(); + $suppressions = $this->getCachedData('searchSuppressions', [ + 'from' => $client->createValidDatetime('-90 days') + ]); + if ($suppressions) { + $suppressionGrid = GridField::create( + 'RecentSuppressions', + _t('SparkPostAdmin.RecentSuppressions', 'Recent suppressions'), + new ArrayList(array_map(function ($item) { + return ArrayData::create($item); + }, $suppressions)) + ); + //@link https://docs.silverstripe.org/en/5/developer_guides/forms/using_gridfield_with_arbitrary_data/ + $suppressionGrid->getConfig()->removeComponentsByType(GridFieldFilterHeader::class); + /** @var GridFieldDataColumns $columns */ + $columns = $suppressionGrid->getConfig()->getComponentByType(GridFieldDataColumns::class); + $columns->setDisplayFields([ + 'recipient' => _t('SparkPostAdmin.Recipient', 'Recipient'), + 'type' => _t('SparkPostAdmin.Type', 'Type'), + 'source' => _t('SparkPostAdmin.Source', 'Source'), + 'description' => _t('SparkPostAdmin.Description', 'Description'), + 'created' => _t('SparkPostAdmin.Created', 'Created'), + // 'updated' => _t('SparkPostAdmin.Updated', 'Updated'), + ]); + $suppressionsTab->push($suppressionGrid); + } + + $fields->addFieldToTab('Root', $suppressionsTab); + $settingsTab = new Tab('Settings', _t('SparkPostAdmin.Settings', 'Settings')); if ($this->CanConfigureApi()) { $domainTabData = $this->DomainTab(); @@ -388,7 +449,7 @@ public function getCacheEnabled() * @param int $expireInSeconds * @return array|false */ - protected function getCachedData($method, $params, $expireInSeconds = 60) + protected function getCachedData($method, $params = null, $expireInSeconds = 60) { $enabled = $this->getCacheEnabled(); $cacheResult = false; diff --git a/src/SparkPostHelper.php b/src/SparkPostHelper.php index 7601577..cadec71 100644 --- a/src/SparkPostHelper.php +++ b/src/SparkPostHelper.php @@ -260,6 +260,30 @@ public static function forceAdminEmailOverride() Config::modify()->set(Email::class, 'admin_email', self::resolveDefaultFromEmailType()); } + /** + * @param string $email + * @return bool + */ + public static function isEmailSuppressed($email) + { + $client = self::getClient(); + + $state = $client->getSuppression($email); + if (empty($state)) { + return false; + } + return true; + } + + /** + * @param string $email + * @return void + */ + public static function removeSuppression($email) + { + self::getClient()->deleteSuppression($email); + } + /** * Check if email is ready to send emails * diff --git a/src/api/SparkPostApiClient.php b/src/api/SparkPostApiClient.php index 7850a98..7b749dc 100644 --- a/src/api/SparkPostApiClient.php +++ b/src/api/SparkPostApiClient.php @@ -10,6 +10,7 @@ /** * A really simple SparkPost api client * + * @link https://developers.sparkpost.com/api/ * @author LeKoala */ class SparkPostApiClient @@ -886,6 +887,66 @@ public function deleteRelayWebhook($id) return $this->makeRequest('relay-webhooks/' . $id, self::METHOD_DELETE); } + /** + * @link https://developers.sparkpost.com/api/suppression-list/#suppression-list-get-retrieve-a-suppression + * @param string $recipient + * @return array + */ + public function getSuppression($recipient) + { + return $this->makeRequest('suppression-list/' . $recipient, self::METHOD_GET); + } + + /** + * @link https://developers.sparkpost.com/api/suppression-list/#suppression-list-put-create-or-update-a-suppression + * @param string $recipient + * @param bool $isTransactional + * @param string $description + * @return array + */ + public function createSuppression($recipient, $isTransactional = true, $description = '') + { + return $this->makeRequest('suppression-list/' . $recipient, self::METHOD_PUT, [ + 'type' => $isTransactional ? 'transactional' : 'non_transactional', + 'description' => $description + ]); + } + + /** + * @param string $recipient + * @return array + */ + public function deleteSuppression($recipient) + { + return $this->makeRequest('suppression-list/' . $recipient, self::METHOD_DELETE); + } + + /** + * @link https://developers.sparkpost.com/api/suppression-list/#suppression-list-get-search-suppressions + * @param array{'from'?:string,'to'?:string,'domain'?:string,'sources'?:string,'types'?:string,'description'?:string} $params + * @return array + */ + public function searchSuppressions($params = []) + { + $defaultParams = [ + 'per_page' => 10, + 'from' => $this->createValidDatetime('-30 days'), + ]; + $params = array_merge($defaultParams, $params); + + return $this->makeRequest('suppression-list', self::METHOD_GET, $params); + } + + /** + * @link https://developers.sparkpost.com/api/suppression-list/#suppression-list-get-retrieve-summary + * @return array{"spam_complaint":int,"list_unsubscribe":int,"bounce_rule":int,"unsubscribe_link":int,"manually_added":int,"compliance":int,"total":int} + */ + public function suppressionSummary() + { + //@phpstan-ignore-next-line + return $this->makeRequest('suppression-list/summary', self::METHOD_GET); + } + /** * Create a valid date for the API *