Merge pull request #292 from mailpoet/total_subscriber_shortcode

Shortcodes (Archives & Total subscribers) & MailPoet page (create on install)
This commit is contained in:
Tautvidas Sipavičius
2016-01-15 17:07:11 +02:00
10 changed files with 249 additions and 125 deletions

View File

@ -5,6 +5,7 @@ use MailPoet\Models;
use MailPoet\Cron\Supervisor;
use MailPoet\Router;
use MailPoet\Models\Setting;
use MailPoet\Settings\Pages;
if(!defined('ABSPATH')) exit;
@ -31,6 +32,7 @@ class Initializer {
$this->runQueueSupervisor();
$this->setupShortcodes();
$this->setupHooks();
$this->setupPages();
$this->setupImages();
}
@ -127,6 +129,11 @@ class Initializer {
$changelog->init();
}
function setupPages() {
$pages = new Pages();
$pages->init();
}
function setupShortcodes() {
$shortcodes = new Shortcodes();
$shortcodes->init();

View File

@ -8,6 +8,7 @@ use MailPoet\Config\PopulatorData\Templates\PostNotificationsBlankTemplate;
use \MailPoet\Models\Segment;
use \MailPoet\Segments\WP;
use \MailPoet\Models\Setting;
use \MailPoet\Settings\Pages;
if (!defined('ABSPATH')) exit;
@ -48,6 +49,29 @@ class Populator {
$this->createDefaultSegments();
$this->createDefaultSettings();
$this->createMailPoetPage();
}
private function createMailPoetPage() {
$pages = get_posts(array(
'posts_per_page' => 1,
'orderby' => 'date',
'order' => 'DESC',
'post_type' => 'mailpoet_page'
));
$page = null;
if(!empty($pages)) {
$page = array_shift($pages);
if(strpos($page->post_content, '[mailpoet_page]') === false) {
$page = null;
}
}
if($page === null) {
$mailpoet_page_id = Pages::createMailPoetPage();
Setting::setValue('subscription.page', $mailpoet_page_id);
}
}
private function createDefaultSettings() {
@ -74,9 +98,7 @@ class Populator {
));
// enable signup confirmation by default
Setting::setValue('signup_confirmation', array(
'enabled' => true
));
Setting::setValue('signup_confirmation.enabled', true);
}
private function createDefaultSegments() {

View File

@ -1,5 +1,8 @@
<?php
namespace MailPoet\Config;
use \MailPoet\Models\Newsletter;
use \MailPoet\Models\Subscriber;
use \MailPoet\Models\SubscriberSegment;
class Shortcodes {
function __construct() {
@ -9,6 +12,26 @@ class Shortcodes {
// form widget shortcode
add_shortcode('mailpoet_form', array($this, 'formWidget'));
add_shortcode('wysija_form', array($this, 'formWidget'));
// subscribers count shortcode
add_shortcode('mailpoet_subscribers_count', array(
$this, 'getSubscribersCount'
));
add_shortcode('wysija_subscribers_count', array(
$this, 'getSubscribersCount'
));
// archives page
add_shortcode('mailpoet_archive', array(
$this, 'getArchive'
));
add_filter('mailpoet_archive_date', array(
$this, 'renderArchiveDate'
), 2);
add_filter('mailpoet_archive_subject', array(
$this, 'renderArchiveSubject'
), 2);
}
function formWidget($params = array()) {
@ -23,4 +46,76 @@ class Shortcodes {
));
}
}
function getSubscribersCount($params) {
if(!empty($params['segments'])) {
$segment_ids = array_map(function($segment_id) {
return (int)trim($segment_id);
}, explode(',', $params['segments']));
}
if(empty($segment_ids)) {
return Subscriber::filter('subscribed')->count();
} else {
return SubscriberSegment::whereIn('segment_id', $segment_ids)
->select('subscriber_id')->distinct()
->filter('subscribed')
->findResultSet()->count();
}
}
function getArchive($params) {
if(!empty($params['segments'])) {
$segment_ids = array_map(function($segment_id) {
return (int)trim($segment_id);
}, explode(',', $params['segments']));
}
$newsletters = array();
$html = '';
// TODO: needs more advanced newsletters in order to finish
$newsletters = Newsletter::limit(10)->orderByDesc('created_at')->findMany();
if(empty($newsletters)) {
return apply_filters(
'mailpoet_archive_no_newsletters',
__('Oops! There are no newsletters to display.')
);
} else {
$title = apply_filters('mailpoet_archive_title', '');
if(!empty($title)) {
$html .= '<h3 class="mailpoet_archive_title">'.$title.'</h3>';
}
$html .= '<ul class="mailpoet_archive">';
foreach($newsletters as $newsletter) {
$html .= '<li>'.
'<span class="mailpoet_archive_date">'.
apply_filters('mailpoet_archive_date', $newsletter).
'</span>
<span class="mailpoet_archive_subject">'.
apply_filters('mailpoet_archive_subject', $newsletter).
'</span>
</li>';
}
$html .= '</ul>';
}
return $html;
}
function renderArchiveDate($newsletter) {
return date_i18n(
get_option('date_format'),
strtotime($newsletter->created_at)
);
}
function renderArchiveSubject($newsletter) {
return '<a href="TODO" target="_blank" title="'
.esc_attr(__('Preview in new tab')).'">'
.esc_attr($newsletter->subject).
'</a>';
}
}

