Compare commits
27 Commits
Author | SHA1 | Date | |
---|---|---|---|
4ad317ac7b | |||
7cccebbf2c | |||
e4f76ee9eb | |||
7f52f72c25 | |||
44afcbbeaf | |||
e816c59539 | |||
c74421a42a | |||
23eb4633c4 | |||
92dbf966a1 | |||
db226b54a8 | |||
3af059f5c4 | |||
8706abcdf0 | |||
2129d041ac | |||
2a4a44ebb5 | |||
a4f2d5402c | |||
9f5fc151b4 | |||
8a91eb46e6 | |||
e4ab928e82 | |||
a1b02cb862 | |||
84b942b9d2 | |||
1ca99a6209 | |||
6b61abe8c0 | |||
27028ca1ef | |||
eed88926a2 | |||
119e574495 | |||
7308d253b2 | |||
1c19b71697 |
@ -90,6 +90,7 @@ class RoboFile extends \Robo\Tasks {
|
||||
|
||||
$css_files = array(
|
||||
'assets/css/src/admin.styl',
|
||||
'assets/css/src/admin-global.styl',
|
||||
'assets/css/src/newsletter_editor/newsletter_editor.styl',
|
||||
'assets/css/src/public.styl',
|
||||
'assets/css/src/rtl.styl',
|
||||
|
15
assets/css/src/admin-global.styl
Normal file
15
assets/css/src/admin-global.styl
Normal file
@ -0,0 +1,15 @@
|
||||
@import 'nib'
|
||||
|
||||
@require 'icons'
|
||||
|
||||
/*
|
||||
Style for Members plugin
|
||||
*/
|
||||
|
||||
.members-tab-title
|
||||
.mailpoet-icon-logo
|
||||
vertical-align: middle;
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
font-size: 20px;
|
||||
margin-right: 3px;
|
24
assets/css/src/icons.styl
Normal file
24
assets/css/src/icons.styl
Normal file
@ -0,0 +1,24 @@
|
||||
icon-font-path ?= "../fonts"
|
||||
|
||||
@font-face
|
||||
font-family 'mailpoet'
|
||||
src url(icon-font-path + '/mailpoet.ttf?mx0b6n') format('truetype'), url(icon-font-path + '/mailpoet.woff?mx0b6n') format('woff'), url(icon-font-path + '/mailpoet.svg?mx0b6n#mailpoet') format('svg')
|
||||
font-weight normal
|
||||
font-style normal
|
||||
|
||||
[class^="mailpoet-icon-"], [class*=" mailpoet-icon-"]
|
||||
font-family 'mailpoet' !important
|
||||
speak none
|
||||
font-style normal
|
||||
font-weight normal
|
||||
font-variant normal
|
||||
text-transform none
|
||||
line-height 1
|
||||
|
||||
/* Better Font Rendering =========== */
|
||||
-webkit-font-smoothing antialiased
|
||||
-moz-osx-font-smoothing grayscale
|
||||
|
||||
.mailpoet-icon-logo
|
||||
&:before
|
||||
content "\e900"
|
@ -2,7 +2,7 @@ animation-slide-open-downwards($max-height = 2000px)
|
||||
transition: all 250ms cubic-bezier(0.420, 0.000, 0.580, 1.000) /* ease-in-out */
|
||||
max-height: $max-height
|
||||
opacity: 1
|
||||
overflow-y: hidden
|
||||
overflow-y: inherit
|
||||
|
||||
&.mailpoet_closed
|
||||
max-height: 0px
|
||||
|
11
assets/fonts/mailpoet.svg
Normal file
11
assets/fonts/mailpoet.svg
Normal file
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
|
||||
<svg xmlns="http://www.w3.org/2000/svg">
|
||||
<metadata>Generated by IcoMoon</metadata>
|
||||
<defs>
|
||||
<font id="mailpoet" horiz-adv-x="1024">
|
||||
<font-face units-per-em="1024" ascent="960" descent="-64" />
|
||||
<missing-glyph horiz-adv-x="1024" />
|
||||
<glyph unicode=" " horiz-adv-x="0" d="" />
|
||||
<glyph unicode="" glyph-name="optimised" horiz-adv-x="972" d="M230.188 949.695c-21.982-3.361-41.376-14.741-48.618-28.188l-5.948-11.637 0.517-265.588c0.776-263.779 0.776-265.847 6.206-273.088 11.12-15.258 40.601-22.24 68.79-16.551 16.551 3.621 25.861 9.827 32.584 21.723 3.879 7.499 4.397 23.791 5.689 185.161l1.293 176.628 60.514-161.111c33.102-88.702 63.875-168.612 68.013-177.404 13.707-29.481 35.687-41.376 72.151-39.049 21.206 1.293 39.308 9.827 47.584 22.499 3.361 5.172 35.947 91.806 72.41 192.662s67.237 185.42 68.53 187.49c1.551 2.587 2.587-69.307 2.587-185.937v-190.335l5.948-11.379c8.533-16.809 20.172-21.982 49.652-21.982 27.929 0.259 39.825 4.914 49.911 20.172l6.982 10.603v530.401l-5.689 9.31c-12.671 20.43-50.17 31.033-91.806 25.601-34.394-4.138-53.79-16.292-66.72-41.118-2.587-5.172-35.947-101.89-73.961-214.902s-69.824-206.367-70.6-207.403c-1.034-1.034-32.326 86.115-69.824 193.954-37.757 107.581-71.892 205.075-76.030 216.453-10.086 26.118-25.601 42.929-45.514 48.877-17.326 5.172-46.807 6.982-64.652 4.138zM54.854 243.443c-20.172-3.879-43.963-19.136-51.204-33.619-6.206-11.379-4.914-32.843 2.587-47.841 23.533-46.807 71.634-86.892 126.717-104.736 17.068-5.689 23.274-5.948 120.252-7.499 97.235-1.551 102.926-1.81 116.373-7.241 29.739-11.896 51.204-35.687 61.807-68.013 3.621-11.12 13.964-21.206 25.861-25.344 4.914-1.551 18.361-2.844 29.739-2.844 16.809 0 23.533 1.293 32.584 5.689 11.896 6.206 13.964 9.31 26.895 38.791 11.896 27.671 39.567 49.652 70.858 56.117 8.533 1.81 47.067 2.844 100.856 2.844 99.563 0 113.786 2.068 151.801 20.689 49.652 24.567 96.978 77.84 101.373 113.529 3.104 26.118-17.326 49.394-51.204 58.187-25.601 6.465-41.635-0.517-54.825-24.050-11.12-19.655-29.998-38.015-47.841-46.29l-14.741-6.982-99.563-1.551c-90.77-1.293-101.373-2.068-120.252-6.982-27.154-7.499-58.444-23.016-80.427-40.084l-17.844-13.964-16.809 13.964c-20.689 16.809-51.462 32.584-78.875 39.825-19.136 5.172-28.705 5.948-120.252 7.241l-99.563 1.551-15.775 7.241c-18.102 8.533-32.584 21.982-48.36 45.773-16.034 24.567-26.895 29.998-50.17 25.601z" />
|
||||
</font></defs></svg>
|
After Width: | Height: | Size: 2.4 KiB |
BIN
assets/fonts/mailpoet.ttf
Normal file
BIN
assets/fonts/mailpoet.ttf
Normal file
Binary file not shown.
BIN
assets/fonts/mailpoet.woff
Normal file
BIN
assets/fonts/mailpoet.woff
Normal file
Binary file not shown.
@ -20,13 +20,14 @@ class AutomatedLatestContent extends APIEndpoint {
|
||||
|
||||
function getPostTypes() {
|
||||
$post_types = array_map(function($post_type) {
|
||||
if(!empty($post_type->exclude_from_search)) return;
|
||||
return array(
|
||||
'name' => $post_type->name,
|
||||
'label' => $post_type->label
|
||||
);
|
||||
}, get_post_types(array(), 'objects'));
|
||||
return $this->successResponse(
|
||||
$post_types
|
||||
array_filter($post_types)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,7 @@ class NewsletterTemplates extends APIEndpoint {
|
||||
}
|
||||
|
||||
function getAll() {
|
||||
$collection = NewsletterTemplate::findMany();
|
||||
$collection = NewsletterTemplate::orderByDesc('created_at')->orderByAsc('name')->findMany();
|
||||
$templates = array_map(function($item) {
|
||||
return $item->asArray();
|
||||
}, $collection);
|
||||
|
@ -10,10 +10,13 @@ use MailPoet\Form\Util\FieldNameObfuscator;
|
||||
use MailPoet\Models\Form;
|
||||
use MailPoet\Models\StatisticsForms;
|
||||
use MailPoet\Models\Subscriber;
|
||||
use MailPoet\Util\Helpers;
|
||||
|
||||
if(!defined('ABSPATH')) exit;
|
||||
|
||||
class Subscribers extends APIEndpoint {
|
||||
const SUBSCRIPTION_LIMIT_COOLDOWN = 60;
|
||||
|
||||
public $permissions = array(
|
||||
'global' => AccessControl::PERMISSION_MANAGE_SUBSCRIBERS,
|
||||
'methods' => array('subscribe' => AccessControl::NO_ACCESS_RESTRICTION)
|
||||
@ -94,6 +97,19 @@ class Subscribers extends APIEndpoint {
|
||||
$form_fields = $form->getFieldList();
|
||||
$data = array_intersect_key($data, array_flip($form_fields));
|
||||
|
||||
// make sure we don't allow too many subscriptions with the same ip address
|
||||
$subscription_count = Subscriber::where(
|
||||
'subscribed_ip',
|
||||
Helpers::getIP()
|
||||
)->whereRaw(
|
||||
'(TIME_TO_SEC(TIMEDIFF(NOW(), created_at)) < ? OR TIME_TO_SEC(TIMEDIFF(NOW(), updated_at)) < ?)',
|
||||
array(self::SUBSCRIPTION_LIMIT_COOLDOWN, self::SUBSCRIPTION_LIMIT_COOLDOWN)
|
||||
)->count();
|
||||
|
||||
if($subscription_count > 0) {
|
||||
throw new \Exception(__('You need to wait before subscribing again.', 'mailpoet'));
|
||||
}
|
||||
|
||||
$subscriber = Subscriber::subscribe($data, $segment_ids);
|
||||
$errors = $subscriber->getErrors();
|
||||
|
||||
|
@ -8,26 +8,25 @@ if(!defined('ABSPATH')) exit;
|
||||
require_once(ABSPATH . 'wp-includes/pluggable.php');
|
||||
|
||||
class AccessControl {
|
||||
const PERMISSION_ACCESS_PLUGIN_ADMIN = 'access_plugin_admin';
|
||||
const PERMISSION_MANAGE_SETTINGS = 'manage_settings';
|
||||
const PERMISSION_MANAGE_EMAILS = 'manage_emails';
|
||||
const PERMISSION_MANAGE_SUBSCRIBERS = 'manage_subscribers';
|
||||
const PERMISSION_MANAGE_FORMS = 'manage_forms';
|
||||
const PERMISSION_MANAGE_SEGMENTS = 'manage_segments';
|
||||
const PERMISSION_UPDATE_PLUGIN = 'update_plugin';
|
||||
const NO_ACCESS_RESTRICTION = 'no_access_restriction';
|
||||
const PERMISSION_ACCESS_PLUGIN_ADMIN = 'mailpoet_access_plugin_admin';
|
||||
const PERMISSION_MANAGE_SETTINGS = 'mailpoet_manage_settings';
|
||||
const PERMISSION_MANAGE_EMAILS = 'mailpoet_manage_emails';
|
||||
const PERMISSION_MANAGE_SUBSCRIBERS = 'mailpoet_manage_subscribers';
|
||||
const PERMISSION_MANAGE_FORMS = 'mailpoet_manage_forms';
|
||||
const PERMISSION_MANAGE_SEGMENTS = 'mailpoet_manage_segments';
|
||||
const NO_ACCESS_RESTRICTION = 'mailpoet_no_access_restriction';
|
||||
|
||||
public $permissions;
|
||||
public $current_user_roles;
|
||||
public $user_roles;
|
||||
public $user_capabilities;
|
||||
|
||||
function __construct() {
|
||||
$this->permissions = $this->getDefaultPermissions();
|
||||
$this->permissions = self::getDefaultPermissions();
|
||||
$this->user_roles = $this->getUserRoles();
|
||||
$this->user_capabilities = $this->getUserCapabilities();
|
||||
}
|
||||
|
||||
private function getDefaultPermissions() {
|
||||
static function getDefaultPermissions() {
|
||||
return array(
|
||||
self::PERMISSION_ACCESS_PLUGIN_ADMIN => WPHooks::applyFilters(
|
||||
'mailpoet_permission_access_plugin_admin',
|
||||
@ -67,12 +66,17 @@ class AccessControl {
|
||||
'administrator'
|
||||
)
|
||||
),
|
||||
self::PERMISSION_UPDATE_PLUGIN => WPHooks::applyFilters(
|
||||
'mailpoet_permission_update_plugin',
|
||||
array(
|
||||
'administrator'
|
||||
)
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
static function getPermissionLabels() {
|
||||
return array(
|
||||
self::PERMISSION_ACCESS_PLUGIN_ADMIN => __('Admin menu item', 'mailpoet'),
|
||||
self::PERMISSION_MANAGE_SETTINGS => __('Manage settings', 'mailpoet'),
|
||||
self::PERMISSION_MANAGE_EMAILS => __('Manage emails', 'mailpoet'),
|
||||
self::PERMISSION_MANAGE_SUBSCRIBERS => __('Manage subscribers', 'mailpoet'),
|
||||
self::PERMISSION_MANAGE_FORMS => __('Manage forms', 'mailpoet'),
|
||||
self::PERMISSION_MANAGE_SEGMENTS => __('Manage segments', 'mailpoet'),
|
||||
);
|
||||
}
|
||||
|
||||
@ -94,11 +98,12 @@ class AccessControl {
|
||||
|
||||
function validatePermission($permission) {
|
||||
if($permission === self::NO_ACCESS_RESTRICTION) return true;
|
||||
if(empty($this->permissions[$permission])) return false;
|
||||
$permitted_roles = array_intersect(
|
||||
$this->user_roles,
|
||||
$this->permissions[$permission]
|
||||
);
|
||||
return (!empty($permitted_roles));
|
||||
foreach($this->user_roles as $role) {
|
||||
$role_object = get_role($role);
|
||||
if($role_object && $role_object->has_cap($permission)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -14,10 +14,16 @@ class Activator {
|
||||
$populator = new Populator();
|
||||
$populator->up();
|
||||
Setting::setValue('db_version', Env::$version);
|
||||
|
||||
$caps = new Capabilities();
|
||||
$caps->setupWPCapabilities();
|
||||
}
|
||||
|
||||
function deactivate() {
|
||||
$migrator = new Migrator();
|
||||
$migrator->down();
|
||||
|
||||
$caps = new Capabilities();
|
||||
$caps->removeWPCapabilities();
|
||||
}
|
||||
}
|
85
lib/Config/Capabilities.php
Normal file
85
lib/Config/Capabilities.php
Normal file
@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
namespace MailPoet\Config;
|
||||
|
||||
use MailPoet\WP\Hooks;
|
||||
|
||||
class Capabilities {
|
||||
const MEMBERS_CAP_GROUP_NAME = 'mailpoet';
|
||||
|
||||
private $renderer = null;
|
||||
|
||||
function __construct($renderer = null) {
|
||||
if($renderer !== null) {
|
||||
$this->renderer = $renderer;
|
||||
}
|
||||
}
|
||||
|
||||
function init() {
|
||||
$this->setupMembersCapabilities();
|
||||
}
|
||||
|
||||
function setupWPCapabilities() {
|
||||
$permissions = AccessControl::getDefaultPermissions();
|
||||
$role_objects = array();
|
||||
foreach($permissions as $name => $roles) {
|
||||
foreach($roles as $role) {
|
||||
if(!isset($role_objects[$role])) {
|
||||
$role_objects[$role] = get_role($role);
|
||||
}
|
||||
$role_objects[$role]->add_cap($name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function removeWPCapabilities() {
|
||||
$permissions = AccessControl::getDefaultPermissions();
|
||||
$role_objects = array();
|
||||
foreach($permissions as $name => $roles) {
|
||||
foreach($roles as $role) {
|
||||
if(!isset($role_objects[$role])) {
|
||||
$role_objects[$role] = get_role($role);
|
||||
}
|
||||
$role_objects[$role]->remove_cap($name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function setupMembersCapabilities() {
|
||||
Hooks::addAction('admin_enqueue_scripts', array($this, 'enqueueMembersStyles'));
|
||||
Hooks::addAction('members_register_cap_groups', array($this, 'registerMembersCapGroup'));
|
||||
Hooks::addAction('members_register_caps', array($this, 'registerMembersCapabilities'));
|
||||
}
|
||||
|
||||
function enqueueMembersStyles() {
|
||||
wp_enqueue_style(
|
||||
'mailpoet-admin-global',
|
||||
Env::$assets_url . '/css/' . $this->renderer->getCssAsset('admin-global.css')
|
||||
);
|
||||
}
|
||||
|
||||
function registerMembersCapGroup() {
|
||||
members_register_cap_group(
|
||||
self::MEMBERS_CAP_GROUP_NAME,
|
||||
array(
|
||||
'label' => __('MailPoet', 'mailpoet'),
|
||||
'caps' => array(),
|
||||
'icon' => 'mailpoet-icon-logo',
|
||||
'priority' => 30
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function registerMembersCapabilities() {
|
||||
$permissions = AccessControl::getPermissionLabels();
|
||||
foreach($permissions as $name => $label) {
|
||||
members_register_cap(
|
||||
$name,
|
||||
array(
|
||||
'label' => $label,
|
||||
'group' => self::MEMBERS_CAP_GROUP_NAME
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
@ -125,6 +125,7 @@ class Initializer {
|
||||
$this->setupUpdater();
|
||||
|
||||
$this->setupLocalizer();
|
||||
$this->setupCapabilities();
|
||||
$this->setupMenu();
|
||||
$this->setupShortcodes();
|
||||
$this->setupImages();
|
||||
@ -152,9 +153,6 @@ class Initializer {
|
||||
|
||||
// if current db version and plugin version differ
|
||||
if(version_compare($current_db_version, Env::$version) !== 0) {
|
||||
if(!$this->access_control->validatePermission(AccessControl::PERMISSION_UPDATE_PLUGIN)) {
|
||||
throw new \Exception(__('You do not have permission to activate/deactivate MailPoet plugin.', 'mailpoet'));
|
||||
}
|
||||
$this->runActivator();
|
||||
}
|
||||
}
|
||||
@ -189,6 +187,11 @@ class Initializer {
|
||||
$localizer->init();
|
||||
}
|
||||
|
||||
function setupCapabilities() {
|
||||
$caps = new Capabilities($this->renderer);
|
||||
$caps->init();
|
||||
}
|
||||
|
||||
function setupMenu() {
|
||||
$menu = new Menu($this->renderer, Env::$assets_url, $this->access_control);
|
||||
$menu->init();
|
||||
|
@ -37,7 +37,6 @@ class Menu {
|
||||
$this->renderer = $renderer;
|
||||
$this->assets_url = $assets_url;
|
||||
$this->access_control = $access_control;
|
||||
$this->user_capability = $this->access_control->getUserFirstCapability();
|
||||
$subscribers_feature = new SubscribersFeature();
|
||||
$this->subscribers_over_limit = $subscribers_feature->check();
|
||||
$this->checkMailPoetAPIKey();
|
||||
@ -70,7 +69,7 @@ class Menu {
|
||||
add_menu_page(
|
||||
'MailPoet',
|
||||
'MailPoet',
|
||||
$this->user_capability,
|
||||
AccessControl::PERMISSION_ACCESS_PLUGIN_ADMIN,
|
||||
self::MAIN_PAGE_SLUG,
|
||||
null,
|
||||
$this->assets_url . '/img/menu_icon.png',
|
||||
@ -78,186 +77,176 @@ class Menu {
|
||||
);
|
||||
|
||||
// Emails page
|
||||
if($this->access_control->validatePermission(AccessControl::PERMISSION_MANAGE_EMAILS)) {
|
||||
$newsletters_page = add_submenu_page(
|
||||
self::MAIN_PAGE_SLUG,
|
||||
$this->setPageTitle(__('Emails', 'mailpoet')),
|
||||
__('Emails', 'mailpoet'),
|
||||
$this->user_capability,
|
||||
self::MAIN_PAGE_SLUG,
|
||||
array(
|
||||
$this,
|
||||
'newsletters'
|
||||
)
|
||||
);
|
||||
$newsletters_page = add_submenu_page(
|
||||
self::MAIN_PAGE_SLUG,
|
||||
$this->setPageTitle(__('Emails', 'mailpoet')),
|
||||
__('Emails', 'mailpoet'),
|
||||
AccessControl::PERMISSION_MANAGE_EMAILS,
|
||||
self::MAIN_PAGE_SLUG,
|
||||
array(
|
||||
$this,
|
||||
'newsletters'
|
||||
)
|
||||
);
|
||||
|
||||
// add limit per page to screen options
|
||||
add_action('load-' . $newsletters_page, function() {
|
||||
add_screen_option('per_page', array(
|
||||
'label' => _x(
|
||||
'Number of newsletters per page',
|
||||
'newsletters per page (screen options)',
|
||||
'mailpoet'
|
||||
),
|
||||
'option' => 'mailpoet_newsletters_per_page'
|
||||
));
|
||||
});
|
||||
// add limit per page to screen options
|
||||
add_action('load-' . $newsletters_page, function() {
|
||||
add_screen_option('per_page', array(
|
||||
'label' => _x(
|
||||
'Number of newsletters per page',
|
||||
'newsletters per page (screen options)',
|
||||
'mailpoet'
|
||||
),
|
||||
'option' => 'mailpoet_newsletters_per_page'
|
||||
));
|
||||
});
|
||||
|
||||
// newsletter editor
|
||||
add_submenu_page(
|
||||
true,
|
||||
$this->setPageTitle(__('Newsletter', 'mailpoet')),
|
||||
__('Newsletter Editor', 'mailpoet'),
|
||||
$this->user_capability,
|
||||
'mailpoet-newsletter-editor',
|
||||
array(
|
||||
$this,
|
||||
'newletterEditor'
|
||||
)
|
||||
);
|
||||
}
|
||||
// newsletter editor
|
||||
add_submenu_page(
|
||||
true,
|
||||
$this->setPageTitle(__('Newsletter', 'mailpoet')),
|
||||
__('Newsletter Editor', 'mailpoet'),
|
||||
AccessControl::PERMISSION_MANAGE_EMAILS,
|
||||
'mailpoet-newsletter-editor',
|
||||
array(
|
||||
$this,
|
||||
'newletterEditor'
|
||||
)
|
||||
);
|
||||
|
||||
// Forms page
|
||||
if($this->access_control->validatePermission(AccessControl::PERMISSION_MANAGE_FORMS)) {
|
||||
$forms_page = add_submenu_page(
|
||||
self::MAIN_PAGE_SLUG,
|
||||
$this->setPageTitle(__('Forms', 'mailpoet')),
|
||||
__('Forms', 'mailpoet'),
|
||||
$this->user_capability,
|
||||
'mailpoet-forms',
|
||||
array(
|
||||
$this,
|
||||
'forms'
|
||||
)
|
||||
);
|
||||
$forms_page = add_submenu_page(
|
||||
self::MAIN_PAGE_SLUG,
|
||||
$this->setPageTitle(__('Forms', 'mailpoet')),
|
||||
__('Forms', 'mailpoet'),
|
||||
AccessControl::PERMISSION_MANAGE_FORMS,
|
||||
'mailpoet-forms',
|
||||
array(
|
||||
$this,
|
||||
'forms'
|
||||
)
|
||||
);
|
||||
|
||||
// add limit per page to screen options
|
||||
add_action('load-' . $forms_page, function() {
|
||||
add_screen_option('per_page', array(
|
||||
'label' => _x(
|
||||
'Number of forms per page',
|
||||
'forms per page (screen options)',
|
||||
'mailpoet'
|
||||
),
|
||||
'option' => 'mailpoet_forms_per_page'
|
||||
));
|
||||
});
|
||||
// add limit per page to screen options
|
||||
add_action('load-' . $forms_page, function() {
|
||||
add_screen_option('per_page', array(
|
||||
'label' => _x(
|
||||
'Number of forms per page',
|
||||
'forms per page (screen options)',
|
||||
'mailpoet'
|
||||
),
|
||||
'option' => 'mailpoet_forms_per_page'
|
||||
));
|
||||
});
|
||||
|
||||
// form editor
|
||||
add_submenu_page(
|
||||
true,
|
||||
$this->setPageTitle(__('Form Editor', 'mailpoet')),
|
||||
__('Form Editor', 'mailpoet'),
|
||||
$this->user_capability,
|
||||
'mailpoet-form-editor',
|
||||
array(
|
||||
$this,
|
||||
'formEditor'
|
||||
)
|
||||
);
|
||||
}
|
||||
// form editor
|
||||
add_submenu_page(
|
||||
true,
|
||||
$this->setPageTitle(__('Form Editor', 'mailpoet')),
|
||||
__('Form Editor', 'mailpoet'),
|
||||
AccessControl::PERMISSION_MANAGE_FORMS,
|
||||
'mailpoet-form-editor',
|
||||
array(
|
||||
$this,
|
||||
'formEditor'
|
||||
)
|
||||
);
|
||||
|
||||
// Subscribers page
|
||||
if($this->access_control->validatePermission(AccessControl::PERMISSION_MANAGE_SUBSCRIBERS)) {
|
||||
$subscribers_page = add_submenu_page(
|
||||
self::MAIN_PAGE_SLUG,
|
||||
$this->setPageTitle(__('Subscribers', 'mailpoet')),
|
||||
__('Subscribers', 'mailpoet'),
|
||||
$this->user_capability,
|
||||
'mailpoet-subscribers',
|
||||
array(
|
||||
$this,
|
||||
'subscribers'
|
||||
)
|
||||
);
|
||||
$subscribers_page = add_submenu_page(
|
||||
self::MAIN_PAGE_SLUG,
|
||||
$this->setPageTitle(__('Subscribers', 'mailpoet')),
|
||||
__('Subscribers', 'mailpoet'),
|
||||
AccessControl::PERMISSION_MANAGE_SUBSCRIBERS,
|
||||
'mailpoet-subscribers',
|
||||
array(
|
||||
$this,
|
||||
'subscribers'
|
||||
)
|
||||
);
|
||||
|
||||
// add limit per page to screen options
|
||||
add_action('load-' . $subscribers_page, function() {
|
||||
add_screen_option('per_page', array(
|
||||
'label' => _x(
|
||||
'Number of subscribers per page',
|
||||
'subscribers per page (screen options)',
|
||||
'mailpoet'
|
||||
),
|
||||
'option' => 'mailpoet_subscribers_per_page'
|
||||
));
|
||||
});
|
||||
// add limit per page to screen options
|
||||
add_action('load-' . $subscribers_page, function() {
|
||||
add_screen_option('per_page', array(
|
||||
'label' => _x(
|
||||
'Number of subscribers per page',
|
||||
'subscribers per page (screen options)',
|
||||
'mailpoet'
|
||||
),
|
||||
'option' => 'mailpoet_subscribers_per_page'
|
||||
));
|
||||
});
|
||||
|
||||
// import
|
||||
add_submenu_page(
|
||||
'admin.php?page=mailpoet-subscribers',
|
||||
$this->setPageTitle(__('Import', 'mailpoet')),
|
||||
__('Import', 'mailpoet'),
|
||||
$this->user_capability,
|
||||
'mailpoet-import',
|
||||
array(
|
||||
$this,
|
||||
'import'
|
||||
)
|
||||
);
|
||||
// import
|
||||
add_submenu_page(
|
||||
'admin.php?page=mailpoet-subscribers',
|
||||
$this->setPageTitle(__('Import', 'mailpoet')),
|
||||
__('Import', 'mailpoet'),
|
||||
AccessControl::PERMISSION_MANAGE_SUBSCRIBERS,
|
||||
'mailpoet-import',
|
||||
array(
|
||||
$this,
|
||||
'import'
|
||||
)
|
||||
);
|
||||
|
||||
// export
|
||||
add_submenu_page(
|
||||
true,
|
||||
$this->setPageTitle(__('Export', 'mailpoet')),
|
||||
__('Export', 'mailpoet'),
|
||||
$this->user_capability,
|
||||
'mailpoet-export',
|
||||
array(
|
||||
$this,
|
||||
'export'
|
||||
)
|
||||
);
|
||||
}
|
||||
// export
|
||||
add_submenu_page(
|
||||
true,
|
||||
$this->setPageTitle(__('Export', 'mailpoet')),
|
||||
__('Export', 'mailpoet'),
|
||||
AccessControl::PERMISSION_MANAGE_SUBSCRIBERS,
|
||||
'mailpoet-export',
|
||||
array(
|
||||
$this,
|
||||
'export'
|
||||
)
|
||||
);
|
||||
|
||||
// Segments page
|
||||
if($this->access_control->validatePermission(AccessControl::PERMISSION_MANAGE_SEGMENTS)) {
|
||||
$segments_page = add_submenu_page(
|
||||
self::MAIN_PAGE_SLUG,
|
||||
$this->setPageTitle(__('Lists', 'mailpoet')),
|
||||
__('Lists', 'mailpoet'),
|
||||
$this->user_capability,
|
||||
'mailpoet-segments',
|
||||
array(
|
||||
$this,
|
||||
'segments'
|
||||
)
|
||||
);
|
||||
$segments_page = add_submenu_page(
|
||||
self::MAIN_PAGE_SLUG,
|
||||
$this->setPageTitle(__('Lists', 'mailpoet')),
|
||||
__('Lists', 'mailpoet'),
|
||||
AccessControl::PERMISSION_MANAGE_SEGMENTS,
|
||||
'mailpoet-segments',
|
||||
array(
|
||||
$this,
|
||||
'segments'
|
||||
)
|
||||
);
|
||||
|
||||
// add limit per page to screen options
|
||||
add_action('load-' . $segments_page, function() {
|
||||
add_screen_option('per_page', array(
|
||||
'label' => _x(
|
||||
'Number of segments per page',
|
||||
'segments per page (screen options)',
|
||||
'mailpoet'
|
||||
),
|
||||
'option' => 'mailpoet_segments_per_page'
|
||||
));
|
||||
});
|
||||
}
|
||||
// add limit per page to screen options
|
||||
add_action('load-' . $segments_page, function() {
|
||||
add_screen_option('per_page', array(
|
||||
'label' => _x(
|
||||
'Number of segments per page',
|
||||
'segments per page (screen options)',
|
||||
'mailpoet'
|
||||
),
|
||||
'option' => 'mailpoet_segments_per_page'
|
||||
));
|
||||
});
|
||||
|
||||
// Settings page
|
||||
if($this->access_control->validatePermission(AccessControl::PERMISSION_MANAGE_SETTINGS)) {
|
||||
add_submenu_page(
|
||||
self::MAIN_PAGE_SLUG,
|
||||
$this->setPageTitle(__('Settings', 'mailpoet')),
|
||||
__('Settings', 'mailpoet'),
|
||||
$this->user_capability,
|
||||
'mailpoet-settings',
|
||||
array(
|
||||
$this,
|
||||
'settings'
|
||||
)
|
||||
);
|
||||
}
|
||||
add_submenu_page(
|
||||
self::MAIN_PAGE_SLUG,
|
||||
$this->setPageTitle(__('Settings', 'mailpoet')),
|
||||
__('Settings', 'mailpoet'),
|
||||
AccessControl::PERMISSION_MANAGE_SETTINGS,
|
||||
'mailpoet-settings',
|
||||
array(
|
||||
$this,
|
||||
'settings'
|
||||
)
|
||||
);
|
||||
|
||||
// Help page
|
||||
add_submenu_page(
|
||||
self::MAIN_PAGE_SLUG,
|
||||
$this->setPageTitle(__('Help', 'mailpoet')),
|
||||
__('Help', 'mailpoet'),
|
||||
$this->user_capability,
|
||||
AccessControl::PERMISSION_ACCESS_PLUGIN_ADMIN,
|
||||
'mailpoet-help',
|
||||
array(
|
||||
$this,
|
||||
@ -271,7 +260,7 @@ class Menu {
|
||||
License::getLicense() ? true : self::MAIN_PAGE_SLUG,
|
||||
$this->setPageTitle(__('Premium', 'mailpoet')),
|
||||
__('Premium', 'mailpoet'),
|
||||
$this->user_capability,
|
||||
AccessControl::PERMISSION_ACCESS_PLUGIN_ADMIN,
|
||||
'mailpoet-premium',
|
||||
array(
|
||||
$this,
|
||||
@ -284,7 +273,7 @@ class Menu {
|
||||
true,
|
||||
$this->setPageTitle(__('Welcome', 'mailpoet')),
|
||||
__('Welcome', 'mailpoet'),
|
||||
$this->user_capability,
|
||||
AccessControl::PERMISSION_ACCESS_PLUGIN_ADMIN,
|
||||
'mailpoet-welcome',
|
||||
array(
|
||||
$this,
|
||||
@ -297,7 +286,7 @@ class Menu {
|
||||
true,
|
||||
$this->setPageTitle(__('Update', 'mailpoet')),
|
||||
__('Update', 'mailpoet'),
|
||||
$this->user_capability,
|
||||
AccessControl::PERMISSION_ACCESS_PLUGIN_ADMIN,
|
||||
'mailpoet-update',
|
||||
array(
|
||||
$this,
|
||||
@ -310,7 +299,7 @@ class Menu {
|
||||
true,
|
||||
$this->setPageTitle(__('Migration', 'mailpoet')),
|
||||
'',
|
||||
$this->user_capability,
|
||||
AccessControl::PERMISSION_ACCESS_PLUGIN_ADMIN,
|
||||
'mailpoet-migration',
|
||||
array(
|
||||
$this,
|
||||
@ -422,6 +411,7 @@ class Menu {
|
||||
'premium_key_valid' => !empty($this->premium_key_valid),
|
||||
'mss_active' => Bridge::isMPSendingServiceEnabled(),
|
||||
'mss_key_valid' => !empty($mp_api_key_valid),
|
||||
'members_plugin_active' => is_plugin_active('members/members.php'),
|
||||
'pages' => Pages::getAll(),
|
||||
'flags' => $flags,
|
||||
'current_user' => wp_get_current_user(),
|
||||
@ -658,7 +648,7 @@ class Menu {
|
||||
true,
|
||||
'MailPoet',
|
||||
'MailPoet',
|
||||
$access_control->getUserFirstCapability(),
|
||||
AccessControl::PERMISSION_ACCESS_PLUGIN_ADMIN,
|
||||
$_REQUEST['page'],
|
||||
array(
|
||||
__CLASS__,
|
||||
|
@ -14,7 +14,6 @@ class Subscriber extends Model {
|
||||
const STATUS_UNSUBSCRIBED = 'unsubscribed';
|
||||
const STATUS_UNCONFIRMED = 'unconfirmed';
|
||||
const STATUS_BOUNCED = 'bounced';
|
||||
const SUBSCRIPTION_LIMIT_COOLDOWN = 60;
|
||||
const SUBSCRIBER_TOKEN_LENGTH = 6;
|
||||
|
||||
function __construct() {
|
||||
@ -175,22 +174,7 @@ class Subscriber extends Model {
|
||||
'signup_confirmation.enabled'
|
||||
);
|
||||
|
||||
$subscriber_data['subscribed_ip'] = (isset($_SERVER['REMOTE_ADDR']))
|
||||
? $_SERVER['REMOTE_ADDR']
|
||||
: null;
|
||||
|
||||
// make sure we don't allow too many subscriptions with the same ip address
|
||||
$subscription_count = Subscriber::where(
|
||||
'subscribed_ip',
|
||||
$subscriber_data['subscribed_ip']
|
||||
)->whereRaw(
|
||||
'TIME_TO_SEC(TIMEDIFF(NOW(), created_at)) < ?',
|
||||
self::SUBSCRIPTION_LIMIT_COOLDOWN
|
||||
)->count();
|
||||
|
||||
if($subscription_count > 0) {
|
||||
throw new \Exception(__('You need to wait before subscribing again.', 'mailpoet'));
|
||||
}
|
||||
$subscriber_data['subscribed_ip'] = Helpers::getIP();
|
||||
|
||||
$subscriber = self::findOne($subscriber_data['email']);
|
||||
|
||||
@ -205,6 +189,7 @@ class Subscriber extends Model {
|
||||
} else {
|
||||
// store subscriber data to be updated after confirmation
|
||||
$subscriber->setUnconfirmedData($subscriber_data);
|
||||
$subscriber->setExpr('updated_at', 'NOW()');
|
||||
}
|
||||
|
||||
// restore trashed subscriber
|
||||
|
@ -111,6 +111,7 @@ class WP {
|
||||
SELECT wu.id, wu.user_email, "subscribed", CURRENT_TIMESTAMP() FROM %s wu
|
||||
LEFT JOIN %s mps ON wu.id = mps.wp_user_id
|
||||
WHERE mps.wp_user_id IS NULL
|
||||
ON DUPLICATE KEY UPDATE wp_user_id = wu.id
|
||||
', $subscribers_table, $wpdb->users, $subscribers_table));
|
||||
}
|
||||
|
||||
|
@ -64,7 +64,7 @@ class Pages {
|
||||
$subscriber_data = $this->subscriber->getUnconfirmedData();
|
||||
|
||||
$this->subscriber->status = Subscriber::STATUS_SUBSCRIBED;
|
||||
$this->subscriber->confirmed_ip = (!empty($_SERVER['REMOTE_ADDR'])) ? $_SERVER['REMOTE_ADDR'] : null;
|
||||
$this->subscriber->confirmed_ip = Helpers::getIP();
|
||||
$this->subscriber->setExpr('confirmed_at', 'NOW()');
|
||||
$this->subscriber->unconfirmed_data = null;
|
||||
$this->subscriber->save();
|
||||
|
@ -146,4 +146,9 @@ class Helpers {
|
||||
return explode(self::DIVIDER, $object);
|
||||
}
|
||||
|
||||
static function getIP() {
|
||||
return (isset($_SERVER['REMOTE_ADDR']))
|
||||
? $_SERVER['REMOTE_ADDR']
|
||||
: null;
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ if(!defined('ABSPATH')) exit;
|
||||
|
||||
/*
|
||||
* Plugin Name: MailPoet 3 (new)
|
||||
* Version: 3.0.1
|
||||
* Version: 3.0.3
|
||||
* Plugin URI: http://www.mailpoet.com
|
||||
* Description: Create and send newsletters, post notifications and welcome emails from your WordPress.
|
||||
* Author: MailPoet
|
||||
@ -12,7 +12,6 @@ if(!defined('ABSPATH')) exit;
|
||||
* Requires at least: 4.6
|
||||
* Tested up to: 4.8
|
||||
*
|
||||
* Text Domain: mailpoet
|
||||
* Domain Path: /lang/
|
||||
*
|
||||
* @package WordPress
|
||||
@ -21,7 +20,7 @@ if(!defined('ABSPATH')) exit;
|
||||
*/
|
||||
|
||||
$mailpoet_plugin = array(
|
||||
'version' => '3.0.1',
|
||||
'version' => '3.0.3',
|
||||
'filename' => __FILE__,
|
||||
'path' => dirname(__FILE__),
|
||||
'autoloader' => dirname(__FILE__) . '/vendor/autoload.php',
|
||||
|
12
readme.txt
12
readme.txt
@ -4,7 +4,7 @@ Tags: newsletter, email, welcome email, post notification, autoresponder, signup
|
||||
Requires at least: 4.6
|
||||
Tested up to: 4.8
|
||||
Requires PHP: 5.3
|
||||
Stable tag: 3.0.1
|
||||
Stable tag: 3.0.3
|
||||
License: GPLv3
|
||||
License URI: https://www.gnu.org/licenses/gpl-3.0.html
|
||||
|
||||
@ -114,6 +114,16 @@ Stop by our [support site](https://www.mailpoet.com/support).
|
||||
|
||||
== Changelog ==
|
||||
|
||||
= 3.0.3 - 2017-10-03 =
|
||||
* Fixed: mixed collation error in WordPress user synchronization. Thanks Chris, Till, Robin, Robero, @Seph, @kaiwen and others for the reports!
|
||||
|
||||
= 3.0.2 - 2017-10-03 =
|
||||
* Improved: plugin capabilities can be managed with Members plugin;
|
||||
* Improved: removes unsightly horizontal scrollbar in some parts of the newsletter editor;
|
||||
* Improved: email templates to be displayed in order of last modification;
|
||||
* Fixed: it's not possible to submit a subscription form multiple times with an existing e-mail address anymore. Thanks Suyog Palav and Bits of Freedom!
|
||||
* Fixed: users subscribed before registering on a site are synchronized during WP users sync. Thanks Nicolas!
|
||||
|
||||
= 3.0.1 - 2017-09-26 =
|
||||
* Added: images can be resized in newsletter editor;
|
||||
* Fixed: scheduled newsletters that are unscheduled will not be mistakenly sent. Thx Georges in Provence;
|
||||
|
@ -15,4 +15,14 @@ class AutomatedLatestContentTest extends \MailPoetTest {
|
||||
expect($post_type['label'])->notEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
function testItDoesNotGetPostTypesExludedFromSearch() {
|
||||
$router = new AutomatedLatestContent();
|
||||
$response = $router->getPostTypes();
|
||||
// WP's default post type 'revision' is excluded from search
|
||||
// https://codex.wordpress.org/Post_Types
|
||||
$revision_post_type = get_post_type_object('revision');
|
||||
expect($revision_post_type->exclude_from_search)->true();
|
||||
expect(isset($response->data['revision']))->false();
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
<?php
|
||||
namespace MailPoet\Test\API\JSON\v1;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Codeception\Util\Fixtures;
|
||||
use MailPoet\API\JSON\v1\Subscribers;
|
||||
use MailPoet\API\JSON\Response as APIResponse;
|
||||
@ -519,6 +520,34 @@ class SubscribersTest extends \MailPoetTest {
|
||||
}
|
||||
}
|
||||
|
||||
function testItCannotMassResubscribe() {
|
||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
|
||||
|
||||
$router = new Subscribers();
|
||||
$response = $router->subscribe(array(
|
||||
$this->obfuscatedEmail => 'toto@mailpoet.com',
|
||||
'form_id' => $this->form->id,
|
||||
$this->obfuscatedSegments => array($this->segment_1->id, $this->segment_2->id)
|
||||
));
|
||||
|
||||
// Try to resubscribe an existing subscriber that was updated just now
|
||||
$subscriber = Subscriber::findOne($response->data['id']);
|
||||
$subscriber->created_at = Carbon::yesterday();
|
||||
$subscriber->updated_at = Carbon::now();
|
||||
$subscriber->save();
|
||||
|
||||
try {
|
||||
$response = $router->subscribe(array(
|
||||
$this->obfuscatedEmail => $subscriber->email,
|
||||
'form_id' => $this->form->id,
|
||||
$this->obfuscatedSegments => array($this->segment_1->id, $this->segment_2->id)
|
||||
));
|
||||
$this->fail('It should not be possible to resubscribe a second time so soon');
|
||||
} catch(\Exception $e) {
|
||||
expect($e->getMessage())->equals('You need to wait before subscribing again.');
|
||||
}
|
||||
}
|
||||
|
||||
function _after() {
|
||||
Segment::deleteMany();
|
||||
Subscriber::deleteMany();
|
||||
|
@ -29,9 +29,6 @@ class AccessControlTest extends \MailPoetTest {
|
||||
AccessControl::PERMISSION_MANAGE_SEGMENTS => array(
|
||||
'administrator'
|
||||
),
|
||||
AccessControl::PERMISSION_UPDATE_PLUGIN => array(
|
||||
'administrator'
|
||||
)
|
||||
);
|
||||
$access_control = new AccessControl();
|
||||
expect($access_control->permissions)->equals($default_permissions);
|
||||
@ -74,12 +71,6 @@ class AccessControlTest extends \MailPoetTest {
|
||||
return array('custom_manage_segments_role');
|
||||
}
|
||||
);
|
||||
Hooks::addFilter(
|
||||
'mailpoet_permission_update_plugin',
|
||||
function() {
|
||||
return array('custom_update_plugin_role');
|
||||
}
|
||||
);
|
||||
|
||||
$access_control = new AccessControl();
|
||||
expect($access_control->permissions)->equals(
|
||||
@ -102,13 +93,16 @@ class AccessControlTest extends \MailPoetTest {
|
||||
AccessControl::PERMISSION_MANAGE_SEGMENTS => array(
|
||||
'custom_manage_segments_role'
|
||||
),
|
||||
AccessControl::PERMISSION_UPDATE_PLUGIN => array(
|
||||
'custom_update_plugin_role'
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function testItGetsPermissionLabels() {
|
||||
$permissions = AccessControl::getDefaultPermissions();
|
||||
$labels = AccessControl::getPermissionLabels();
|
||||
expect(count($permissions))->equals(count($labels));
|
||||
}
|
||||
|
||||
function _after() {
|
||||
WPHooksHelper::releaseAllHooks();
|
||||
}
|
||||
|
98
tests/unit/Config/CapabilitiesTest.php
Normal file
98
tests/unit/Config/CapabilitiesTest.php
Normal file
@ -0,0 +1,98 @@
|
||||
<?php
|
||||
namespace MailPoet\Test\Config;
|
||||
|
||||
use AspectMock\Test as Mock;
|
||||
use Codeception\Util\Stub;
|
||||
use Helper\WordPressHooks as WPHooksHelper;
|
||||
use MailPoet\Config\AccessControl;
|
||||
use MailPoet\Config\Capabilities;
|
||||
use MailPoet\Config\Renderer;
|
||||
|
||||
class CapabilitiesTest extends \MailPoetTest {
|
||||
function _before() {
|
||||
$renderer = new Renderer();
|
||||
$this->caps = new Capabilities($renderer);
|
||||
}
|
||||
|
||||
function testItInitializes() {
|
||||
$caps = Stub::makeEmptyExcept(
|
||||
$this->caps,
|
||||
'init',
|
||||
array('setupMembersCapabilities' => Stub::once()),
|
||||
$this
|
||||
);
|
||||
$caps->init();
|
||||
}
|
||||
|
||||
function testItSetsUpWPCapabilities() {
|
||||
$permissions = AccessControl::getDefaultPermissions();
|
||||
$this->caps->setupWPCapabilities();
|
||||
$checked = false;
|
||||
foreach($permissions as $name => $roles) {
|
||||
foreach($roles as $role) {
|
||||
$checked = true;
|
||||
expect(get_role($role)->has_cap($name))->true();
|
||||
}
|
||||
}
|
||||
expect($checked)->true();
|
||||
}
|
||||
|
||||
function testItRemovesWPCapabilities() {
|
||||
$permissions = AccessControl::getDefaultPermissions();
|
||||
$this->caps->removeWPCapabilities();
|
||||
$checked = false;
|
||||
foreach($permissions as $name => $roles) {
|
||||
foreach($roles as $role) {
|
||||
$checked = true;
|
||||
expect(get_role($role)->has_cap($name))->false();
|
||||
}
|
||||
}
|
||||
expect($checked)->true();
|
||||
// Restore capabilities
|
||||
$this->caps->setupWPCapabilities();
|
||||
}
|
||||
|
||||
function testItSetsUpMembersCapabilities() {
|
||||
WPHooksHelper::interceptAddAction();
|
||||
|
||||
$this->caps->setupMembersCapabilities();
|
||||
|
||||
$hook_name = 'members_register_cap_groups';
|
||||
expect(WPHooksHelper::isActionAdded($hook_name))->true();
|
||||
expect(is_callable(WPHooksHelper::getActionAdded($hook_name)[0]))->true();
|
||||
|
||||
$hook_name = 'members_register_caps';
|
||||
expect(WPHooksHelper::isActionAdded($hook_name))->true();
|
||||
expect(is_callable(WPHooksHelper::getActionAdded($hook_name)[0]))->true();
|
||||
}
|
||||
|
||||
function testItRegistersMembersCapGroup() {
|
||||
if(function_exists('members_register_cap_group')) { // Members plugin active
|
||||
$this->caps->registerMembersCapGroup();
|
||||
expect_that(members_cap_group_exists(Capabilities::MEMBERS_CAP_GROUP_NAME));
|
||||
} else {
|
||||
$func = Mock::func('MailPoet\Config', 'members_register_cap_group', true);
|
||||
$this->caps->registerMembersCapGroup();
|
||||
$func->verifyInvoked([Capabilities::MEMBERS_CAP_GROUP_NAME]);
|
||||
}
|
||||
}
|
||||
|
||||
function testItRegistersMembersCapabilities() {
|
||||
$permissions = AccessControl::getPermissionLabels();
|
||||
$permission_count = count($permissions);
|
||||
if(function_exists('members_register_cap')) { // Members plugin active
|
||||
$this->caps->registerMembersCapabilities();
|
||||
expect(members_get_cap_group(Capabilities::MEMBERS_CAP_GROUP_NAME)->caps)
|
||||
->count($permission_count);
|
||||
} else {
|
||||
$func = Mock::func('MailPoet\Config', 'members_register_cap', true);
|
||||
$this->caps->registerMembersCapabilities();
|
||||
$func->verifyInvokedMultipleTimes($permission_count);
|
||||
}
|
||||
}
|
||||
|
||||
function _after() {
|
||||
WPHooksHelper::releaseAllHooks();
|
||||
Mock::clean();
|
||||
}
|
||||
}
|
@ -32,6 +32,19 @@ class WPTest extends \MailPoetTest {
|
||||
expect($subscribersCount)->equals(3);
|
||||
}
|
||||
|
||||
function testItSynchronizesPresubscribedUsers() {
|
||||
$random_number = 12345;
|
||||
$subscriber = Subscriber::createOrUpdate(array(
|
||||
'email' => 'user-sync-test' . $random_number . '@example.com',
|
||||
'status' => Subscriber::STATUS_SUBSCRIBED
|
||||
));
|
||||
$id = $this->insertUser($random_number);
|
||||
WP::synchronizeUsers();
|
||||
$wp_subscriber = Segment::getWPSegment()->subscribers()->where('wp_user_id', $id)->findOne();
|
||||
expect($wp_subscriber)->notEmpty();
|
||||
expect($wp_subscriber->id)->equals($subscriber->id);
|
||||
}
|
||||
|
||||
function testItSynchronizeEmails() {
|
||||
$id = $this->insertUser();
|
||||
WP::synchronizeUsers();
|
||||
@ -216,16 +229,17 @@ class WPTest extends \MailPoetTest {
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function insertUser() {
|
||||
private function insertUser($number = null) {
|
||||
global $wpdb;
|
||||
$db = \ORM::getDb();
|
||||
$number_sql = !is_null($number) ? (int)$number : 'rand()';
|
||||
$db->exec(sprintf('
|
||||
INSERT INTO
|
||||
%s (user_login, user_email, user_registered)
|
||||
VALUES
|
||||
(
|
||||
CONCAT("user-sync-test", rand()),
|
||||
CONCAT("user-sync-test", rand(), "@example.com"),
|
||||
CONCAT("user-sync-test", ' . $number_sql . '),
|
||||
CONCAT("user-sync-test", ' . $number_sql . ', "@example.com"),
|
||||
"2017-01-02 12:31:12"
|
||||
)', $wpdb->users));
|
||||
$id = $db->lastInsertId();
|
||||
|
@ -19,7 +19,7 @@
|
||||
<a class="nav-tab" href="#basics"><%= __('Basics') %></a>
|
||||
<a class="nav-tab" href="#signup"><%= __('Sign-up Confirmation') %></a>
|
||||
<a class="nav-tab" href="#advanced"><%= __('Advanced') %></a>
|
||||
<a class="nav-tab" href="#premium"><%= __('Premium') %></a>
|
||||
<a class="nav-tab" href="#premium"><%= __('Key Activation') %></a>
|
||||
</h2>
|
||||
|
||||
<!-- sending method -->
|
||||
|
@ -67,6 +67,27 @@
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- roles and capabilities -->
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<%= __('Roles and capabilities') %>
|
||||
<p class="description">
|
||||
<%= __('Manage which WordPress roles access which features of MailPoet.') %>
|
||||
</p>
|
||||
</th>
|
||||
<td>
|
||||
<% if (members_plugin_active) %>
|
||||
<p>
|
||||
<a href="<%= admin_url('users.php?page=roles') %>"><%= __('Manage using the Members plugin') %></a>
|
||||
</p>
|
||||
<% else %>
|
||||
<%= __('Install the plugin [link]Members[/link] (free) to manage permissions.')
|
||||
|replaceLinkTags('https://wordpress.org/plugins/members/', {'target' : '_blank'})
|
||||
|raw
|
||||
%>
|
||||
<% endif %>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- link tracking -->
|
||||
<tr>
|
||||
<th scope="row">
|
||||
|
@ -4,10 +4,10 @@
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label for="mailpoet_premium_key">
|
||||
<%= __('Premium License Key') %>
|
||||
<%= __('Activation Key') %>
|
||||
</label>
|
||||
<p class="description">
|
||||
<%= __('This key is used for automatic upgrades of your Premium features and access to support.') %>
|
||||
<%= __('This key is used to validate your free or paid subscription. Paying customers will enjoy automatic upgrades of their Premium plugin and access to faster support.') %>
|
||||
</p>
|
||||
</th>
|
||||
<td>
|
||||
@ -32,7 +32,7 @@
|
||||
<div
|
||||
class="mailpoet_premium_key_invalid mailpoet_error_item mailpoet_error<% if not(settings.premium.premium_key) or premium_key_valid %> mailpoet_hidden<% endif %>"
|
||||
>
|
||||
<%= __('Your Premium key is invalid.') %>
|
||||
<%= __('Your key is not valid for the Premium plugin.') %>
|
||||
</div>
|
||||
<div
|
||||
class="mailpoet_mss_key_valid mailpoet_success_item mailpoet_success<% if not(settings.mta.mailpoet_api_key) or not(mss_key_valid) %> mailpoet_hidden<% endif %>"
|
||||
@ -42,7 +42,7 @@
|
||||
<div
|
||||
class="mailpoet_mss_key_invalid mailpoet_error_item mailpoet_error<% if not(settings.mta.mailpoet_api_key) or mss_key_valid %> mailpoet_hidden<% endif %>"
|
||||
>
|
||||
<%= __('Your MailPoet Sending Service key is invalid.') %>
|
||||
<%= __('Your key is not valid for the MailPoet Sending Service.') %>
|
||||
</div>
|
||||
<div
|
||||
class="mailpoet_premium_download mailpoet_spaced_block"
|
||||
|
@ -60,18 +60,8 @@
|
||||
<div class="feature-section one-col mailpoet_centered">
|
||||
<h2><%= __('Care to Give Your Opinion?') %></h2>
|
||||
|
||||
<div class="pd-embed" id="pd_1505214143"></div>
|
||||
<script type="text/javascript">
|
||||
var _polldaddy = [] || _polldaddy;
|
||||
_polldaddy.push( {
|
||||
type: "iframe",
|
||||
auto: "1",
|
||||
domain: "mailpoet.polldaddy.com/s/",
|
||||
id: "what-s-one-feature-that-s-missing-in-mailpoet",
|
||||
placeholder: "pd_1505214143"
|
||||
} );
|
||||
(function(d,c,j){if(!document.getElementById(j)){var pd=d.createElement(c),s;pd.id=j;pd.src=('https:'==document.location.protocol)?'https://polldaddy.com/survey.js':'http://i0.poll.fm/survey.js';s=document.getElementsByTagName(c)[0];s.parentNode.insertBefore(pd,s);}}(document,'script','pd-embed'));
|
||||
</script>
|
||||
<script type="text/javascript" charset="utf-8" src="https://static.polldaddy.com/p/9840615.js"></script>
|
||||
<noscript><a href="https://polldaddy.com/poll/9840615/">How did you find out about our plugin?</a></noscript>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
Reference in New Issue
Block a user