Add Premium key validation [PREMIUM-4]
This commit is contained in:
@ -64,4 +64,57 @@ class Services extends APIEndpoint {
|
||||
|
||||
return $this->errorResponse(array(APIError::BAD_REQUEST => $error));
|
||||
}
|
||||
|
||||
function verifyPremiumKey($data = array()) {
|
||||
$key = isset($data['key']) ? trim($data['key']) : null;
|
||||
|
||||
if(!$key) {
|
||||
return $this->badRequest(array(
|
||||
APIError::BAD_REQUEST => __('Please specify a key.', 'mailpoet')
|
||||
));
|
||||
}
|
||||
|
||||
try {
|
||||
$result = $this->bridge->checkPremiumKey($key);
|
||||
} catch(\Exception $e) {
|
||||
return $this->errorResponse(array(
|
||||
$e->getCode() => $e->getMessage()
|
||||
));
|
||||
}
|
||||
|
||||
$state = !empty($result['state']) ? $result['state'] : null;
|
||||
|
||||
$success_message = null;
|
||||
if($state == Bridge::PREMIUM_KEY_VALID) {
|
||||
$success_message = __('Your Premium API key is valid!', 'mailpoet');
|
||||
} elseif($state == Bridge::PREMIUM_KEY_EXPIRING) {
|
||||
$success_message = sprintf(
|
||||
__('Your Premium key expires on %s!', 'mailpoet'),
|
||||
Carbon::createFromTimestamp(strtotime($result['data']['expire_at']))
|
||||
->format('Y-m-d')
|
||||
);
|
||||
}
|
||||
|
||||
if($success_message) {
|
||||
return $this->successResponse(array('message' => $success_message));
|
||||
}
|
||||
|
||||
switch($state) {
|
||||
case Bridge::PREMIUM_KEY_INVALID:
|
||||
$error = __('Your Premium key is invalid!', 'mailpoet');
|
||||
break;
|
||||
case Bridge::PREMIUM_KEY_USED:
|
||||
$error = __('Your Premium key is already used on another site!', 'mailpoet');
|
||||
break;
|
||||
default:
|
||||
$code = !empty($result['code']) ? $result['code'] : Bridge::CHECK_ERROR_UNKNOWN;
|
||||
$error = sprintf(
|
||||
__('Error validating Premium key, please try again later (code: %s)', 'mailpoet'),
|
||||
$code
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
return $this->errorResponse(array(APIError::BAD_REQUEST => $error));
|
||||
}
|
||||
}
|
@ -3,7 +3,6 @@ namespace MailPoet\API\Endpoints\v1;
|
||||
|
||||
use MailPoet\API\Endpoint as APIEndpoint;
|
||||
use MailPoet\API\Error as APIError;
|
||||
use MailPoet\Mailer\Mailer as MailerConfig;
|
||||
use MailPoet\Models\Setting;
|
||||
use MailPoet\Services\Bridge;
|
||||
|
||||
@ -24,13 +23,8 @@ class Settings extends APIEndpoint {
|
||||
foreach($settings as $name => $value) {
|
||||
Setting::setValue($name, $value);
|
||||
}
|
||||
if(!empty($settings[MailerConfig::MAILER_CONFIG_SETTING_NAME]['mailpoet_api_key'])
|
||||
&& Bridge::isMPSendingServiceEnabled()
|
||||
) {
|
||||
$bridge = new Bridge();
|
||||
$result = $bridge->checkKey($settings[MailerConfig::MAILER_CONFIG_SETTING_NAME]['mailpoet_api_key']);
|
||||
$bridge->updateSubscriberCount($result);
|
||||
}
|
||||
$bridge->onSettingsSave($settings);
|
||||
return $this->successResponse(Setting::getAll());
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ use MailPoet\Settings\Hosts;
|
||||
use MailPoet\Settings\Pages;
|
||||
use MailPoet\Subscribers\ImportExport\ImportExportFactory;
|
||||
use MailPoet\Util\License\Features\Subscribers as SubscribersFeature;
|
||||
use MailPoet\Util\License\License;
|
||||
use MailPoet\WP\DateTime;
|
||||
use MailPoet\WP\Notice as WPNotice;
|
||||
use MailPoet\WP\Readme;
|
||||
@ -28,6 +29,7 @@ class Menu {
|
||||
$subscribers_feature = new SubscribersFeature();
|
||||
$this->subscribers_over_limit = $subscribers_feature->check();
|
||||
$this->checkMailPoetAPIKey();
|
||||
$this->checkPremiumKey();
|
||||
}
|
||||
|
||||
function init() {
|
||||
@ -308,6 +310,8 @@ class Menu {
|
||||
'segments' => Segment::getSegmentsWithSubscriberCount(),
|
||||
'cron_trigger' => CronTrigger::getAvailableMethods(),
|
||||
'total_subscribers' => Subscriber::getTotalSubscribers(),
|
||||
'premium_plugin_active' => License::getLicense(),
|
||||
'premium_key_valid' => isset($this->premium_key_valid) ? $this->premium_key_valid : null,
|
||||
'pages' => Pages::getAll(),
|
||||
'flags' => $flags,
|
||||
'current_user' => wp_get_current_user(),
|
||||
@ -525,6 +529,15 @@ class Menu {
|
||||
}
|
||||
}
|
||||
|
||||
function checkPremiumKey(ServicesChecker $checker = null) {
|
||||
if(self::isOnMailPoetAdminPage()) {
|
||||
$show_notices = isset($_REQUEST['page'])
|
||||
&& stripos($_REQUEST['page'], 'mailpoet-newsletters') === false;
|
||||
$checker = $checker ?: new ServicesChecker();
|
||||
$this->premium_key_valid = $checker->isPremiumKeyValid($show_notices);
|
||||
}
|
||||
}
|
||||
|
||||
private function getLimitPerPage($model = null) {
|
||||
if($model === null) {
|
||||
return Listing\Handler::DEFAULT_LIMIT_PER_PAGE;
|
||||
|
@ -5,6 +5,7 @@ use MailPoet\Models\Setting;
|
||||
use MailPoet\Models\Subscriber;
|
||||
use MailPoet\Services\Bridge;
|
||||
use MailPoet\Util\Helpers;
|
||||
use MailPoet\Util\License\License;
|
||||
use MailPoet\WP\Notice as WPNotice;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
@ -46,4 +47,44 @@ class ServicesChecker {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function isPremiumKeyValid($display_error_notice = true) {
|
||||
if(!Bridge::isPremiumKeySpecified()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$premium_plugin_active = License::getLicense();
|
||||
$result = Setting::getValue(Bridge::PREMIUM_KEY_STATE_SETTING_NAME);
|
||||
if(empty($result['state']) || $result['state'] == Bridge::PREMIUM_KEY_VALID) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if($result['state'] == Bridge::PREMIUM_KEY_INVALID
|
||||
|| $result['state'] == Bridge::PREMIUM_KEY_USED
|
||||
) {
|
||||
$error = Helpers::replaceLinkTags(
|
||||
__('Warning! Your License Key is either invalid or expired. [link]Renew your License now[/link] to enjoy automatic updates and Premium support.', 'mailpoet'),
|
||||
'https://account.mailpoet.com'
|
||||
);
|
||||
if($premium_plugin_active && $display_error_notice) {
|
||||
WPNotice::displayError($error);
|
||||
}
|
||||
return false;
|
||||
} elseif($result['state'] == Bridge::PREMIUM_KEY_EXPIRING
|
||||
&& !empty($result['data']['expire_at'])
|
||||
) {
|
||||
$date = date('Y-m-d', strtotime($result['data']['expire_at']));
|
||||
$error = Helpers::replaceLinkTags(
|
||||
__('Your License Key is expiring! Don\'t forget to [link]renew your license[/link] by %s to keep enjoying automatic updates and Premium support.', 'mailpoet'),
|
||||
'https://account.mailpoet.com'
|
||||
);
|
||||
$error = sprintf($error, $date);
|
||||
if($premium_plugin_active && $display_error_notice) {
|
||||
WPNotice::displayWarning($error);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ namespace MailPoet\Cron;
|
||||
use MailPoet\Cron\Workers\Scheduler as SchedulerWorker;
|
||||
use MailPoet\Cron\Workers\SendingQueue\SendingQueue as SendingQueueWorker;
|
||||
use MailPoet\Cron\Workers\Bounce as BounceWorker;
|
||||
use MailPoet\Cron\Workers\PremiumKeyCheck as PremiumKeyCheckWorker;
|
||||
use MailPoet\Cron\Workers\SendingServiceKeyCheck as SendingServiceKeyCheckWorker;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
@ -50,6 +51,7 @@ class Daemon {
|
||||
$this->executeScheduleWorker();
|
||||
$this->executeQueueWorker();
|
||||
$this->executeSendingServiceKeyCheckWorker();
|
||||
$this->executePremiumKeyCheckWorker();
|
||||
$this->executeBounceWorker();
|
||||
} catch(\Exception $e) {
|
||||
// continue processing, no need to handle errors
|
||||
@ -87,6 +89,11 @@ class Daemon {
|
||||
return $worker->process();
|
||||
}
|
||||
|
||||
function executePremiumKeyCheckWorker() {
|
||||
$worker = new PremiumKeyCheckWorker($this->timer);
|
||||
return $worker->process();
|
||||
}
|
||||
|
||||
function executeBounceWorker() {
|
||||
$bounce = new BounceWorker($this->timer);
|
||||
return $bounce->process();
|
||||
|
@ -5,6 +5,7 @@ use MailPoet\Cron\CronHelper;
|
||||
use MailPoet\Cron\Workers\Scheduler as SchedulerWorker;
|
||||
use MailPoet\Cron\Workers\SendingQueue\SendingQueue as SendingQueueWorker;
|
||||
use MailPoet\Cron\Workers\Bounce as BounceWorker;
|
||||
use MailPoet\Cron\Workers\PremiumKeyCheck as PremiumKeyCheckWorker;
|
||||
use MailPoet\Cron\Workers\SendingServiceKeyCheck as SendingServiceKeyCheckWorker;
|
||||
use MailPoet\Mailer\MailerLog;
|
||||
use MailPoet\Services\Bridge;
|
||||
@ -32,12 +33,17 @@ class WordPress {
|
||||
// sending service key check
|
||||
$sskeycheck_due_queues = SendingServiceKeyCheckWorker::getAllDueQueues();
|
||||
$sskeycheck_future_queues = SendingServiceKeyCheckWorker::getFutureQueues();
|
||||
// premium key check
|
||||
$premium_key_specified = Bridge::isPremiumKeySpecified();
|
||||
$premium_keycheck_due_queues = PremiumKeyCheckWorker::getAllDueQueues();
|
||||
$premium_keycheck_future_queues = PremiumKeyCheckWorker::getFutureQueues();
|
||||
// check requirements for each worker
|
||||
$sending_queue_active = (($scheduled_queues || $running_queues) && !$sending_limit_reached && !$sending_is_paused);
|
||||
$bounce_sync_active = ($mp_sending_enabled && ($bounce_due_queues || !$bounce_future_queues));
|
||||
$sending_service_key_check_active = ($mp_sending_enabled && ($sskeycheck_due_queues || !$sskeycheck_future_queues));
|
||||
$premium_key_check_active = ($premium_key_specified && ($premium_keycheck_due_queues || !$premium_keycheck_future_queues));
|
||||
|
||||
return ($sending_queue_active || $bounce_sync_active || $sending_service_key_check_active);
|
||||
return ($sending_queue_active || $bounce_sync_active || $sending_service_key_check_active || $premium_key_check_active);
|
||||
}
|
||||
|
||||
static function cleanup() {
|
||||
|
146
lib/Cron/Workers/PremiumKeyCheck.php
Normal file
146
lib/Cron/Workers/PremiumKeyCheck.php
Normal file
@ -0,0 +1,146 @@
|
||||
<?php
|
||||
namespace MailPoet\Cron\Workers;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use MailPoet\Cron\CronHelper;
|
||||
use MailPoet\Models\SendingQueue;
|
||||
use MailPoet\Models\Setting;
|
||||
use MailPoet\Services\Bridge;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
|
||||
class PremiumKeyCheck {
|
||||
const TASK_TYPE = 'premium_key_check';
|
||||
const UNAVAILABLE_SERVICE_RESCHEDULE_TIMEOUT = 60;
|
||||
|
||||
public $timer;
|
||||
public $bridge;
|
||||
|
||||
function __construct($timer = false) {
|
||||
$this->timer = ($timer) ? $timer : microtime(true);
|
||||
// abort if execution limit is reached
|
||||
CronHelper::enforceExecutionLimit($this->timer);
|
||||
}
|
||||
|
||||
function initApi() {
|
||||
if(!$this->bridge) {
|
||||
$this->bridge = new Bridge();
|
||||
}
|
||||
}
|
||||
|
||||
function process() {
|
||||
if(!Bridge::isPremiumKeySpecified()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->initApi();
|
||||
|
||||
$scheduled_queues = self::getScheduledQueues();
|
||||
$running_queues = self::getRunningQueues();
|
||||
|
||||
if(!$scheduled_queues && !$running_queues) {
|
||||
self::schedule();
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach($scheduled_queues as $i => $queue) {
|
||||
$this->prepareQueue($queue);
|
||||
}
|
||||
foreach($running_queues as $i => $queue) {
|
||||
$this->processQueue($queue);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static function schedule() {
|
||||
$already_scheduled = SendingQueue::where('type', self::TASK_TYPE)
|
||||
->whereNull('deleted_at')
|
||||
->where('status', SendingQueue::STATUS_SCHEDULED)
|
||||
->findMany();
|
||||
if($already_scheduled) {
|
||||
return false;
|
||||
}
|
||||
$queue = SendingQueue::create();
|
||||
$queue->type = self::TASK_TYPE;
|
||||
$queue->status = SendingQueue::STATUS_SCHEDULED;
|
||||
$queue->priority = SendingQueue::PRIORITY_LOW;
|
||||
$queue->scheduled_at = self::getNextRunDate();
|
||||
$queue->newsletter_id = 0;
|
||||
$queue->save();
|
||||
return $queue;
|
||||
}
|
||||
|
||||
function prepareQueue(SendingQueue $queue) {
|
||||
$queue->status = null;
|
||||
$queue->save();
|
||||
|
||||
// abort if execution limit is reached
|
||||
CronHelper::enforceExecutionLimit($this->timer);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function processQueue(SendingQueue $queue) {
|
||||
// abort if execution limit is reached
|
||||
CronHelper::enforceExecutionLimit($this->timer);
|
||||
|
||||
try {
|
||||
$premium_key = Setting::getValue(Bridge::PREMIUM_KEY_STATE_SETTING_NAME);
|
||||
$result = $this->bridge->checkPremiumKey($premium_key);
|
||||
} catch (\Exception $e) {
|
||||
$result = false;
|
||||
}
|
||||
|
||||
if(empty($result['code']) || $result['code'] == Bridge::CHECK_ERROR_UNAVAILABLE) {
|
||||
// reschedule the check
|
||||
$scheduled_at = Carbon::createFromTimestamp(current_time('timestamp'));
|
||||
$queue->scheduled_at = $scheduled_at->addMinutes(
|
||||
self::UNAVAILABLE_SERVICE_RESCHEDULE_TIMEOUT
|
||||
);
|
||||
$queue->save();
|
||||
return false;
|
||||
}
|
||||
|
||||
$queue->processed_at = current_time('mysql');
|
||||
$queue->status = SendingQueue::STATUS_COMPLETED;
|
||||
$queue->save();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static function getNextRunDate() {
|
||||
$date = Carbon::createFromTimestamp(current_time('timestamp'));
|
||||
// Random day of the next week
|
||||
$date->setISODate($date->format('o'), $date->format('W') + 1, mt_rand(1, 7));
|
||||
$date->startOfDay();
|
||||
return $date;
|
||||
}
|
||||
|
||||
static function getScheduledQueues($future = false) {
|
||||
$dateWhere = ($future) ? 'whereGt' : 'whereLte';
|
||||
return SendingQueue::where('type', self::TASK_TYPE)
|
||||
->$dateWhere('scheduled_at', Carbon::createFromTimestamp(current_time('timestamp')))
|
||||
->whereNull('deleted_at')
|
||||
->where('status', SendingQueue::STATUS_SCHEDULED)
|
||||
->findMany();
|
||||
}
|
||||
|
||||
static function getRunningQueues() {
|
||||
return SendingQueue::where('type', self::TASK_TYPE)
|
||||
->whereLte('scheduled_at', Carbon::createFromTimestamp(current_time('timestamp')))
|
||||
->whereNull('deleted_at')
|
||||
->whereNull('status')
|
||||
->findMany();
|
||||
}
|
||||
|
||||
static function getAllDueQueues() {
|
||||
$scheduled_queues = self::getScheduledQueues();
|
||||
$running_queues = self::getRunningQueues();
|
||||
return array_merge((array)$scheduled_queues, (array)$running_queues);
|
||||
}
|
||||
|
||||
static function getFutureQueues() {
|
||||
return self::getScheduledQueues(true);
|
||||
}
|
||||
}
|
@ -9,6 +9,7 @@ if(!defined('ABSPATH')) exit;
|
||||
|
||||
class Bridge {
|
||||
const API_KEY_STATE_SETTING_NAME = 'mta.mailpoet_api_key_state';
|
||||
const PREMIUM_KEY_STATE_SETTING_NAME = 'premium.premium_key_state';
|
||||
|
||||
const MAILPOET_KEY_VALID = 'valid';
|
||||
const MAILPOET_KEY_INVALID = 'invalid';
|
||||
@ -16,6 +17,13 @@ class Bridge {
|
||||
|
||||
const MAILPOET_KEY_CHECK_ERROR = 'check_error';
|
||||
|
||||
const PREMIUM_KEY_VALID = 'valid';
|
||||
const PREMIUM_KEY_INVALID = 'invalid';
|
||||
const PREMIUM_KEY_EXPIRING = 'expiring';
|
||||
const PREMIUM_KEY_USED = 'used';
|
||||
|
||||
const PREMIUM_KEY_CHECK_ERROR = 'check_error';
|
||||
|
||||
const CHECK_ERROR_UNAVAILABLE = 503;
|
||||
const CHECK_ERROR_UNKNOWN = 'unknown';
|
||||
|
||||
@ -31,6 +39,11 @@ class Bridge {
|
||||
}
|
||||
}
|
||||
|
||||
static function isPremiumKeySpecified() {
|
||||
$key = Setting::getValue(self::PREMIUM_KEY_STATE_SETTING_NAME);
|
||||
return !empty($key);
|
||||
}
|
||||
|
||||
function initApi($api_key) {
|
||||
if($this->api) {
|
||||
$this->api->setKey($api_key);
|
||||
@ -77,6 +90,50 @@ class Bridge {
|
||||
return $state;
|
||||
}
|
||||
|
||||
function checkPremiumKey($key) {
|
||||
$this->initApi($key);
|
||||
$result = $this->api->checkPremiumKey();
|
||||
return $this->processPremiumKeyCheckResult($result);
|
||||
}
|
||||
|
||||
function processPremiumKeyCheckResult(array $result) {
|
||||
$state_map = array(
|
||||
200 => self::PREMIUM_KEY_VALID,
|
||||
401 => self::PREMIUM_KEY_INVALID,
|
||||
402 => self::PREMIUM_KEY_USED
|
||||
);
|
||||
|
||||
$update_settings = false;
|
||||
|
||||
if(!empty($result['code']) && isset($state_map[$result['code']])) {
|
||||
if($result['code'] == self::PREMIUM_KEY_VALID
|
||||
&& !empty($result['data']['expire_at'])
|
||||
) {
|
||||
$key_state = self::PREMIUM_KEY_EXPIRING;
|
||||
} else {
|
||||
$key_state = $state_map[$result['code']];
|
||||
}
|
||||
$update_settings = true;
|
||||
} else {
|
||||
$key_state = self::PREMIUM_KEY_CHECK_ERROR;
|
||||
}
|
||||
|
||||
$state = array(
|
||||
'state' => $key_state,
|
||||
'data' => !empty($result['data']) ? $result['data'] : null,
|
||||
'code' => !empty($result['code']) ? $result['code'] : self::CHECK_ERROR_UNKNOWN
|
||||
);
|
||||
|
||||
if($update_settings) {
|
||||
Setting::setValue(
|
||||
self::PREMIUM_KEY_STATE_SETTING_NAME,
|
||||
$state
|
||||
);
|
||||
}
|
||||
|
||||
return $state;
|
||||
}
|
||||
|
||||
function updateSubscriberCount($result) {
|
||||
if(!empty($result['state'])
|
||||
&& ($result['state'] === self::MAILPOET_KEY_VALID
|
||||
@ -93,4 +150,16 @@ class Bridge {
|
||||
array('state' => self::MAILPOET_KEY_INVALID)
|
||||
);
|
||||
}
|
||||
|
||||
function onSettingsSave($settings) {
|
||||
$api_key_set = !empty($settings[Mailer::MAILER_CONFIG_SETTING_NAME]['mailpoet_api_key']);
|
||||
$premium_key_set = !empty($settings['premium']['premium_key']);
|
||||
if($api_key_set && self::isMPSendingServiceEnabled()) {
|
||||
$result = $this->checkKey($settings[Mailer::MAILER_CONFIG_SETTING_NAME]['mailpoet_api_key']);
|
||||
$this->updateSubscriberCount($result);
|
||||
}
|
||||
if($premium_key_set) {
|
||||
$this->checkPremiumKey($settings['premium']['premium_key']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ class API {
|
||||
private $api_key;
|
||||
|
||||
public $url_me = 'https://bridge.mailpoet.com/api/v0/me';
|
||||
public $url_premium = 'https://bridge.mailpoet.com/api/v0/premium';
|
||||
public $url_messages = 'https://bridge.mailpoet.com/api/v0/messages';
|
||||
public $url_bounces = 'https://bridge.mailpoet.com/api/v0/bounces/search';
|
||||
public $url_stats = 'https://bridge.mailpoet.com/api/v0/stats';
|
||||
@ -46,6 +47,28 @@ class API {
|
||||
return array('code' => $code, 'data' => $body);
|
||||
}
|
||||
|
||||
function checkPremiumKey() {
|
||||
$result = $this->request(
|
||||
$this->url_premium,
|
||||
array('site' => home_url())
|
||||
);
|
||||
|
||||
$code = wp_remote_retrieve_response_code($result);
|
||||
switch($code) {
|
||||
case 200:
|
||||
if($body = wp_remote_retrieve_body($result)) {
|
||||
$body = json_decode($body, true);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
$body = null;
|
||||
break;
|
||||
}
|
||||
|
||||
return array('code' => $code, 'data' => $body);
|
||||
}
|
||||
|
||||
|
||||
function sendMessages($message_body) {
|
||||
$result = $this->request(
|
||||
$this->url_messages,
|
||||
|
@ -13,12 +13,19 @@ class MockAPI {
|
||||
}
|
||||
|
||||
function checkKey() {
|
||||
// if key begins with these codes, return them
|
||||
// if a key begins with these codes, return them
|
||||
$regex = '/^(401|402|503)/';
|
||||
$code = preg_match($regex, $this->api_key, $m) ? $m[1] : 200;
|
||||
return $this->processResponse($code);
|
||||
}
|
||||
|
||||
function checkPremiumKey() {
|
||||
// if a key begins with these codes, return them
|
||||
$regex = '/^(401|402|503)/';
|
||||
$code = preg_match($regex, $this->api_key, $m) ? $m[1] : 200;
|
||||
return $this->processPremiumResponse($code);
|
||||
}
|
||||
|
||||
function updateSubscriberCount($count) {
|
||||
return true;
|
||||
}
|
||||
@ -47,4 +54,22 @@ class MockAPI {
|
||||
|
||||
return array('code' => $code, 'data' => $body);
|
||||
}
|
||||
|
||||
private function processPremiumResponse($code) {
|
||||
switch($code) {
|
||||
case 200:
|
||||
$body = array(
|
||||
'expire_at' => Carbon::createFromTimestamp(current_time('timestamp'))
|
||||
->addMonth()->format('c')
|
||||
);
|
||||
break;
|
||||
case 401:
|
||||
case 402:
|
||||
default:
|
||||
$body = null;
|
||||
break;
|
||||
}
|
||||
|
||||
return array('code' => $code, 'data' => $body);
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,7 @@
|
||||
<a class="nav-tab" href="#signup"><%= __('Sign-up Confirmation') %></a>
|
||||
<a class="nav-tab" href="#mta"><%= __('Send With...') %></a>
|
||||
<a class="nav-tab" href="#advanced"><%= __('Advanced') %></a>
|
||||
<a class="nav-tab" href="#premium"><%= __('Premium') %></a>
|
||||
</h2>
|
||||
|
||||
<!-- basics -->
|
||||
@ -41,6 +42,11 @@
|
||||
<% include 'settings/advanced.html' %>
|
||||
</div>
|
||||
|
||||
<!-- premium -->
|
||||
<div data-tab="premium" class="mailpoet_panel">
|
||||
<% include 'settings/premium.html' %>
|
||||
</div>
|
||||
|
||||
<p class="submit mailpoet_settings_submit" style="display:none;">
|
||||
<input
|
||||
type="submit"
|
||||
|
112
views/settings/premium.html
Normal file
112
views/settings/premium.html
Normal file
@ -0,0 +1,112 @@
|
||||
<table class="form-table">
|
||||
<tbody>
|
||||
<!-- premium key -->
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label for="mailpoet_premium_key">
|
||||
<%= __('Premium License Key') %>
|
||||
</label>
|
||||
<p class="description">
|
||||
<%= __('This key is used for automatic upgrades of your Premium features and access to support.') %>
|
||||
</p>
|
||||
</th>
|
||||
<td>
|
||||
<div>
|
||||
<input
|
||||
type="text"
|
||||
class="regular-text"
|
||||
id="mailpoet_premium_key"
|
||||
name="premium[premium_key]"
|
||||
value="<%=- settings.premium.premium_key -%>"
|
||||
/>
|
||||
<a
|
||||
id="mailpoet_premium_key_verify"
|
||||
class="button-secondary"
|
||||
><%= __('Verify') %></a>
|
||||
</div>
|
||||
<div
|
||||
class="mailpoet_premium_key_valid mailpoet_success"
|
||||
<% if not(settings.premium.premium_key) or not(premium_key_valid) %>
|
||||
style="display: none;"
|
||||
<% endif %>
|
||||
>
|
||||
✔ <%= __('Your license key has been successfully validated.') %>
|
||||
</div>
|
||||
<div
|
||||
class="mailpoet_premium_key_invalid mailpoet_error"
|
||||
<% if not(settings.premium.premium_key) or premium_key_valid %>
|
||||
style="display: none;"
|
||||
<% endif %>
|
||||
>
|
||||
✗ <%= __('Your license key is invalid.') %>
|
||||
</div>
|
||||
<br/>
|
||||
<div
|
||||
<% if premium_plugin_active or not(premium_key_valid) %>
|
||||
style="display: none;"
|
||||
<% endif %>
|
||||
>
|
||||
<a class="button-primary" href="#"><%= __('Download Premium now.') %></a>
|
||||
<span>
|
||||
<%= __("[link]Read guide[/link] on how to install Premium.")
|
||||
|replace({
|
||||
'[link]': '<a target="_blank" href="http://beta.docs.mailpoet.com/article/194-instructions-to-install-the-premium-plugin">',
|
||||
'[/link]': '</a>'
|
||||
})
|
||||
|raw
|
||||
%>
|
||||
</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<script type="text/javascript">
|
||||
jQuery(function($) {
|
||||
$(function() {
|
||||
// verifying premium key
|
||||
$('#mailpoet_premium_key_verify').on('click', function() {
|
||||
// get premium key
|
||||
var key = $('#mailpoet_premium_key').val();
|
||||
|
||||
if(key.length === 0) {
|
||||
// validation
|
||||
return MailPoet.Notice.error(
|
||||
'<%= __('Please specify a Premium key before validating it.') | escape('js') %>',
|
||||
{ scroll: true }
|
||||
);
|
||||
}
|
||||
|
||||
$('.mailpoet_premium_key_valid, .mailpoet_premium_key_invalid').hide();
|
||||
MailPoet.Modal.loading(true);
|
||||
MailPoet.Ajax.post({
|
||||
api_version: window.mailpoet_api_version,
|
||||
endpoint: 'services',
|
||||
action: 'verifyPremiumKey',
|
||||
data: {
|
||||
key: key
|
||||
}
|
||||
}).always(function() {
|
||||
MailPoet.Modal.loading(false);
|
||||
}).done(function(response) {
|
||||
// Hide server error notices
|
||||
$('.mailpoet_notice_server').hide();
|
||||
MailPoet.Notice.success(
|
||||
response.data.message,
|
||||
{ scroll: true }
|
||||
);
|
||||
$('.mailpoet_premium_key_valid').show();
|
||||
}).fail(function(response) {
|
||||
if (response.errors.length > 0) {
|
||||
MailPoet.Notice.error(
|
||||
response.errors.map(function(error) { return error.message; }),
|
||||
{ scroll: true }
|
||||
);
|
||||
$('.mailpoet_premium_key_invalid').show();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
Reference in New Issue
Block a user