View File

@ -1,6 +1,5 @@
<?php
namespace MailPoet\Config;
use \MailPoet\Models\Subscriber;
use \MailPoet\Util\Security;
if(!defined('ABSPATH')) exit;
@ -22,18 +21,6 @@ class Widget {
function registerWidget() {
register_widget('\MailPoet\Form\Widget');
// subscribers count shortcode
add_shortcode('mailpoet_subscribers_count', array(
$this, 'getSubscribersCount'
));
add_shortcode('wysija_subscribers_count', array(
$this, 'getSubscribersCount'
));
}
function getSubscribersCount($params) {
return Subscriber::filter('subscribed')->count();
}
function setupDependencies() {

View File

@ -194,96 +194,4 @@ class Widget extends \WP_Widget {
}
}
}
}
// set the content filter to replace the shortcode
if(isset($_GET['mailpoet_page']) && strlen(trim($_GET['mailpoet_page'])) > 0) {
switch($_GET['mailpoet_page']) {
case 'mailpoet_form_iframe':
$id = (isset($_GET['mailpoet_form']) && (int)$_GET['mailpoet_form'] > 0) ? (int)$_GET['mailpoet_form'] : null;
$form = Form::findOne($id);
if($form !== false) {
// render form
$output = Util\Export::get('html', $form->asArray());
// $output = do_shortcode($output);
print $output;
exit;
}
break;
default:
// add_filter('wp_title', 'mailpoet_meta_page_title'));
add_filter('the_title', 'mailpoet_page_title', 10, 2);
add_filter('the_content', 'mailpoet_page_content', 98, 1);
break;
}
}
function mailpoet_page_title($title = '', $id = null) {
// get signup confirmation page id
$signup_confirmation = Setting::getValue('signup_confirmation');
$page_id = $signup_confirmation['page'];
// check if we're on the signup confirmation page
if((int)$page_id === (int)$id) {
global $post;
// disable comments
$post->comment_status = 'close';
// disable password
$post->post_password = '';
$subscriber = null;
// get subscriber key from url
$subscriber_digest = (isset($_GET['mailpoet_key']) && strlen(trim($_GET['mailpoet_key'])) === 32) ? trim($_GET['mailpoet_key']) : null;
if($subscriber_digest !== null) {
// get subscriber
// TODO: change select() to selectOne() once it's implemented
$subscribers = $mailpoet->subscribers()->select(array(
'filter' => array(
'subscriber_digest' => $subscriber_digest
),
'limit' => 1
));
if(!empty($subscribers)) {
$subscriber = array_shift($subscribers);
}
}
// check if we have a subscriber record
if($subscriber === null) {
return __('Your confirmation link expired, please subscribe again.');
} else {
// we have a subscriber, let's check its state
switch($subscriber['subscriber_state']) {
case MailPoetSubscribers::STATE_UNCONFIRMED:
case MailPoetSubscribers::STATE_UNSUBSCRIBED:
// set subscriber state as confirmed
$mailpoet->subscribers()->update(array(
'subscriber' => $subscriber['subscriber'],
'subscriber_state' => MailPoetSubscribers::STATE_SUBSCRIBED,
'subscriber_confirmed_at' => time()
));
return __("You've subscribed");
break;
case MailPoetSubscribers::STATE_SUBSCRIBED:
return __("You've already subscribed");
break;
}
}
} else {
return $title;
}
}
function mailpoet_page_content($content = '') {
if(strpos($content, '[mailpoet_page]') !== FALSE) {
$content = str_replace('[mailpoet_page]', '', $content);
}
return $content;
}

View File

