Source of file SparkPostAdmin.php
Size: 32,428 Bytes - Last Modified: 2021-12-23T10:01:31+00:00
/var/www/docs.ssmods.com/process/src/src/SparkPostAdmin.php
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062 | <?php namespace LeKoala\SparkPost; use \Exception; use SilverStripe\Forms\Tab; use SilverStripe\Forms\Form; use SilverStripe\Forms\TabSet; use SilverStripe\ORM\ArrayLib; use SilverStripe\ORM\ArrayList; use SilverStripe\View\ArrayData; use SilverStripe\Control\Session; use SilverStripe\Forms\DateField; use SilverStripe\Forms\FieldList; use SilverStripe\Forms\FormField; use SilverStripe\Forms\TextField; use SilverStripe\Control\Director; use SilverStripe\Core\Environment; use SilverStripe\Forms\FormAction; use SilverStripe\Admin\LeftAndMain; use SilverStripe\Forms\HiddenField; use SilverStripe\Security\Security; use SilverStripe\View\ViewableData; use SilverStripe\Forms\LiteralField; use SilverStripe\Control\Email\Email; use SilverStripe\Forms\DropdownField; use SilverStripe\Security\Permission; use LeKoala\SparkPost\SparkPostHelper; use SilverStripe\Forms\CompositeField; use SilverStripe\SiteConfig\SiteConfig; use SilverStripe\Core\Injector\Injector; use SilverStripe\Control\Email\SwiftMailer; use SilverStripe\Forms\GridField\GridField; use SilverStripe\Security\PermissionProvider; use LeKoala\SparkPost\SparkPostSwiftTransport; use SilverStripe\Security\DefaultAdminService; use SilverStripe\Forms\GridField\GridFieldConfig; 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; /** * Allow you to see messages sent through the api key used to send messages * * @author LeKoala <thomas@lekoala.be> */ class SparkPostAdmin extends LeftAndMain implements PermissionProvider { const MESSAGE_CACHE_MINUTES = 5; const WEBHOOK_CACHE_MINUTES = 1440; // 1 day const SENDINGDOMAIN_CACHE_MINUTES = 1440; // 1 day private static $menu_title = "SparkPost"; private static $url_segment = "sparkpost"; private static $menu_icon = "sparkpost/images/sparkpost-icon.png"; private static $url_rule = '/$Action/$ID/$OtherID'; private static $allowed_actions = [ 'settings', 'SearchForm', 'doSearch', "doInstallHook", "doUninstallHook", "doInstallDomain", "doUninstallDomain", "send_test", ]; private static $cache_enabled = true; /** * @var bool */ protected $subaccountKey = false; /** * @var Exception */ protected $lastException; /** * @var ViewableData */ protected $currentMessage; /** * Inject public dependencies into the controller * * @var array */ private static $dependencies = [ 'logger' => '%$Psr\Log\LoggerInterface', 'cache' => '%$Psr\SimpleCache\CacheInterface.sparkpost', // see _config/cache.yml ]; /** * @var Psr\Log\LoggerInterface */ public $logger; /** * @var Psr\SimpleCache\CacheInterface */ public $cache; public function init() { parent::init(); if (isset($_GET['refresh'])) { $this->getCache()->clear(); } } public function index($request) { return parent::index($request); } public function settings($request) { return parent::index($request); } public function send_test($request) { if (!$this->CanConfigureApi()) { return $this->httpError(404); } $service = DefaultAdminService::create(); $to = $request->getVar('to'); if (!$to) { $to = $service->findOrCreateDefaultAdmin()->Email; } $email = Email::create(); $email->setSubject("Test email"); $email->setBody("Test " . date('Y-m-d H:i:s')); $email->setTo($to); $result = $email->send(); var_dump($result); } /** * @return Session */ public function getSession() { return $this->getRequest()->getSession(); } /** * Returns a GridField of messages * @return CMSForm */ public function getEditForm($id = null, $fields = null) { if (!$id) { $id = $this->currentPageID(); } $form = parent::getEditForm($id); $record = $this->getRecord($id); // Check if this record is viewable if ($record && !$record->canView()) { $response = Security::permissionFailure($this); $this->setResponse($response); return null; } // Build gridfield $messageListConfig = GridFieldConfig::create()->addComponents( new GridFieldSortableHeader(), new GridFieldDataColumns(), new GridFieldFooter() ); $messages = $this->Messages(); if (is_string($messages)) { // The api returned an error $messagesList = new LiteralField("MessageAlert", $this->MessageHelper($messages, 'bad')); } else { $messagesList = GridField::create( 'Messages', false, $messages, $messageListConfig )->addExtraClass("messages_grid"); /** @var GridFieldDataColumns $columns */ $columns = $messageListConfig->getComponentByType(GridFieldDataColumns::class); $columns->setDisplayFields([ 'transmission_id' => _t('SparkPostAdmin.EventTransmissionId', 'Id'), 'timestamp' => _t('SparkPostAdmin.EventDate', 'Date'), 'type' => _t('SparkPostAdmin.EventType', 'Type'), 'rcpt_to' => _t('SparkPostAdmin.EventRecipient', 'Recipient'), 'subject' => _t('SparkPostAdmin.EventSubject', 'Subject'), 'friendly_from' => _t('SparkPostAdmin.EventSender', 'Sender'), ]); $columns->setFieldFormatting([ 'timestamp' => function ($value, &$item) { return date('Y-m-d H:i:s', strtotime($value)); }, ]); // Validator setup $validator = null; if ($record && method_exists($record, 'getValidator')) { $validator = $record->getValidator(); } if ($validator) { /** @var GridFieldDetailForm $detailForm */ $detailForm = $messageListConfig->getComponentByType(GridFieldDetailForm::class); if ($detailForm) { $detailForm->setValidator($validator); } } } // Create tabs $messagesTab = new Tab( 'Messages', _t('SparkPostAdmin.Messages', 'Messages'), $this->SearchFields(), $messagesList, // necessary for tree node selection in LeftAndMain.EditForm.js new HiddenField('ID', false, 0) ); $fields = new FieldList([ $root = new TabSet('Root', $messagesTab) ]); if ($this->CanConfigureApi()) { $settingsTab = new Tab('Settings', _t('SparkPostAdmin.Settings', 'Settings')); $domainTabData = $this->DomainTab(); $settingsTab->push($domainTabData); // Show webhook options if not using a subaccount key if (!$this->subaccountKey) { $webhookTabData = $this->WebhookTab(); $settingsTab->push($webhookTabData); } $toolsHtml = '<h2>Tools</h2>'; // Show default from email $defaultEmail = SparkPostHelper::resolveDefaultFromEmail(); $toolsHtml .= "<p>Default sending email: " . $defaultEmail . " (" . SparkPostHelper::resolveDefaultFromEmailType() . ")</p>"; if (!SparkPostHelper::isEmailDomainReady($defaultEmail)) { $toolsHtml .= '<p style="color:red">The default email is not ready to send emails</p>'; } // Show constants if (SparkPostHelper::getEnvSendingDisabled()) { $toolsHtml .= '<p style="color:red">Sending is disabled by .env configuration</p>'; } if (SparkPostHelper::getEnvEnableLogging()) { $toolsHtml .= '<p style="color:orange">Logging is enabled by .env configuration</p>'; } if (SparkPostHelper::getEnvSubaccountId()) { $toolsHtml .= '<p style="color:orange">Using subaccount id</p>'; } if (SparkPostHelper::getEnvForceSender()) { $toolsHtml .= '<p style="color:orange">Sender is forced to ' . SparkPostHelper::getEnvForceSender() . '</p>'; } // Add a refresh button $toolsHtml .= $this->ButtonHelper( $this->Link() . '?refresh=true', _t('SparkPostAdmin.REFRESH', 'Force data refresh from the API') ); $toolsHtml = $this->FormGroupHelper($toolsHtml); $Tools = new LiteralField('Tools', $toolsHtml); $settingsTab->push($Tools); $fields->addFieldToTab('Root', $settingsTab); } // Tab nav in CMS is rendered through separate template $root->setTemplate('SilverStripe\\Forms\\CMSTabSet'); // Manage tabs state $actionParam = $this->getRequest()->param('Action'); if ($actionParam == 'setting') { $settingsTab->addExtraClass('ui-state-active'); } elseif ($actionParam == 'messages') { $messagesTab->addExtraClass('ui-state-active'); } $actions = new FieldList(); // Build replacement form $form = Form::create( $this, 'EditForm', $fields, new FieldList() )->setHTMLID('Form_EditForm'); $form->addExtraClass('cms-edit-form fill-height'); $form->setTemplate($this->getTemplatesWithSuffix('_EditForm')); $form->addExtraClass('ss-tabset cms-tabset ' . $this->BaseCSSClasses()); $form->setAttribute('data-pjax-fragment', 'CurrentForm'); $this->extend('updateEditForm', $form); return $form; } /** * Get logger * * @return Psr\Log\LoggerInterface */ public function getLogger() { return $this->logger; } /** * Get the cache * * @return Psr\SimpleCache\CacheInterface */ public function getCache() { return $this->cache; } /** * @return boolean */ public function getCacheEnabled() { if (isset($_GET['disable_cache'])) { return false; } if (Environment::getEnv('SPARKPOST_DISABLE_CACHE')) { return false; } $v = $this->config()->cache_enabled; if ($v === null) { $v = self::$cache_enabled; } return $v; } /** * A simple cache helper * * @param string $method * @param array $params * @param int $expireInSeconds * @return array */ protected function getCachedData($method, $params, $expireInSeconds = 60) { $enabled = $this->getCacheEnabled(); if ($enabled) { $cache = $this->getCache(); $key = md5(serialize($params)); $cacheResult = $cache->get($key); } if ($enabled && $cacheResult) { $data = unserialize($cacheResult); } else { try { $client = SparkPostHelper::getClient(); $data = $client->$method($params); } catch (Exception $ex) { $this->lastException = $ex; $this->getLogger()->debug($ex); $data = false; } //5 minutes cache if ($enabled) { $cache->set($key, serialize($data), $expireInSeconds); } } return $data; } public function getParams() { $params = $this->config()->default_search_params; if (!$params) { $params = []; } $data = $this->getSession()->get(__class__ . '.Search'); if (!$data) { $data = []; } $params = array_merge($params, $data); // Respect api formats if (!empty($params['to'])) { $params['to'] = date('Y-m-d', strtotime(str_replace('/', '-', $params['to']))) . 'T00:00'; } if (!empty($params['from'])) { $params['from'] = date('Y-m-d', strtotime(str_replace('/', '-', $params['from']))) . 'T23:59'; } $params = array_filter($params); return $params; } public function getParam($name, $default = null) { $data = $this->getSession()->get(__class__ . '.Search'); if (!$data) { return $default; } return (isset($data[$name]) && strlen($data[$name])) ? $data[$name] : $default; } public function SearchFields() { $disabled_filters = $this->config()->disabled_search_filters; if (!$disabled_filters) { $disabled_filters = []; } $fields = new CompositeField(); $fields->push($from = new DateField('params[from]', _t('SparkPostAdmin.DATEFROM', 'From'), $this->getParam('from'))); // $from->setConfig('min', date('Y-m-d', strtotime('-10 days'))); $fields->push(new DateField('params[to]', _t('SparkPostAdmin.DATETO', 'To'), $to = $this->getParam('to'))); if (!in_array('friendly_froms', $disabled_filters)) { $fields->push($friendly_froms = new TextField('params[friendly_froms]', _t('SparkPostAdmin.FRIENDLYFROM', 'Sender'), $this->getParam('friendly_froms'))); $friendly_froms->setAttribute('placeholder', 'sender@mail.example.com,other@example.com'); } if (!in_array('recipients', $disabled_filters)) { $fields->push($recipients = new TextField('params[recipients]', _t('SparkPostAdmin.RECIPIENTS', 'Recipients'), $this->getParam('recipients'))); $recipients->setAttribute('placeholder', 'recipient@example.com,other@example.com'); } // Only allow filtering by subaccount if a master key is defined if (SparkPostHelper::config()->master_api_key && !in_array('subaccounts', $disabled_filters)) { $fields->push($subaccounts = new TextField('params[subaccounts]', _t('SparkPostAdmin.SUBACCOUNTS', 'Subaccounts'), $this->getParam('subaccounts'))); $subaccounts->setAttribute('placeholder', '101,102'); } $fields->push(new DropdownField('params[per_page]', _t('SparkPostAdmin.PERPAGE', 'Number of results'), array( 100 => 100, 500 => 500, 1000 => 1000, 10000 => 10000, ), $this->getParam('per_page', 100))); foreach ($fields->FieldList() as $field) { $field->addExtraClass('no-change-track'); } // This is a ugly hack to allow embedding a form into another form $fields->push($doSearch = new FormAction('doSearch', _t('SparkPostAdmin.DOSEARCH', 'Search'))); $doSearch->addExtraClass("btn-primary"); $doSearch->setAttribute('onclick', "jQuery('#Form_SearchForm').append(jQuery('#Form_EditForm input,#Form_EditForm select').clone()).submit();"); return $fields; } public function SearchForm() { $SearchForm = new Form($this, 'SearchForm', new FieldList(), new FieldList([ new FormAction('doSearch') ])); $SearchForm->setAttribute('style', 'display:none'); return $SearchForm; } public function doSearch($data, Form $form) { $post = $this->getRequest()->postVar('params'); if (!$post) { return $this->redirectBack(); } $params = []; $validFields = []; foreach ($this->SearchFields()->FieldList()->dataFields() as $field) { $validFields[] = str_replace(['params[', ']'], '', $field->getName()); } foreach ($post as $k => $v) { if (in_array($k, $validFields)) { $params[$k] = $v; } } $this->getSession()->set(__class__ . '.Search', $params); $this->getSession()->save($this->getRequest()); return $this->redirectBack(); } /** * List of messages events * * Messages are cached to avoid hammering the api * * @return ArrayList|string */ public function Messages() { $params = $this->getParams(); $messages = $this->getCachedData('searchEvents', $params, 60 * self::MESSAGE_CACHE_MINUTES); if ($messages === false) { if ($this->lastException) { return $this->lastException->getMessage(); } return _t('SparkpostAdmin.NO_MESSAGES', 'No messages'); } // Consolidate Subject/Sender for open and click events $transmissions = []; foreach ($messages as $message) { if (empty($message['transmission_id']) || empty($message['subject'])) { continue; } if (isset($transmissions[$message['transmission_id']])) { continue; } $transmissions[$message['transmission_id']] = $message; } $list = new ArrayList(); if ($messages) { foreach ($messages as $message) { // If we have a transmission id but no subject, try to find the transmission details if (isset($message['transmission_id']) && empty($message['subject']) && isset($transmissions[$message['transmission_id']])) { $message = array_merge($transmissions[$message['transmission_id']], $message); } // In some case (errors, etc) we don't have a friendly from if (empty($message['friendly_from']) && isset($message['msg_from'])) { $message['friendly_from'] = $message['msg_from']; } $m = new ArrayData($message); $list->push($m); } } return $list; } /** * Provides custom permissions to the Security section * * @return array */ public function providePermissions() { $title = _t("SparkPostAdmin.MENUTITLE", LeftAndMain::menu_title_for_class('SparkPost')); return [ "CMS_ACCESS_SparkPost" => [ 'name' => _t('SparkPostAdmin.ACCESS', "Access to '{title}' section", ['title' => $title]), 'category' => _t('Permission.CMS_ACCESS_CATEGORY', 'CMS Access'), 'help' => _t( 'SparkPostAdmin.ACCESS_HELP', 'Allow use of SparkPost admin section' ) ], ]; } /** * Message helper * * @param string $message * @param string $status * @return string */ protected function MessageHelper($message, $status = 'info') { return '<div class="message ' . $status . '">' . $message . '</div>'; } /** * Button helper * * @param string $link * @param string $text * @param boolean $confirm * @return string */ protected function ButtonHelper($link, $text, $confirm = false) { $link = '<a class="btn btn-primary" href="' . $link . '"'; if ($confirm) { $link .= ' onclick="return confirm(\'' . _t('SparkPostAdmin.CONFIRM_MSG', 'Are you sure?') . '\')"'; } $link .= '>' . $text . '</a>'; return $link; } /** * Wrap html in a form group * * @param string $html * @return string */ protected function FormGroupHelper($html) { return '<div class="form-group"><div class="form__fieldgroup form__field-holder form__field-holder--no-label">' . $html . '</div></div>'; } /** * A template accessor to check the ADMIN permission * * @return bool */ public function IsAdmin() { return Permission::check("ADMIN"); } /** * Check the permission for current user * * @return bool */ public function canView($member = null) { $mailer = SparkPostHelper::getMailer(); // Another custom mailer has been set if (!$mailer instanceof SwiftMailer) { return false; } // Doesn't use the proper transport if (!$mailer->getSwiftMailer()->getTransport() instanceof SparkPostSwiftTransport) { return false; } return Permission::check("CMS_ACCESS_SparkPost", 'any', $member); } /** * * @return bool */ public function CanConfigureApi() { return Permission::check('ADMIN') || Director::isDev(); } /** * Check if webhook is installed * * @return array */ public function WebhookInstalled() { $list = $this->getCachedData('listAllWebhooks', null, 60 * self::WEBHOOK_CACHE_MINUTES); if (empty($list)) { return false; } $url = $this->WebhookUrl(); foreach ($list as $el) { if (!empty($el['target']) && $el['target'] === $url) { return $el; } } return false; } /** * Hook details for template * @return \ArrayData */ public function WebhookDetails() { $el = $this->WebhookInstalled(); if ($el) { return new ArrayData($el); } } /** * Get content of the tab * * @return FormField */ public function WebhookTab() { if ($this->WebhookInstalled()) { return $this->UninstallHookForm(); } return $this->InstallHookForm(); } /** * @return string */ public function WebhookUrl() { if (self::config()->webhook_base_url) { return rtrim(self::config()->webhook_base_url, '/') . '/sparkpost/incoming'; } if (Director::isLive()) { return Director::absoluteURL('/sparkpost/incoming'); } $protocol = Director::protocol(); return $protocol . $this->getDomain() . '/sparkpost/incoming'; } /** * Install hook form * * @return FormField */ public function InstallHookForm() { $fields = new CompositeField(); $fields->push(new LiteralField('Info', $this->MessageHelper( _t('SparkPostAdmin.WebhookNotInstalled', 'Webhook is not installed. It should be configured using the following url {url}. This url must be publicly visible to be used as a hook.', ['url' => $this->WebhookUrl()]), 'bad' ))); $fields->push(new LiteralField('doInstallHook', $this->ButtonHelper( $this->Link('doInstallHook'), _t('SparkPostAdmin.DOINSTALL_WEBHOOK', 'Install webhook') ))); return $fields; } public function doInstallHook() { if (!$this->CanConfigureApi()) { return $this->redirectBack(); } $client = SparkPostHelper::getClient(); $url = $this->WebhookUrl(); $description = SiteConfig::current_site_config()->Title; $defaultAdmin = Environment::getEnv('SS_DEFAULT_ADMIN_USERNAME'); $defaultPassword = Environment::getEnv('SS_DEFAULT_ADMIN_PASSWORD'); try { if ($defaultAdmin) { $client->createSimpleWebhook($description, $url, null, true, ['username' => $defaultAdmin, 'password' => $defaultPassword]); } else { $client->createSimpleWebhook($description, $url); } $this->getCache()->clear(); } catch (Exception $ex) { $this->getLogger()->debug($ex); } return $this->redirectBack(); } /** * Uninstall hook form * * @return FormField */ public function UninstallHookForm() { $fields = new CompositeField(); $fields->push(new LiteralField('Info', $this->MessageHelper( _t('SparkPostAdmin.WebhookInstalled', 'Webhook is installed and accessible at the following url {url}.', ['url' => $this->WebhookUrl()]), 'good' ))); $fields->push(new LiteralField('doUninstallHook', $this->ButtonHelper( $this->Link('doUninstallHook'), _t('SparkPostAdmin.DOUNINSTALL_WEBHOOK', 'Uninstall webhook'), true ))); return $fields; } public function doUninstallHook($data, Form $form) { if (!$this->CanConfigureApi()) { return $this->redirectBack(); } $client = SparkPostHelper::getClient(); try { $el = $this->WebhookInstalled(); if ($el && !empty($el['id'])) { $client->deleteWebhook($el['id']); } $this->getCache()->clear(); } catch (Exception $ex) { $this->getLogger()->debug($ex); } return $this->redirectBack(); } /** * Check if sending domain is installed * * @return array */ public function SendingDomainInstalled() { $domain = $this->getCachedData('getSendingDomain', $this->getDomain(), 60 * self::SENDINGDOMAIN_CACHE_MINUTES); if (empty($domain)) { return false; } return $domain; } /** * Trigger request to check if sending domain is verified * * @return array */ public function VerifySendingDomain() { $client = SparkPostHelper::getClient(); $host = $this->getDomain(); $verification = $client->verifySendingDomain($host); if (empty($verification)) { return false; } return $verification; } /** * Get content of the tab * * @return FormField */ public function DomainTab() { $defaultDomain = $this->getDomain(); $defaultDomainInfos = null; $domains = $this->getCachedData('listAllSendingDomains', null, 60 * self::SENDINGDOMAIN_CACHE_MINUTES); $fields = new CompositeField(); $list = new ArrayList(); if ($domains) { foreach ($domains as $domain) { // We are using a subaccount api key if (!isset($domain['shared_with_subaccounts'])) { $this->subaccountKey = true; } $list->push(new ArrayData([ 'Domain' => $domain['domain'], 'SPF' => $domain['status']['spf_status'], 'DKIM' => $domain['status']['dkim_status'], 'Compliance' => $domain['status']['compliance_status'], 'Verified' => $domain['status']['ownership_verified'], ])); if ($domain['domain'] == $defaultDomain) { $defaultDomainInfos = $domain; } } } $config = GridFieldConfig::create(); $config->addComponent(new GridFieldToolbarHeader()); $config->addComponent(new GridFieldTitleHeader()); $config->addComponent($columns = new GridFieldDataColumns()); $columns->setDisplayFields(ArrayLib::valuekey(['Domain', 'SPF', 'DKIM', 'Compliance', 'Verified'])); $domainsList = new GridField('SendingDomains', _t('SparkPostAdmin.ALL_SENDING_DOMAINS', 'Configured sending domains'), $list, $config); $domainsList->addExtraClass('mb-2'); $fields->push($domainsList); if (!$defaultDomainInfos) { $this->InstallDomainForm($fields); } else { $this->UninstallDomainForm($fields); } return $fields; } /** * @return string */ public function InboundUrl() { $subdomain = self::config()->inbound_subdomain; $domain = $this->getDomain(); if ($domain) { return $subdomain . '.' . $domain; } return false; } /** * Get domain name from current host * * @return boolean|string */ public function getDomainFromHost() { $base = Environment::getEnv('SS_BASE_URL'); if (!$base) { $base = Director::protocolAndHost(); } $host = parse_url($base, PHP_URL_HOST); $hostParts = explode('.', $host); $parts = count($hostParts); if ($parts < 2) { return false; } $domain = $hostParts[$parts - 2] . "." . $hostParts[$parts - 1]; return $domain; } /** * Get domain from admin email * * @return boolean|string */ public function getDomainFromEmail() { $email = SparkPostHelper::resolveDefaultFromEmail(null, false); if ($email) { $domain = substr(strrchr($email, "@"), 1); return $domain; } return false; } /** * Get domain * * @return boolean|string */ public function getDomain() { $domain = $this->getDomainFromEmail(); if (!$domain) { return $this->getDomainFromHost(); } return $domain; } /** * Install domain form * * @param CompositeField $fieldsd * @return FormField */ public function InstallDomainForm(CompositeField $fields) { $host = $this->getDomain(); $fields->push(new LiteralField('Info', $this->MessageHelper( _t('SparkPostAdmin.DomainNotInstalled', 'Default sending domain {domain} is not installed.', ['domain' => $host]), "bad" ))); $fields->push(new LiteralField('doInstallDomain', $this->ButtonHelper( $this->Link('doInstallDomain'), _t('SparkPostAdmin.DOINSTALLDOMAIN', 'Install domain') ))); } public function doInstallDomain() { if (!$this->CanConfigureApi()) { return $this->redirectBack(); } $client = SparkPostHelper::getClient(); $domain = $this->getDomain(); if (!$domain) { return $this->redirectBack(); } try { $client->createSimpleSendingDomain($domain); $this->getCache()->clear(); } catch (Exception $ex) { $this->getLogger()->debug($ex); } return $this->redirectBack(); } /** * Uninstall domain form * * @param CompositeField $fieldsd * @return FormField */ public function UninstallDomainForm(CompositeField $fields) { $domainInfos = $this->SendingDomainInstalled(); $domain = $this->getDomain(); if ($domainInfos && $domainInfos['status']['ownership_verified']) { $fields->push(new LiteralField('Info', $this->MessageHelper( _t('SparkPostAdmin.DomainInstalled', 'Default domain {domain} is installed.', ['domain' => $domain]), 'good' ))); } else { $fields->push(new LiteralField('Info', $this->MessageHelper( _t('SparkPostAdmin.DomainInstalledBut', 'Default domain {domain} is installed, but is not properly configured.'), 'warning' ))); } $fields->push(new LiteralField('doUninstallHook', $this->ButtonHelper( $this->Link('doUninstallHook'), _t('SparkPostAdmin.DOUNINSTALLDOMAIN', 'Uninstall domain'), true ))); } public function doUninstallDomain($data, Form $form) { if (!$this->CanConfigureApi()) { return $this->redirectBack(); } $client = SparkPostHelper::getClient(); $domain = $this->getDomain(); if (!$domain) { return $this->redirectBack(); } try { $el = $this->SendingDomainInstalled(); if ($el) { $client->deleteSendingDomain($domain); } $this->getCache()->clear(); } catch (Exception $ex) { $this->getLogger()->debug($ex); } return $this->redirectBack(); } } |