@ -48,14 +48,41 @@ class Setting extends Model {
}
public static function setValue($key, $value) {
if(is_array($value)) {
$value = serialize($value);
}
$keys = explode('.', $key);
return Setting::createOrUpdate(array(
'name' => $key,
'value' => $value
));
if(count($keys) === 1) {
if(is_array($value)) {
$value = serialize($value);
}
return Setting::createOrUpdate(array(
'name' => $key,
'value' => $value
));
} else {
$main_key = array_shift($keys);
$setting_value = static::getValue($main_key, array());
$current_value = &$setting_value;
$last_key = array_pop($keys);
foreach($keys as $key) {
if(!is_array($current_value)) {
$current_value = array();
}
if(!array_key_exists($key, $current_value)) {
$current_value = array($key => array());
}
$current_value =& $current_value[$key];
}
if(is_scalar($current_value)) {
$current_value = array();
}
$current_value[$last_key] = $value;
return static::setValue($main_key, $setting_value);
}
}
public static function getAll() {

View File

@ -33,6 +33,10 @@ class SubscriberSegment extends Model {
return $orm;
}
static function subscribed($orm) {
return $orm->where('status', 'subscribed');
}
static function createMultiple($segmnets, $subscribers) {
$values = Helpers::flattenArray(
array_map(function ($segment) use ($subscribers) {

View File

@ -2,22 +2,71 @@
namespace MailPoet\Settings;
class Pages {
function __construct() {
}
static function getAll() {
$mailpoet_pages = \get_posts(array(
function init() {
register_post_type('mailpoet_page', array(
'labels' => array(
'name' => __('MailPoet Page'),
'singular_name' => __('MailPoet Page')
),
'public' => true,
'has_archive' => false,
'show_ui' => true,
'show_in_menu' => false,
'rewrite' => false,
'show_in_nav_menus'=>false,
'can_export'=>false,
'publicly_queryable'=>true,
'exclude_from_search'=>true
));
}
static function createMailPoetPage() {
remove_all_actions('pre_post_update');
remove_all_actions('save_post');
remove_all_actions('wp_insert_post');
$id = wp_insert_post(array(
'post_status' => 'publish',
'post_type' => 'mailpoet_page',
'post_author' => 1,
'post_content' => '[mailpoet_page]',
'post_title' => __('MailPoet Page'),
'post_name' => 'subscriptions'
));
flush_rewrite_rules();
return ((int)$id > 0) ? (int)$id : false;
}
static function getMailPoetPages() {
return get_posts(array(
'post_type' => 'mailpoet_page'
));
}
static function getAll() {
$all_pages = array_merge(
static::getMailPoetPages(),
get_pages()
);
$pages = array();
foreach(array_merge($mailpoet_pages, \get_pages()) as $page) {
$pages[] = array(
'id' => $page->ID,
'title' => $page->post_title,
'preview_url' => \get_permalink($page->ID),
'edit_url' => \get_edit_post_link($page->ID)
);
foreach($all_pages as $page) {
$pages[] = static::getPageData($page);
}
return $pages;
}
static function getPageData($page) {
return array(
'id' => $page->ID,
'title' => $page->post_title,
'preview_url' => get_permalink($page->ID),
'edit_url' => get_edit_post_link($page->ID)
);
}
}

View File

@ -79,6 +79,31 @@ class SettingCest {
expect($record->value)->equals('new data');
}
function itCanGetAndSetValue() {
expect(Setting::setValue('test', '123'))->true();
expect(Setting::getValue('test'))->equals('123');
}
function itCanGetAndSetNestedValue() {
expect(Setting::setValue('test.key', '123'))->true();
expect(Setting::getValue('test.key'))->equals('123');
expect(Setting::setValue('test.key.subkey', '123'))->true();
expect(Setting::setValue('test.key.subkey2', '456'))->true();
expect(Setting::getValue('test.key'))->notEmpty();
expect(Setting::getValue('test.key.subkey'))->equals('123');
expect(Setting::getValue('test.key.subkey2'))->equals('456');
}
function itCanSetValueToNull() {
expect(Setting::setValue('test.key', true))->true();
expect(Setting::getValue('test.key'))->equals(true);
expect(Setting::setValue('test.key', null))->true();
expect(Setting::getValue('test.key'))->null();
}
function _after() {
ORM::forTable(Setting::$_table)
->deleteMany();

View File

@ -347,7 +347,7 @@
values = $(this).val() || [];
if (values.length > 0) {
shortcode += ' list_id="';
shortcode += ' segments="';
shortcode += values.join(',');
shortcode += '"';
}