Compare commits
33 Commits
Author | SHA1 | Date | |
---|---|---|---|
ebca4257a6 | |||
c3944095bc | |||
a1445d1b6a | |||
e62c24879b | |||
00f06ea202 | |||
32ca24ce38 | |||
44e3adb422 | |||
a1346ebecc | |||
25b51d0446 | |||
556a170903 | |||
7ac386a8e2 | |||
d91b55ec52 | |||
786fbc36a2 | |||
160e8b7a12 | |||
0b1f85da09 | |||
fbc6f54ddc | |||
a603e97b8c | |||
0875b627b6 | |||
035784ece0 | |||
aa93c7349f | |||
82cf4a28fd | |||
832e5ef342 | |||
e3de3a123a | |||
db91590159 | |||
28c61fca0b | |||
e62a8c2ec5 | |||
fdbd1245e3 | |||
0eef46db57 | |||
080ae88a04 | |||
225be9f3cd | |||
c9a42ebb76 | |||
ae9b3df92d | |||
63a08ebb55 |
3
.gitignore
vendored
3
.gitignore
vendored
@ -15,4 +15,5 @@ temp
|
|||||||
wysija-newsletters.zip
|
wysija-newsletters.zip
|
||||||
tests/javascript/testBundles
|
tests/javascript/testBundles
|
||||||
assets/css/*.css
|
assets/css/*.css
|
||||||
assets/js/*.js
|
assets/js/*.js
|
||||||
|
.vagrant
|
||||||
|
67
Vagrantfile
vendored
Normal file
67
Vagrantfile
vendored
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
# -*- mode: ruby -*-
|
||||||
|
# vi: set ft=ruby :
|
||||||
|
|
||||||
|
Vagrant.configure(2) do |config|
|
||||||
|
config.vm.provider "virtualbox" do |v|
|
||||||
|
v.name = "phoenix"
|
||||||
|
v.memory = "2048"
|
||||||
|
end
|
||||||
|
|
||||||
|
config.vm.define :web do |web|
|
||||||
|
web.vm.box = "ubuntu/trusty64"
|
||||||
|
web.vm.hostname = "phoenix"
|
||||||
|
web.vm.network "forwarded_port", guest: 80, host: 8080
|
||||||
|
web.vm.synced_folder(
|
||||||
|
".",
|
||||||
|
"/var/www/html/wp-content/plugins/wysija-newsletters",
|
||||||
|
create: true,
|
||||||
|
owner: "vagrant",
|
||||||
|
group: "www-data"
|
||||||
|
)
|
||||||
|
|
||||||
|
web.vm.provision "shell", inline: <<-SHELL
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y apache2 curl zip sendmail git build-essential
|
||||||
|
|
||||||
|
sudo debconf-set-selections <<< 'mysql-server mysql-server/root_password password root'
|
||||||
|
sudo debconf-set-selections <<< 'mysql-server mysql-server/root_password_again password root'
|
||||||
|
sudo apt-get install -y mysql-server-5.5
|
||||||
|
|
||||||
|
sudo apt-get install -y php5 libapache2-mod-php5 php5-curl php5-gd php5-mcrypt php5-readline mysql-server-5.5 php5-mysql php-apc
|
||||||
|
sudo sed -i "s/error_reporting = .*/error_reporting = E_ALL/" /etc/php5/apache2/php.ini
|
||||||
|
sudo sed -i "s/display_errors = .*/display_errors = On/" /etc/php5/apache2/php.ini
|
||||||
|
|
||||||
|
cd /var/www/html
|
||||||
|
|
||||||
|
sudo wget https://github.com/calvinlough/sqlbuddy/raw/gh-pages/sqlbuddy.zip -O /var/www/html/sqlbuddy.zip
|
||||||
|
sudo rm index.html
|
||||||
|
unzip sqlbuddy.zip
|
||||||
|
|
||||||
|
sudo curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
|
||||||
|
sudo chmod +x wp-cli.phar
|
||||||
|
sudo mv wp-cli.phar /usr/local/bin/wp
|
||||||
|
sudo wp core download --allow-root
|
||||||
|
mysql -uroot -proot -e "create database wordpress"
|
||||||
|
sudo wp core config --allow-root --dbname=wordpress --dbuser=root --dbpass=root
|
||||||
|
sudo wp core install --allow-root --url="http://localhost:8080" --title=WordPress --admin_user=admin --admin_password=password --admin_email=test@mailpoet-container.com
|
||||||
|
|
||||||
|
sudo sed -i "s/upload_max_filesize = .*/upload_max_filesize = 32M/" /etc/php5/apache2/php.ini
|
||||||
|
sudo sed -i "s/post_max_size = .*/post_max_size = 32M/" /etc/php5/apache2/php.ini
|
||||||
|
sudo chown -hR vagrant:www-data /var/www/html/
|
||||||
|
sudo a2enmod rewrite > /dev/null 2>&1
|
||||||
|
|
||||||
|
cd /var/www/html/wp-content/plugins/wysija-newsletters
|
||||||
|
|
||||||
|
curl -sS https://getcomposer.org/installer | php
|
||||||
|
|
||||||
|
sudo add-apt-repository -y ppa:chris-lea/node.js
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y nodejs
|
||||||
|
|
||||||
|
sudo sed -i "s/export APACHE_RUN_USER.*/export APACHE_RUN_USER=vagrant/" /etc/apache2/envvars
|
||||||
|
sudo chown -R vagrant:www-data /var/lock/apache2
|
||||||
|
|
||||||
|
sudo service apache2 restart
|
||||||
|
SHELL
|
||||||
|
end
|
||||||
|
end
|
@ -159,23 +159,6 @@ body.mailpoet_modal_opened
|
|||||||
margin: 0
|
margin: 0
|
||||||
text-align: right
|
text-align: right
|
||||||
|
|
||||||
.mailpoet_button
|
|
||||||
padding: 3px 15px
|
|
||||||
border: 1px solid #444
|
|
||||||
font-weight: normal
|
|
||||||
cursor: pointer
|
|
||||||
background-color: #222
|
|
||||||
color: #cfcfcf
|
|
||||||
font-size: 1em
|
|
||||||
|
|
||||||
.mailpoet_button:hover
|
|
||||||
background-color: #00aacc
|
|
||||||
color: #fff
|
|
||||||
|
|
||||||
.mailpoet_button:active
|
|
||||||
background-color: #00ccff
|
|
||||||
color: #fff
|
|
||||||
|
|
||||||
@media screen and (max-width: 782px)
|
@media screen and (max-width: 782px)
|
||||||
#mailpoet_modal_overlay.mailpoet_panel_overlay
|
#mailpoet_modal_overlay.mailpoet_panel_overlay
|
||||||
top: 46px
|
top: 46px
|
||||||
|
@ -19,6 +19,10 @@ $divider-hover-border-color = $primary-active-color
|
|||||||
width: 100%
|
width: 100%
|
||||||
border: 1px solid transparent
|
border: 1px solid transparent
|
||||||
|
|
||||||
|
.mailpoet_active_divider_style
|
||||||
|
border: 1px solid $active-divider-border-color
|
||||||
|
background: $active-divider-background-color
|
||||||
|
|
||||||
.mailpoet_field_divider_style:hover
|
.mailpoet_field_divider_style:hover
|
||||||
border: 1px solid $divider-hover-border-color
|
border: 1px solid $divider-hover-border-color
|
||||||
|
|
||||||
|
@ -1,15 +1,12 @@
|
|||||||
.mailpoet_posts_block
|
.mailpoet_posts_block
|
||||||
box-shadow(none)
|
padding-left: 0
|
||||||
|
padding-right: 0
|
||||||
|
|
||||||
& > .mailpoet_content
|
.mailpoet_posts_block_posts
|
||||||
font-size: 1em
|
overflow: auto
|
||||||
text-align: center
|
|
||||||
background-color: $primary-active-color
|
& > .mailpoet_block
|
||||||
margin: 20px 0
|
width: 100%
|
||||||
padding: 15px
|
|
||||||
box-shadow(inset 1px 2px 1px $primary-inset-shadow-color)
|
|
||||||
color: $white-color
|
|
||||||
border-radius(3px)
|
|
||||||
|
|
||||||
.mailpoet_post_selection_filter_row
|
.mailpoet_post_selection_filter_row
|
||||||
margin-top: 5px
|
margin-top: 5px
|
||||||
|
@ -306,7 +306,7 @@ define([
|
|||||||
_.each(postTypes, function(type) {
|
_.each(postTypes, function(type) {
|
||||||
select.append(jQuery('<option>', {
|
select.append(jQuery('<option>', {
|
||||||
value: type.name,
|
value: type.name,
|
||||||
text: type.labels.singular_name,
|
text: type.label,
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
select.val(selectedValue);
|
select.val(selectedValue);
|
||||||
|
@ -31,7 +31,7 @@ define([
|
|||||||
base = BaseBlock;
|
base = BaseBlock;
|
||||||
|
|
||||||
Module.PostsBlockModel = base.BlockModel.extend({
|
Module.PostsBlockModel = base.BlockModel.extend({
|
||||||
stale: ['_selectedPosts', '_availablePosts'],
|
stale: ['_selectedPosts', '_availablePosts', '_transformedPosts'],
|
||||||
defaults: function() {
|
defaults: function() {
|
||||||
return this._getDefaults({
|
return this._getDefaults({
|
||||||
type: 'posts',
|
type: 'posts',
|
||||||
@ -63,6 +63,7 @@ define([
|
|||||||
divider: {},
|
divider: {},
|
||||||
_selectedPosts: [],
|
_selectedPosts: [],
|
||||||
_availablePosts: [],
|
_availablePosts: [],
|
||||||
|
_transformedPosts: new (App.getBlockTypeModel('container'))(),
|
||||||
}, App.getConfig().get('blockDefaults.posts'));
|
}, App.getConfig().get('blockDefaults.posts'));
|
||||||
},
|
},
|
||||||
relations: function() {
|
relations: function() {
|
||||||
@ -71,15 +72,26 @@ define([
|
|||||||
divider: App.getBlockTypeModel('divider'),
|
divider: App.getBlockTypeModel('divider'),
|
||||||
_selectedPosts: Backbone.Collection,
|
_selectedPosts: Backbone.Collection,
|
||||||
_availablePosts: Backbone.Collection,
|
_availablePosts: Backbone.Collection,
|
||||||
|
_transformedPosts: App.getBlockTypeModel('container'),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
initialize: function() {
|
initialize: function() {
|
||||||
var that = this;
|
var that = this,
|
||||||
|
POST_REFRESH_DELAY_MS = 500,
|
||||||
|
refreshAvailablePosts = _.debounce(this.fetchAvailablePosts.bind(this), POST_REFRESH_DELAY_MS),
|
||||||
|
refreshTransformedPosts = _.debounce(this._refreshTransformedPosts.bind(this), POST_REFRESH_DELAY_MS);
|
||||||
|
|
||||||
// Attach Radio.Requests API primarily for highlighting
|
// Attach Radio.Requests API primarily for highlighting
|
||||||
_.extend(this, Radio.Requests);
|
_.extend(this, Radio.Requests);
|
||||||
|
|
||||||
this.fetchAvailablePosts();
|
this.fetchAvailablePosts();
|
||||||
this.on('change:amount change:contentType change:terms change:inclusionType change:postStatus change:search change:sortBy', this._scheduleFetchAvailablePosts, this);
|
this.on('change:amount change:contentType change:terms change:inclusionType change:postStatus change:search change:sortBy', refreshAvailablePosts);
|
||||||
|
|
||||||
|
this.listenTo(this.get('_selectedPosts'), 'add remove reset', refreshTransformedPosts);
|
||||||
|
this.on('change:displayType change:titleFormat change:titlePosition change:titleAlignment change:titleIsLink change:imagePadded change:showAuthor change:authorPrecededBy change:showCategories change:categoriesPrecededBy change:readMoreType change:readMoreText change:showDivider', refreshTransformedPosts);
|
||||||
|
this.listenTo(this.get('readMoreButton'), 'change', refreshTransformedPosts);
|
||||||
|
this.listenTo(this.get('divider'), 'change', refreshTransformedPosts);
|
||||||
|
|
||||||
this.on('insertSelectedPosts', this._insertSelectedPosts, this);
|
this.on('insertSelectedPosts', this._insertSelectedPosts, this);
|
||||||
},
|
},
|
||||||
fetchAvailablePosts: function() {
|
fetchAvailablePosts: function() {
|
||||||
@ -93,20 +105,23 @@ define([
|
|||||||
console.log('Posts fetchPosts error', arguments);
|
console.log('Posts fetchPosts error', arguments);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
/**
|
_refreshTransformedPosts: function() {
|
||||||
* Batch more changes during a specific time, instead of fetching
|
var that = this,
|
||||||
* ALC posts on each model change
|
data = this.toJSON();
|
||||||
*/
|
|
||||||
_scheduleFetchAvailablePosts: function() {
|
data.posts = this.get('_selectedPosts').pluck('ID');
|
||||||
var timeout = 500,
|
|
||||||
that = this;
|
if (data.posts.length === 0) {
|
||||||
if (this._fetchPostsTimer !== undefined) {
|
this.get('_transformedPosts.blocks').reset();
|
||||||
clearTimeout(this._fetchPostsTimer);
|
return;
|
||||||
}
|
}
|
||||||
this._fetchPostsTimer = setTimeout(function() {
|
|
||||||
that.fetchAvailablePosts();
|
WordpressComponent.getTransformedPosts(data).done(function(posts) {
|
||||||
that._fetchPostsTimer = undefined;
|
console.log('Transformed posts fetched', arguments);
|
||||||
}, timeout);
|
that.get('_transformedPosts').get('blocks').reset(posts, {parse: true});
|
||||||
|
}).fail(function() {
|
||||||
|
console.log('Posts _refreshTransformedPosts error', arguments);
|
||||||
|
});
|
||||||
},
|
},
|
||||||
_insertSelectedPosts: function() {
|
_insertSelectedPosts: function() {
|
||||||
var that = this,
|
var that = this,
|
||||||
@ -131,6 +146,9 @@ define([
|
|||||||
className: "mailpoet_block mailpoet_posts_block mailpoet_droppable_block",
|
className: "mailpoet_block mailpoet_posts_block mailpoet_droppable_block",
|
||||||
getTemplate: function() { return templates.postsBlock; },
|
getTemplate: function() { return templates.postsBlock; },
|
||||||
modelEvents: {},
|
modelEvents: {},
|
||||||
|
regions: _.extend({
|
||||||
|
postsRegion: '.mailpoet_posts_block_posts',
|
||||||
|
}, base.BlockView.prototype.regions),
|
||||||
onDragSubstituteBy: function() { return Module.PostsWidgetView; },
|
onDragSubstituteBy: function() { return Module.PostsWidgetView; },
|
||||||
initialize: function() {
|
initialize: function() {
|
||||||
base.BlockView.prototype.initialize.apply(this, arguments);
|
base.BlockView.prototype.initialize.apply(this, arguments);
|
||||||
@ -142,6 +160,13 @@ define([
|
|||||||
this.toolsRegion.show(this.toolsView);
|
this.toolsRegion.show(this.toolsView);
|
||||||
}
|
}
|
||||||
this.trigger('showSettings');
|
this.trigger('showSettings');
|
||||||
|
|
||||||
|
var ContainerView = App.getBlockTypeView('container'),
|
||||||
|
renderOptions = {
|
||||||
|
disableTextEditor: true,
|
||||||
|
disableDragAndDrop: true,
|
||||||
|
};
|
||||||
|
this.postsRegion.show(new ContainerView({ model: this.model.get('_transformedPosts'), renderOptions: renderOptions }));
|
||||||
},
|
},
|
||||||
notifyAboutSelf: function() {
|
notifyAboutSelf: function() {
|
||||||
return this;
|
return this;
|
||||||
@ -216,6 +241,7 @@ define([
|
|||||||
insertPosts: function() {
|
insertPosts: function() {
|
||||||
this.model.trigger('insertSelectedPosts');
|
this.model.trigger('insertSelectedPosts');
|
||||||
this.model.destroy();
|
this.model.destroy();
|
||||||
|
this.close();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -307,11 +333,6 @@ define([
|
|||||||
},
|
},
|
||||||
}).trigger( 'change' );
|
}).trigger( 'change' );
|
||||||
},
|
},
|
||||||
onBeforeDestroy: function() {
|
|
||||||
base.BlockSettingsView.prototype.onBeforeDestroy.apply(this, arguments);
|
|
||||||
// Force close select2 if it hasn't closed yet
|
|
||||||
this.$('.mailpoet_posts_categories_and_tags').select2('close');
|
|
||||||
},
|
|
||||||
changeField: function(field, event) {
|
changeField: function(field, event) {
|
||||||
this.model.set(field, jQuery(event.target).val());
|
this.model.set(field, jQuery(event.target).val());
|
||||||
},
|
},
|
||||||
@ -323,7 +344,7 @@ define([
|
|||||||
_.each(postTypes, function(type) {
|
_.each(postTypes, function(type) {
|
||||||
select.append(jQuery('<option>', {
|
select.append(jQuery('<option>', {
|
||||||
value: type.name,
|
value: type.name,
|
||||||
text: type.labels.singular_name,
|
text: type.label,
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
select.val(selectedValue);
|
select.val(selectedValue);
|
||||||
|
@ -56,7 +56,7 @@ define([
|
|||||||
};
|
};
|
||||||
|
|
||||||
Module.getTransformedPosts = function(options) {
|
Module.getTransformedPosts = function(options) {
|
||||||
return Module._cachedQuery({
|
return Module._query({
|
||||||
action: 'getTransformedPosts',
|
action: 'getTransformedPosts',
|
||||||
options: options,
|
options: options,
|
||||||
});
|
});
|
||||||
|
264
assets/js/src/vendor_static/jquery.sticky-kit.js
Normal file
264
assets/js/src/vendor_static/jquery.sticky-kit.js
Normal file
@ -0,0 +1,264 @@
|
|||||||
|
// Generated by CoffeeScript 1.9.2
|
||||||
|
|
||||||
|
/**
|
||||||
|
@license Sticky-kit v1.1.2 | WTFPL | Leaf Corcoran 2015 | http://leafo.net
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
var $, win;
|
||||||
|
|
||||||
|
$ = this.jQuery || window.jQuery;
|
||||||
|
|
||||||
|
win = $(window);
|
||||||
|
|
||||||
|
$.fn.stick_in_parent = function(opts) {
|
||||||
|
var doc, elm, enable_bottoming, fn, i, inner_scrolling, len, manual_spacer, offset_top, outer_width, parent_selector, recalc_every, sticky_class;
|
||||||
|
if (opts == null) {
|
||||||
|
opts = {};
|
||||||
|
}
|
||||||
|
sticky_class = opts.sticky_class, inner_scrolling = opts.inner_scrolling, recalc_every = opts.recalc_every, parent_selector = opts.parent, offset_top = opts.offset_top, manual_spacer = opts.spacer, enable_bottoming = opts.bottoming;
|
||||||
|
if (offset_top == null) {
|
||||||
|
offset_top = 0;
|
||||||
|
}
|
||||||
|
if (parent_selector == null) {
|
||||||
|
parent_selector = void 0;
|
||||||
|
}
|
||||||
|
if (inner_scrolling == null) {
|
||||||
|
inner_scrolling = true;
|
||||||
|
}
|
||||||
|
if (sticky_class == null) {
|
||||||
|
sticky_class = "is_stuck";
|
||||||
|
}
|
||||||
|
doc = $(document);
|
||||||
|
if (enable_bottoming == null) {
|
||||||
|
enable_bottoming = true;
|
||||||
|
}
|
||||||
|
outer_width = function(el) {
|
||||||
|
var _el, computed, w;
|
||||||
|
if (window.getComputedStyle) {
|
||||||
|
_el = el[0];
|
||||||
|
computed = window.getComputedStyle(el[0]);
|
||||||
|
w = parseFloat(computed.getPropertyValue("width")) + parseFloat(computed.getPropertyValue("margin-left")) + parseFloat(computed.getPropertyValue("margin-right"));
|
||||||
|
if (computed.getPropertyValue("box-sizing") !== "border-box") {
|
||||||
|
w += parseFloat(computed.getPropertyValue("border-left-width")) + parseFloat(computed.getPropertyValue("border-right-width")) + parseFloat(computed.getPropertyValue("padding-left")) + parseFloat(computed.getPropertyValue("padding-right"));
|
||||||
|
}
|
||||||
|
return w;
|
||||||
|
} else {
|
||||||
|
return el.outerWidth(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
fn = function(elm, padding_bottom, parent_top, parent_height, top, height, el_float, detached) {
|
||||||
|
var bottomed, detach, fixed, last_pos, last_scroll_height, offset, parent, recalc, recalc_and_tick, recalc_counter, spacer, tick;
|
||||||
|
if (elm.data("sticky_kit")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
elm.data("sticky_kit", true);
|
||||||
|
last_scroll_height = doc.height();
|
||||||
|
parent = elm.parent();
|
||||||
|
if (parent_selector != null) {
|
||||||
|
parent = parent.closest(parent_selector);
|
||||||
|
}
|
||||||
|
if (!parent.length) {
|
||||||
|
throw "failed to find stick parent";
|
||||||
|
}
|
||||||
|
fixed = false;
|
||||||
|
bottomed = false;
|
||||||
|
spacer = manual_spacer != null ? manual_spacer && elm.closest(manual_spacer) : $("<div />");
|
||||||
|
if (spacer) {
|
||||||
|
spacer.css('position', elm.css('position'));
|
||||||
|
}
|
||||||
|
recalc = function() {
|
||||||
|
var border_top, padding_top, restore;
|
||||||
|
if (detached) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
last_scroll_height = doc.height();
|
||||||
|
border_top = parseInt(parent.css("border-top-width"), 10);
|
||||||
|
padding_top = parseInt(parent.css("padding-top"), 10);
|
||||||
|
padding_bottom = parseInt(parent.css("padding-bottom"), 10);
|
||||||
|
parent_top = parent.offset().top + border_top + padding_top;
|
||||||
|
parent_height = parent.height();
|
||||||
|
if (fixed) {
|
||||||
|
fixed = false;
|
||||||
|
bottomed = false;
|
||||||
|
if (manual_spacer == null) {
|
||||||
|
elm.insertAfter(spacer);
|
||||||
|
spacer.detach();
|
||||||
|
}
|
||||||
|
elm.css({
|
||||||
|
position: "",
|
||||||
|
top: "",
|
||||||
|
width: "",
|
||||||
|
bottom: ""
|
||||||
|
}).removeClass(sticky_class);
|
||||||
|
restore = true;
|
||||||
|
}
|
||||||
|
top = elm.offset().top - (parseInt(elm.css("margin-top"), 10) || 0) - offset_top;
|
||||||
|
height = elm.outerHeight(true);
|
||||||
|
el_float = elm.css("float");
|
||||||
|
if (spacer) {
|
||||||
|
spacer.css({
|
||||||
|
width: outer_width(elm),
|
||||||
|
height: height,
|
||||||
|
display: elm.css("display"),
|
||||||
|
"vertical-align": elm.css("vertical-align"),
|
||||||
|
"float": el_float
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (restore) {
|
||||||
|
return tick();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
recalc();
|
||||||
|
|
||||||
|
last_pos = void 0;
|
||||||
|
offset = offset_top;
|
||||||
|
recalc_counter = recalc_every;
|
||||||
|
tick = function() {
|
||||||
|
var css, delta, recalced, scroll, will_bottom, win_height;
|
||||||
|
if (detached) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
recalced = false;
|
||||||
|
if (recalc_counter != null) {
|
||||||
|
recalc_counter -= 1;
|
||||||
|
if (recalc_counter <= 0) {
|
||||||
|
recalc_counter = recalc_every;
|
||||||
|
recalc();
|
||||||
|
recalced = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!recalced && doc.height() !== last_scroll_height) {
|
||||||
|
recalc();
|
||||||
|
recalced = true;
|
||||||
|
}
|
||||||
|
scroll = win.scrollTop();
|
||||||
|
if (last_pos != null) {
|
||||||
|
delta = scroll - last_pos;
|
||||||
|
}
|
||||||
|
last_pos = scroll;
|
||||||
|
if (fixed) {
|
||||||
|
if (enable_bottoming) {
|
||||||
|
will_bottom = scroll + height + offset > parent_height + parent_top;
|
||||||
|
if (bottomed && !will_bottom) {
|
||||||
|
bottomed = false;
|
||||||
|
elm.css({
|
||||||
|
position: "fixed",
|
||||||
|
bottom: "",
|
||||||
|
top: offset
|
||||||
|
}).trigger("sticky_kit:unbottom");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (scroll < top) {
|
||||||
|
fixed = false;
|
||||||
|
offset = offset_top;
|
||||||
|
if (manual_spacer == null) {
|
||||||
|
if (el_float === "left" || el_float === "right") {
|
||||||
|
elm.insertAfter(spacer);
|
||||||
|
}
|
||||||
|
spacer.detach();
|
||||||
|
}
|
||||||
|
css = {
|
||||||
|
position: "",
|
||||||
|
width: "",
|
||||||
|
top: ""
|
||||||
|
};
|
||||||
|
elm.css(css).removeClass(sticky_class).trigger("sticky_kit:unstick");
|
||||||
|
}
|
||||||
|
if (inner_scrolling) {
|
||||||
|
win_height = win.height();
|
||||||
|
if (height + offset_top > win_height) {
|
||||||
|
if (!bottomed) {
|
||||||
|
offset -= delta;
|
||||||
|
offset = Math.max(win_height - height, offset);
|
||||||
|
offset = Math.min(offset_top, offset);
|
||||||
|
if (fixed) {
|
||||||
|
elm.css({
|
||||||
|
top: offset + "px"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (scroll > top) {
|
||||||
|
fixed = true;
|
||||||
|
css = {
|
||||||
|
position: "fixed",
|
||||||
|
top: offset
|
||||||
|
};
|
||||||
|
css.width = elm.css("box-sizing") === "border-box" ? elm.outerWidth() + "px" : elm.width() + "px";
|
||||||
|
elm.css(css).addClass(sticky_class);
|
||||||
|
if (manual_spacer == null) {
|
||||||
|
elm.after(spacer);
|
||||||
|
if (el_float === "left" || el_float === "right") {
|
||||||
|
spacer.append(elm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
elm.trigger("sticky_kit:stick");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (fixed && enable_bottoming) {
|
||||||
|
if (will_bottom == null) {
|
||||||
|
will_bottom = scroll + height + offset > parent_height + parent_top;
|
||||||
|
}
|
||||||
|
if (!bottomed && will_bottom) {
|
||||||
|
bottomed = true;
|
||||||
|
if (parent.css("position") === "static") {
|
||||||
|
parent.css({
|
||||||
|
position: "relative"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return elm.css({
|
||||||
|
position: "absolute",
|
||||||
|
bottom: padding_bottom,
|
||||||
|
top: "auto"
|
||||||
|
}).trigger("sticky_kit:bottom");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
recalc_and_tick = function() {
|
||||||
|
recalc();
|
||||||
|
return tick();
|
||||||
|
};
|
||||||
|
detach = function() {
|
||||||
|
detached = true;
|
||||||
|
win.off("touchmove", tick);
|
||||||
|
win.off("scroll", tick);
|
||||||
|
win.off("resize", recalc_and_tick);
|
||||||
|
$(document.body).off("sticky_kit:recalc", recalc_and_tick);
|
||||||
|
elm.off("sticky_kit:detach", detach);
|
||||||
|
elm.removeData("sticky_kit");
|
||||||
|
elm.css({
|
||||||
|
position: "",
|
||||||
|
bottom: "",
|
||||||
|
top: "",
|
||||||
|
width: ""
|
||||||
|
});
|
||||||
|
parent.position("position", "");
|
||||||
|
if (fixed) {
|
||||||
|
if (manual_spacer == null) {
|
||||||
|
if (el_float === "left" || el_float === "right") {
|
||||||
|
elm.insertAfter(spacer);
|
||||||
|
}
|
||||||
|
spacer.remove();
|
||||||
|
}
|
||||||
|
return elm.removeClass(sticky_class);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
win.on("touchmove", tick);
|
||||||
|
win.on("scroll", tick);
|
||||||
|
win.on("resize", recalc_and_tick);
|
||||||
|
$(document.body).on("sticky_kit:recalc", recalc_and_tick);
|
||||||
|
elm.on("sticky_kit:detach", detach);
|
||||||
|
return setTimeout(tick, 0);
|
||||||
|
};
|
||||||
|
for (i = 0, len = this.length; i < len; i++) {
|
||||||
|
elm = this[i];
|
||||||
|
fn($(elm));
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
}).call(this);
|
||||||
|
|
6
build
6
build
@ -7,12 +7,10 @@ rm wysija-newsletters.zip;
|
|||||||
mkdir wysija-newsletters;
|
mkdir wysija-newsletters;
|
||||||
|
|
||||||
# Production assets.
|
# Production assets.
|
||||||
|
npm install;
|
||||||
./do compile:all;
|
./do compile:all;
|
||||||
|
|
||||||
# Production libraries.
|
# Production libraries.
|
||||||
rm -rf vendor;
|
|
||||||
rm -rf node_modules;
|
|
||||||
rm composer.lock;
|
|
||||||
./composer.phar install --no-dev;
|
./composer.phar install --no-dev;
|
||||||
|
|
||||||
# Copy release folders.
|
# Copy release folders.
|
||||||
@ -38,6 +36,4 @@ zip -r wysija-newsletters.zip wysija-newsletters;
|
|||||||
rm -rf wysija-newsletters;
|
rm -rf wysija-newsletters;
|
||||||
|
|
||||||
# Reinstall dev dependencies.
|
# Reinstall dev dependencies.
|
||||||
rm composer.lock;
|
|
||||||
./composer.phar install;
|
./composer.phar install;
|
||||||
./do install;
|
|
||||||
|
61
lib/Config/Changelog.php
Normal file
61
lib/Config/Changelog.php
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
<?php
|
||||||
|
namespace MailPoet\Config;
|
||||||
|
use \MailPoet\Models\Setting;
|
||||||
|
|
||||||
|
class Changelog {
|
||||||
|
function init() {
|
||||||
|
$doing_ajax = (bool)(defined('DOING_AJAX') && DOING_AJAX);
|
||||||
|
|
||||||
|
// don't run any check when it's an ajax request
|
||||||
|
if($doing_ajax) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// don't run any check when we're not on our pages
|
||||||
|
if(
|
||||||
|
!(isset($_GET['page']))
|
||||||
|
or
|
||||||
|
(isset($_GET['page']) && strpos($_GET['page'], 'mailpoet') !== 0)
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
add_action(
|
||||||
|
'admin_init',
|
||||||
|
array($this, 'check')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function check() {
|
||||||
|
$version = Setting::getValue('version', null);
|
||||||
|
$redirect_url = null;
|
||||||
|
|
||||||
|
if($version === null) {
|
||||||
|
// new install
|
||||||
|
$redirect_url = admin_url('admin.php?page=mailpoet-welcome');
|
||||||
|
} else if($version !== Env::$version) {
|
||||||
|
// update
|
||||||
|
$redirect_url = admin_url('admin.php?page=mailpoet-update');
|
||||||
|
}
|
||||||
|
|
||||||
|
if($redirect_url !== null) {
|
||||||
|
// save version number
|
||||||
|
Setting::setValue('version', Env::$version);
|
||||||
|
|
||||||
|
global $wp;
|
||||||
|
$current_url = home_url(add_query_arg($wp->query_string, $wp->request));
|
||||||
|
|
||||||
|
if($redirect_url !== $current_url) {
|
||||||
|
wp_safe_redirect(
|
||||||
|
add_query_arg(
|
||||||
|
array(
|
||||||
|
'mailpoet_redirect' => urlencode($current_url)
|
||||||
|
),
|
||||||
|
$redirect_url
|
||||||
|
)
|
||||||
|
);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -6,6 +6,7 @@ if(!defined('ABSPATH')) exit;
|
|||||||
class Env {
|
class Env {
|
||||||
public static $version;
|
public static $version;
|
||||||
public static $plugin_name;
|
public static $plugin_name;
|
||||||
|
public static $plugin_url;
|
||||||
public static $file;
|
public static $file;
|
||||||
public static $path;
|
public static $path;
|
||||||
public static $views_path;
|
public static $views_path;
|
||||||
@ -29,9 +30,10 @@ class Env {
|
|||||||
public static function init($file, $version) {
|
public static function init($file, $version) {
|
||||||
global $wpdb;
|
global $wpdb;
|
||||||
self::$version = $version;
|
self::$version = $version;
|
||||||
self::$plugin_name = 'mailpoet';
|
|
||||||
self::$file = $file;
|
self::$file = $file;
|
||||||
self::$path = dirname(self::$file);
|
self::$path = dirname(self::$file);
|
||||||
|
self::$plugin_name = 'mailpoet';
|
||||||
|
self::$plugin_url = plugins_url() . '/' . basename(Env::$path);
|
||||||
self::$views_path = self::$path . '/views';
|
self::$views_path = self::$path . '/views';
|
||||||
self::$assets_path = self::$path . '/assets';
|
self::$assets_path = self::$path . '/assets';
|
||||||
self::$assets_url = plugins_url('/assets', $file);
|
self::$assets_url = plugins_url('/assets', $file);
|
||||||
|
@ -24,6 +24,7 @@ class Initializer {
|
|||||||
$this->setupWidget();
|
$this->setupWidget();
|
||||||
$this->setupAnalytics();
|
$this->setupAnalytics();
|
||||||
$this->setupPermissions();
|
$this->setupPermissions();
|
||||||
|
$this->setupChangelog();
|
||||||
}
|
}
|
||||||
|
|
||||||
function setupDB() {
|
function setupDB() {
|
||||||
@ -104,4 +105,9 @@ class Initializer {
|
|||||||
$permissions = new Permissions();
|
$permissions = new Permissions();
|
||||||
$permissions->init();
|
$permissions->init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setupChangelog() {
|
||||||
|
$changelog = new Changelog();
|
||||||
|
$changelog->init();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,7 @@ class Menu {
|
|||||||
'MailPoet',
|
'MailPoet',
|
||||||
'manage_options',
|
'manage_options',
|
||||||
'mailpoet',
|
'mailpoet',
|
||||||
array($this, 'welcome'),
|
array($this, 'home'),
|
||||||
$this->assets_url . '/img/menu_icon.png',
|
$this->assets_url . '/img/menu_icon.png',
|
||||||
30
|
30
|
||||||
);
|
);
|
||||||
@ -94,31 +94,42 @@ class Menu {
|
|||||||
'mailpoet-export',
|
'mailpoet-export',
|
||||||
array($this, 'export')
|
array($this, 'export')
|
||||||
);
|
);
|
||||||
// add_submenu_page(
|
|
||||||
// 'mailpoet',
|
|
||||||
// __('Newsletter editor'),
|
|
||||||
// __('Newsletter editor'),
|
|
||||||
// 'manage_options',
|
|
||||||
// 'mailpoet-newsletter-editor',
|
|
||||||
// array($this, 'newletterEditor')
|
|
||||||
// );
|
|
||||||
$this->registered_pages();
|
|
||||||
}
|
|
||||||
|
|
||||||
function registered_pages() {
|
add_submenu_page(
|
||||||
global $_registered_pages;
|
null,
|
||||||
$pages = array(
|
__('Welcome'),
|
||||||
'mailpoet-welcome' => array($this, 'welcome'),
|
__('Welcome'),
|
||||||
'mailpoet-form-editor' => array($this, 'formEditor'),
|
'manage_options',
|
||||||
'mailpoet-newsletter-editor' => array($this, 'newletterEditor')
|
'mailpoet-welcome',
|
||||||
|
array($this, 'welcome')
|
||||||
|
);
|
||||||
|
|
||||||
|
add_submenu_page(
|
||||||
|
null,
|
||||||
|
__('Update'),
|
||||||
|
__('Update'),
|
||||||
|
'manage_options',
|
||||||
|
'mailpoet-update',
|
||||||
|
array($this, 'update')
|
||||||
|
);
|
||||||
|
|
||||||
|
add_submenu_page(
|
||||||
|
null,
|
||||||
|
__('Form editor'),
|
||||||
|
__('Form editor'),
|
||||||
|
'manage_options',
|
||||||
|
'mailpoet-form-editor',
|
||||||
|
array($this, 'formEditor')
|
||||||
|
);
|
||||||
|
|
||||||
|
add_submenu_page(
|
||||||
|
null,
|
||||||
|
__('Newsletter editor'),
|
||||||
|
__('Newsletter editor'),
|
||||||
|
'manage_options',
|
||||||
|
'mailpoet-newsletter-editor',
|
||||||
|
array($this, 'newletterEditor')
|
||||||
);
|
);
|
||||||
foreach($pages as $menu_slug => $callback) {
|
|
||||||
$hookname = get_plugin_page_hookname($menu_slug, null);
|
|
||||||
if(!empty($hookname)) {
|
|
||||||
add_action($hookname, $callback);
|
|
||||||
}
|
|
||||||
$_registered_pages[$hookname] = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function home() {
|
function home() {
|
||||||
@ -127,12 +138,52 @@ class Menu {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function welcome() {
|
function welcome() {
|
||||||
|
global $wp;
|
||||||
|
$current_url = home_url(add_query_arg($wp->query_string, $wp->request));
|
||||||
|
$redirect_url =
|
||||||
|
(!empty($_GET['mailpoet_redirect']))
|
||||||
|
? urldecode($_GET['mailpoet_redirect'])
|
||||||
|
: wp_get_referer();
|
||||||
|
|
||||||
|
if(
|
||||||
|
$redirect_url === $current_url
|
||||||
|
or
|
||||||
|
strpos($redirect_url, 'mailpoet') === false
|
||||||
|
) {
|
||||||
|
$redirect_url = admin_url('admin.php?page=mailpoet');
|
||||||
|
}
|
||||||
|
|
||||||
$data = array(
|
$data = array(
|
||||||
'settings' => Setting::getAll(),
|
'settings' => Setting::getAll(),
|
||||||
'current_user' => wp_get_current_user()
|
'current_user' => wp_get_current_user(),
|
||||||
|
'redirect_url' => $redirect_url
|
||||||
|
);
|
||||||
|
echo $this->renderer->render('welcome.html', $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
function update() {
|
||||||
|
global $wp;
|
||||||
|
$current_url = home_url(add_query_arg($wp->query_string, $wp->request));
|
||||||
|
$redirect_url =
|
||||||
|
(!empty($_GET['mailpoet_redirect']))
|
||||||
|
? urldecode($_GET['mailpoet_redirect'])
|
||||||
|
: wp_get_referer();
|
||||||
|
|
||||||
|
if(
|
||||||
|
$redirect_url === $current_url
|
||||||
|
or
|
||||||
|
strpos($redirect_url, 'mailpoet') === false
|
||||||
|
) {
|
||||||
|
$redirect_url = admin_url('admin.php?page=mailpoet');
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = array(
|
||||||
|
'settings' => Setting::getAll(),
|
||||||
|
'current_user' => wp_get_current_user(),
|
||||||
|
'redirect_url' => $redirect_url
|
||||||
);
|
);
|
||||||
|
|
||||||
echo $this->renderer->render('welcome.html', $data);
|
echo $this->renderer->render('update.html', $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
function settings() {
|
function settings() {
|
||||||
|
@ -14,9 +14,17 @@ class Newsletter extends Model {
|
|||||||
if(is_string($this->deleted_at) && strlen(trim($this->deleted_at)) === 0) {
|
if(is_string($this->deleted_at) && strlen(trim($this->deleted_at)) === 0) {
|
||||||
$this->set_expr('deleted_at', 'NULL');
|
$this->set_expr('deleted_at', 'NULL');
|
||||||
}
|
}
|
||||||
|
|
||||||
return parent::save();
|
return parent::save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function delete() {
|
||||||
|
// delete all relations to segments
|
||||||
|
NewsletterSegment::where('newsletter_id', $this->id)->deleteMany();
|
||||||
|
|
||||||
|
return parent::delete();
|
||||||
|
}
|
||||||
|
|
||||||
function segments() {
|
function segments() {
|
||||||
return $this->has_many_through(
|
return $this->has_many_through(
|
||||||
__NAMESPACE__.'\Segment',
|
__NAMESPACE__.'\Segment',
|
||||||
@ -126,8 +134,8 @@ class Newsletter extends Model {
|
|||||||
static function createOrUpdate($data = array()) {
|
static function createOrUpdate($data = array()) {
|
||||||
$newsletter = false;
|
$newsletter = false;
|
||||||
|
|
||||||
if(isset($data['id']) && (int) $data['id'] > 0) {
|
if(isset($data['id']) && (int)$data['id'] > 0) {
|
||||||
$newsletter = self::findOne((int) $data['id']);
|
$newsletter = self::findOne((int)$data['id']);
|
||||||
}
|
}
|
||||||
|
|
||||||
if($newsletter === false) {
|
if($newsletter === false) {
|
||||||
|
@ -17,7 +17,7 @@ class Segment extends Model {
|
|||||||
function delete() {
|
function delete() {
|
||||||
// delete all relations to subscribers
|
// delete all relations to subscribers
|
||||||
SubscriberSegment::where('segment_id', $this->id)->deleteMany();
|
SubscriberSegment::where('segment_id', $this->id)->deleteMany();
|
||||||
parent::delete();
|
return parent::delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
function newsletters() {
|
function newsletters() {
|
||||||
|
@ -28,6 +28,13 @@ class Setting extends Model {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function setValue($key, $value) {
|
||||||
|
return Setting::createOrUpdate(array(
|
||||||
|
'name' => $key,
|
||||||
|
'value' => $value
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
public static function getAll() {
|
public static function getAll() {
|
||||||
$settingsCollection = self::findMany();
|
$settingsCollection = self::findMany();
|
||||||
$settings = array();
|
$settings = array();
|
||||||
|
@ -135,20 +135,41 @@ class Subscriber extends Model {
|
|||||||
MP_SUBSCRIBER_CUSTOM_FIELD_TABLE . '.value END), NULL) as "' . $customField['name'].'"');
|
MP_SUBSCRIBER_CUSTOM_FIELD_TABLE . '.value END), NULL) as "' . $customField['name'].'"');
|
||||||
}
|
}
|
||||||
$orm = $orm
|
$orm = $orm
|
||||||
->left_outer_join(
|
->leftOuterJoin(
|
||||||
MP_SUBSCRIBER_CUSTOM_FIELD_TABLE,
|
MP_SUBSCRIBER_CUSTOM_FIELD_TABLE,
|
||||||
array(MP_SUBSCRIBERS_TABLE.'.id', '=',
|
array(MP_SUBSCRIBERS_TABLE.'.id', '=',
|
||||||
MP_SUBSCRIBER_CUSTOM_FIELD_TABLE.'.subscriber_id'))
|
MP_SUBSCRIBER_CUSTOM_FIELD_TABLE.'.subscriber_id'))
|
||||||
->left_outer_join(
|
->leftOuterJoin(
|
||||||
MP_CUSTOM_FIELDS_TABLE,
|
MP_CUSTOM_FIELDS_TABLE,
|
||||||
array(MP_CUSTOM_FIELDS_TABLE.'.id','=',
|
array(MP_CUSTOM_FIELDS_TABLE.'.id','=',
|
||||||
MP_SUBSCRIBER_CUSTOM_FIELD_TABLE.'.custom_field_id'))
|
MP_SUBSCRIBER_CUSTOM_FIELD_TABLE.'.custom_field_id'))
|
||||||
->group_by(MP_SUBSCRIBERS_TABLE.'.id');
|
->groupBy(MP_SUBSCRIBERS_TABLE.'.id');
|
||||||
|
return $orm;
|
||||||
|
}
|
||||||
|
|
||||||
|
static function filterWithCustomFieldsForExport($orm) {
|
||||||
|
$orm = $orm->select(MP_SUBSCRIBERS_TABLE.'.*');
|
||||||
|
$customFields = CustomField::findArray();
|
||||||
|
foreach ($customFields as $customField) {
|
||||||
|
$orm = $orm->selectExpr(
|
||||||
|
'CASE WHEN ' .
|
||||||
|
MP_CUSTOM_FIELDS_TABLE . '.id=' . $customField['id'] . ' THEN ' .
|
||||||
|
MP_SUBSCRIBER_CUSTOM_FIELD_TABLE . '.value END as "' . $customField['name'].'"');
|
||||||
|
}
|
||||||
|
$orm = $orm
|
||||||
|
->leftOuterJoin(
|
||||||
|
MP_SUBSCRIBER_CUSTOM_FIELD_TABLE,
|
||||||
|
array(MP_SUBSCRIBERS_TABLE.'.id', '=',
|
||||||
|
MP_SUBSCRIBER_CUSTOM_FIELD_TABLE.'.subscriber_id'))
|
||||||
|
->leftOuterJoin(
|
||||||
|
MP_CUSTOM_FIELDS_TABLE,
|
||||||
|
array(MP_CUSTOM_FIELDS_TABLE.'.id','=',
|
||||||
|
MP_SUBSCRIBER_CUSTOM_FIELD_TABLE.'.custom_field_id'));
|
||||||
return $orm;
|
return $orm;
|
||||||
}
|
}
|
||||||
|
|
||||||
function customFields() {
|
function customFields() {
|
||||||
return $this->has_many_through(
|
return $this->hasManyThrough(
|
||||||
__NAMESPACE__.'\CustomField',
|
__NAMESPACE__.'\CustomField',
|
||||||
__NAMESPACE__.'\SubscriberCustomField',
|
__NAMESPACE__.'\SubscriberCustomField',
|
||||||
'subscriber_id',
|
'subscriber_id',
|
||||||
|
@ -50,9 +50,11 @@ class MetaInformationManager {
|
|||||||
// check if the user specified a label to be displayed before the author's name
|
// check if the user specified a label to be displayed before the author's name
|
||||||
if(strlen($preceded_by) > 0) {
|
if(strlen($preceded_by) > 0) {
|
||||||
$content = stripslashes($preceded_by) . ' ';
|
$content = stripslashes($preceded_by) . ' ';
|
||||||
|
} else {
|
||||||
|
$content = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
return join(', ', $categories);
|
return $content . join(', ', $categories);
|
||||||
} else {
|
} else {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ class PostListTransformer {
|
|||||||
|
|
||||||
function transform($posts) {
|
function transform($posts) {
|
||||||
$results = array();
|
$results = array();
|
||||||
$use_divider = (bool)$this->args['showDivider'];
|
$use_divider = $this->args['showDivider'] === 'true';
|
||||||
|
|
||||||
foreach ($posts as $index => $post) {
|
foreach ($posts as $index => $post) {
|
||||||
if ($use_divider && $index > 0) {
|
if ($use_divider && $index > 0) {
|
||||||
|
@ -22,16 +22,26 @@ class PostTransformer {
|
|||||||
$content = $content_manager->filterContent($content);
|
$content = $content_manager->filterContent($content);
|
||||||
|
|
||||||
$structure_transformer = new StructureTransformer();
|
$structure_transformer = new StructureTransformer();
|
||||||
$structure = $structure_transformer->transform($content, (bool)$this->args['imagePadded']);
|
$structure = $structure_transformer->transform($content, $this->args['imagePadded'] === 'true');
|
||||||
|
|
||||||
$structure = $this->appendFeaturedImage($post, (bool)$this->args['imagePadded'], $structure);
|
$structure = $this->appendFeaturedImage(
|
||||||
|
$post,
|
||||||
|
$this->args['displayType'],
|
||||||
|
$this->args['imagePadded'] === 'true',
|
||||||
|
$structure
|
||||||
|
);
|
||||||
$structure = $this->appendPostTitle($post, $structure);
|
$structure = $this->appendPostTitle($post, $structure);
|
||||||
$structure = $this->appendReadMore($post->ID, $structure);
|
$structure = $this->appendReadMore($post->ID, $structure);
|
||||||
|
|
||||||
return $structure;
|
return $structure;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function appendFeaturedImage($post, $image_padded, $structure) {
|
private function appendFeaturedImage($post, $display_type, $image_padded, $structure) {
|
||||||
|
if ($display_type === 'full') {
|
||||||
|
// No featured images for full posts
|
||||||
|
return $structure;
|
||||||
|
}
|
||||||
|
|
||||||
$featured_image = $this->getFeaturedImage(
|
$featured_image = $this->getFeaturedImage(
|
||||||
$post->ID,
|
$post->ID,
|
||||||
$post->post_title,
|
$post->post_title,
|
||||||
@ -68,7 +78,7 @@ class PostTransformer {
|
|||||||
|
|
||||||
return array(
|
return array(
|
||||||
'type' => 'image',
|
'type' => 'image',
|
||||||
'link' => '',
|
'link' => get_permalink($post_id),
|
||||||
'src' => $image_info[0],
|
'src' => $image_info[0],
|
||||||
'alt' => $alt_text,
|
'alt' => $alt_text,
|
||||||
'padded' => $image_padded,
|
'padded' => $image_padded,
|
||||||
@ -84,6 +94,8 @@ class PostTransformer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private function appendPostTitle($post, $structure) {
|
private function appendPostTitle($post, $structure) {
|
||||||
|
$title = $this->getPostTitle($post);
|
||||||
|
|
||||||
if ($this->args['titlePosition'] === 'inTextBlock') {
|
if ($this->args['titlePosition'] === 'inTextBlock') {
|
||||||
// Attach title to the first text block
|
// Attach title to the first text block
|
||||||
$text_block_index = null;
|
$text_block_index = null;
|
||||||
@ -94,7 +106,6 @@ class PostTransformer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$title = $this->getPostTitle($post);
|
|
||||||
if ($text_block_index === null) {
|
if ($text_block_index === null) {
|
||||||
$structure[] = array(
|
$structure[] = array(
|
||||||
'type' => 'text',
|
'type' => 'text',
|
||||||
@ -103,6 +114,14 @@ class PostTransformer {
|
|||||||
} else {
|
} else {
|
||||||
$structure[$text_block_index]['text'] = $title . $structure[$text_block_index]['text'];
|
$structure[$text_block_index]['text'] = $title . $structure[$text_block_index]['text'];
|
||||||
}
|
}
|
||||||
|
} elseif ($this->args['titlePosition'] === 'aboveBlock') {
|
||||||
|
array_unshift(
|
||||||
|
$structure,
|
||||||
|
array(
|
||||||
|
'type' => 'text',
|
||||||
|
'text' => $title,
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $structure;
|
return $structure;
|
||||||
@ -113,6 +132,15 @@ class PostTransformer {
|
|||||||
$button = $this->args['readMoreButton'];
|
$button = $this->args['readMoreButton'];
|
||||||
$button['url'] = get_permalink($post_id);
|
$button['url'] = get_permalink($post_id);
|
||||||
$structure[] = $button;
|
$structure[] = $button;
|
||||||
|
} else {
|
||||||
|
$structure[] = array(
|
||||||
|
'type' => 'text',
|
||||||
|
'text' => sprintf(
|
||||||
|
'<a href="%s">%s</a>',
|
||||||
|
get_permalink($post_id),
|
||||||
|
$this->args['readMoreText']
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $structure;
|
return $structure;
|
||||||
@ -121,7 +149,7 @@ class PostTransformer {
|
|||||||
private function getPostTitle($post) {
|
private function getPostTitle($post) {
|
||||||
$title = $post->post_title;
|
$title = $post->post_title;
|
||||||
|
|
||||||
if ((bool)$this->args['titleIsLink']) {
|
if ($this->args['titleIsLink'] === 'true') {
|
||||||
$title = '<a href="' . get_permalink($post->ID) . '">' . $title . '</a>';
|
$title = '<a href="' . get_permalink($post->ID) . '">' . $title . '</a>';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,31 +101,51 @@ class Newsletters {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
function delete($data = array()) {
|
function restore($id) {
|
||||||
$newsletter = newsletter::findOne($data['id']);
|
$result = false;
|
||||||
$confirm_delete = filter_var($data['confirm'], FILTER_VALIDATE_BOOLEAN);
|
|
||||||
|
$newsletter = Newsletter::findOne($id);
|
||||||
if($newsletter !== false) {
|
if($newsletter !== false) {
|
||||||
if($confirm_delete) {
|
$result = $newsletter->restore();
|
||||||
$newsletter->delete();
|
|
||||||
$result = array('newsletters' => 1);
|
|
||||||
} else {
|
|
||||||
$newsletter->set_expr('deleted_at', 'NOW()');
|
|
||||||
$result = array('newsletters' => (int)$newsletter->save());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$result = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wp_send_json($result);
|
wp_send_json($result);
|
||||||
}
|
}
|
||||||
|
|
||||||
function restore($id) {
|
function trash($id) {
|
||||||
|
$result = false;
|
||||||
|
|
||||||
$newsletter = Newsletter::findOne($id);
|
$newsletter = Newsletter::findOne($id);
|
||||||
if($newsletter !== false) {
|
if($newsletter !== false) {
|
||||||
$newsletter->set_expr('deleted_at', 'NULL');
|
$result = $newsletter->trash();
|
||||||
$result = array('newsletters' => (int)$newsletter->save());
|
|
||||||
} else {
|
|
||||||
$result = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wp_send_json($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
function delete($id) {
|
||||||
|
$result = false;
|
||||||
|
|
||||||
|
$newsletter = Newsletter::findOne($id);
|
||||||
|
if($newsletter !== false) {
|
||||||
|
$newsletter->delete();
|
||||||
|
$result = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
wp_send_json($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
function duplicate($id) {
|
||||||
|
$result = false;
|
||||||
|
|
||||||
|
$newsletter = Newsletter::findOne($id);
|
||||||
|
if($newsletter !== false) {
|
||||||
|
$data = array(
|
||||||
|
'subject' => sprintf(__('Copy of %s'), $newsletter->subject)
|
||||||
|
);
|
||||||
|
$result = $newsletter->duplicate($data)->asArray();
|
||||||
|
}
|
||||||
|
|
||||||
wp_send_json($result);
|
wp_send_json($result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,7 +55,6 @@ class Segments {
|
|||||||
)
|
)
|
||||||
->findOne()->asArray();
|
->findOne()->asArray();
|
||||||
|
|
||||||
!d(\ORM::get_last_query());exit;
|
|
||||||
$item = array_merge($item, $stats);
|
$item = array_merge($item, $stats);
|
||||||
|
|
||||||
$item['subscribers_url'] = admin_url(
|
$item['subscribers_url'] = admin_url(
|
||||||
|
@ -132,4 +132,4 @@ class BootStrapMenu {
|
|||||||
}
|
}
|
||||||
return $data;
|
return $data;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -2,11 +2,14 @@
|
|||||||
namespace MailPoet\Subscribers\ImportExport\Export;
|
namespace MailPoet\Subscribers\ImportExport\Export;
|
||||||
|
|
||||||
use MailPoet\Config\Env;
|
use MailPoet\Config\Env;
|
||||||
use MailPoet\Subscribers\ImportExport\BootStrapMenu;
|
use MailPoet\Models\CustomField;
|
||||||
use MailPoet\Models\Segment;
|
use MailPoet\Models\Segment;
|
||||||
use MailPoet\Models\Subscriber;
|
use MailPoet\Models\Subscriber;
|
||||||
use MailPoet\Models\SubscriberSegment;
|
use MailPoet\Models\SubscriberSegment;
|
||||||
|
use MailPoet\Subscribers\ImportExport\BootStrapMenu;
|
||||||
|
use MailPoet\Util\Helpers;
|
||||||
use MailPoet\Util\XLSXWriter;
|
use MailPoet\Util\XLSXWriter;
|
||||||
|
use Symfony\Component\Console\Helper\Helper;
|
||||||
|
|
||||||
class Export {
|
class Export {
|
||||||
public function __construct($data) {
|
public function __construct($data) {
|
||||||
@ -16,82 +19,79 @@ class Export {
|
|||||||
$this->segments = $data['segments'];
|
$this->segments = $data['segments'];
|
||||||
$this->subscribersWithoutSegment = array_search(0, $this->segments);
|
$this->subscribersWithoutSegment = array_search(0, $this->segments);
|
||||||
$this->subscriberFields = $data['subscriberFields'];
|
$this->subscriberFields = $data['subscriberFields'];
|
||||||
|
$this->exportFile = $this->getExportFile($this->exportFormatOption);
|
||||||
|
$this->exportFileURL = $this->getExportFileURL($this->exportFile);
|
||||||
$this->profilerStart = microtime(true);
|
$this->profilerStart = microtime(true);
|
||||||
$this->exportFile = sprintf(
|
|
||||||
Env::$temp_path . '/mailpoet_export_%s.%s',
|
|
||||||
substr(md5(time()), 0, 4),
|
|
||||||
$this->exportFormatOption
|
|
||||||
);
|
|
||||||
$this->exportFileURL = sprintf(
|
|
||||||
'%s/%s/%s/%s',
|
|
||||||
plugins_url(),
|
|
||||||
Env::$plugin_name,
|
|
||||||
Env::$temp_name,
|
|
||||||
basename($this->exportFile)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function process() {
|
function process() {
|
||||||
$subscribers = SubscriberSegment::
|
$subscribers = $this->getSubscribers();
|
||||||
left_outer_join(
|
$subscriberCustomFields = $this->getSubscriberCustomFields();
|
||||||
Subscriber::$_table,
|
$formattedSubscriberFields = $this->formatSubscriberFields(
|
||||||
array(
|
$this->subscriberFields,
|
||||||
Subscriber::$_table . '.id',
|
$subscriberCustomFields
|
||||||
'=',
|
);
|
||||||
SubscriberSegment::$_table . '.subscriber_id'
|
|
||||||
))
|
|
||||||
->left_outer_join(
|
|
||||||
Segment::$_table,
|
|
||||||
array(
|
|
||||||
Segment::$_table . '.id',
|
|
||||||
'=',
|
|
||||||
SubscriberSegment::$_table . '.segment_id'
|
|
||||||
))
|
|
||||||
->select(Segment::$_table . '.name', 'segment_name')
|
|
||||||
->orderByAsc('segment_name')
|
|
||||||
->filter('filterWithCustomFields')
|
|
||||||
->whereIn(SubscriberSegment::$_table . '.segment_id', $this->segments);
|
|
||||||
if(!$this->groupBySegmentOption) $subscribers = $subscribers->groupBy(Subscriber::$_table . '.id');
|
|
||||||
if($this->exportConfirmedOption) $subscribers = $subscribers->where(Subscriber::$_table . '.status', 'confirmed');
|
|
||||||
$subscribers = $subscribers->findArray();
|
|
||||||
$formattedSubscriberFields = $this->formatSubscriberFields($this->subscriberFields);
|
|
||||||
try {
|
try {
|
||||||
if($this->exportFormatOption === 'csv') {
|
if($this->exportFormatOption === 'csv') {
|
||||||
$CSVFile = fopen($this->exportFile, 'w');
|
$CSVFile = fopen($this->exportFile, 'w');
|
||||||
$formatCSV = function ($row) {
|
$formatCSV = function ($row) {
|
||||||
return '"' . str_replace('"', '\"', $row) . '"';
|
return '"' . str_replace('"', '\"', $row) . '"';
|
||||||
};
|
};
|
||||||
// add UTF-8 BOM (3 bytes, hex EF BB BF) at the start of the file for Excel to automatically recognize the encoding
|
// add UTF-8 BOM (3 bytes, hex EF BB BF) at the start of the file for
|
||||||
|
// Excel to automatically recognize the encoding
|
||||||
fwrite($CSVFile, chr(0xEF) . chr(0xBB) . chr(0xBF));
|
fwrite($CSVFile, chr(0xEF) . chr(0xBB) . chr(0xBF));
|
||||||
if($this->groupBySegmentOption) $formattedSubscriberFields[] = __('List');
|
if($this->groupBySegmentOption) {
|
||||||
fwrite($CSVFile, implode(",", array_map($formatCSV, $formattedSubscriberFields)) . "\n");
|
$formattedSubscriberFields[] = __('List');
|
||||||
|
}
|
||||||
|
fwrite(
|
||||||
|
$CSVFile,
|
||||||
|
implode(
|
||||||
|
',',
|
||||||
|
array_map(
|
||||||
|
$formatCSV,
|
||||||
|
$formattedSubscriberFields
|
||||||
|
)
|
||||||
|
) . "\n"
|
||||||
|
);
|
||||||
foreach ($subscribers as $subscriber) {
|
foreach ($subscribers as $subscriber) {
|
||||||
$row = array_map(function ($field) use ($subscriber) {
|
$row = $this->formatSubscriberData(
|
||||||
return $subscriber[$field];
|
$subscriber,
|
||||||
}, $this->subscriberFields);
|
$formattedSubscriberFields
|
||||||
if($this->groupBySegmentOption) $row[] = $subscriber['segment_name'];
|
);
|
||||||
fwrite($CSVFile, implode(",", array_map($formatCSV, $row)) . "\n");
|
if($this->groupBySegmentOption) {
|
||||||
|
$row[] = ucwords($subscriber['segment_name']);
|
||||||
|
}
|
||||||
|
fwrite($CSVFile, implode(',', array_map($formatCSV, $row)) . "\n");
|
||||||
}
|
}
|
||||||
fclose($CSVFile);
|
fclose($CSVFile);
|
||||||
} else {
|
} else {
|
||||||
$writer = new XLSXWriter();
|
$writer = new XLSXWriter();
|
||||||
$writer->setAuthor('MailPoet (www.mailpoet.com)');
|
$writer->setAuthor('MailPoet (www.mailpoet.com)');
|
||||||
$headerRow = array($formattedSubscriberFields);
|
$headerRow = array($formattedSubscriberFields);
|
||||||
$segment = null;
|
$lastSegment = false;
|
||||||
$rows = array();
|
$rows = array();
|
||||||
foreach ($subscribers as $subscriber) {
|
foreach ($subscribers as $subscriber) {
|
||||||
if($segment && $segment != $subscriber['segment_name'] && $this->groupBySegmentOption) {
|
if($lastSegment && $lastSegment !== $subscriber['segment_name'] &&
|
||||||
$writer->writeSheet(array_merge($headerRow, $rows), ucwords($segment));
|
$this->groupBySegmentOption
|
||||||
|
) {
|
||||||
|
$writer->writeSheet(
|
||||||
|
array_merge($headerRow, $rows), ucwords($lastSegment)
|
||||||
|
);
|
||||||
$rows = array();
|
$rows = array();
|
||||||
}
|
}
|
||||||
// detect RTL language and set Excel to properly display the sheet
|
// detect RTL language and set Excel to properly display the sheet
|
||||||
if(!$writer->rtl && preg_grep('/\p{Arabic}|\p{Hebrew}/u', $subscriber)) {
|
$RTLRegex = '/\p{Arabic}|\p{Hebrew}/u';
|
||||||
|
if(!$writer->rtl && (
|
||||||
|
preg_grep($RTLRegex, $subscriber) ||
|
||||||
|
preg_grep($RTLRegex, $formattedSubscriberFields))
|
||||||
|
) {
|
||||||
$writer->rtl = true;
|
$writer->rtl = true;
|
||||||
}
|
}
|
||||||
$rows[] = array_map(function ($field) use ($subscriber) {
|
$rows[] = $this->formatSubscriberData(
|
||||||
return $subscriber[$field];
|
$subscriber,
|
||||||
}, $this->subscriberFields);
|
$formattedSubscriberFields
|
||||||
$segment = $subscriber['segment_name'];
|
);
|
||||||
|
$lastSegment = $subscriber['segment_name'];
|
||||||
}
|
}
|
||||||
$writer->writeSheet(array_merge($headerRow, $rows), 'MailPoet');
|
$writer->writeSheet(array_merge($headerRow, $rows), 'MailPoet');
|
||||||
$writer->writeToFile($this->exportFile);
|
$writer->writeToFile($this->exportFile);
|
||||||
@ -107,20 +107,106 @@ class Export {
|
|||||||
'data' => array(
|
'data' => array(
|
||||||
'totalExported' => count($subscribers),
|
'totalExported' => count($subscribers),
|
||||||
'exportFileURL' => $this->exportFileURL
|
'exportFileURL' => $this->exportFileURL
|
||||||
)
|
),
|
||||||
|
'profiler' => $this->timeExecution()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatSubscriberFields($subscriberFields) {
|
function getSubscribers() {
|
||||||
|
$subscribers = Subscriber::
|
||||||
|
left_outer_join(
|
||||||
|
SubscriberSegment::$_table,
|
||||||
|
array(
|
||||||
|
Subscriber::$_table . '.id',
|
||||||
|
'=',
|
||||||
|
SubscriberSegment::$_table . '.subscriber_id'
|
||||||
|
))
|
||||||
|
->left_outer_join(
|
||||||
|
Segment::$_table,
|
||||||
|
array(
|
||||||
|
Segment::$_table . '.id',
|
||||||
|
'=',
|
||||||
|
SubscriberSegment::$_table . '.segment_id'
|
||||||
|
))
|
||||||
|
->orderByAsc('segment_name')
|
||||||
|
->filter('filterWithCustomFieldsForExport');
|
||||||
|
if($this->subscribersWithoutSegment !== false) {
|
||||||
|
$subscribers = $subscribers
|
||||||
|
->selectExpr('CASE WHEN ' . Segment::$_table . '.name IS NOT NULL ' .
|
||||||
|
'THEN ' . Segment::$_table . '.name ' .
|
||||||
|
'ELSE "' . __('Not In List') . '" END as segment_name'
|
||||||
|
)
|
||||||
|
->whereRaw(
|
||||||
|
SubscriberSegment::$_table . '.segment_id IN (' .
|
||||||
|
rtrim(str_repeat('?,', count($this->segments)), ',') . ') ' .
|
||||||
|
'OR ' . SubscriberSegment::$_table . '.segment_id IS NULL ',
|
||||||
|
$this->segments
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
$subscribers = $subscribers
|
||||||
|
->select(Segment::$_table . '.name', 'segment_name')
|
||||||
|
->whereIn(SubscriberSegment::$_table . '.segment_id', $this->segments);
|
||||||
|
}
|
||||||
|
if(!$this->groupBySegmentOption) {
|
||||||
|
$subscribers =
|
||||||
|
$subscribers->groupBy(Subscriber::$_table . '.id');
|
||||||
|
}
|
||||||
|
if($this->exportConfirmedOption) {
|
||||||
|
$subscribers =
|
||||||
|
$subscribers->where(Subscriber::$_table . '.status', 'subscribed');
|
||||||
|
}
|
||||||
|
return $subscribers->findArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
function getExportFileURL($file) {
|
||||||
|
return sprintf(
|
||||||
|
'%s/%s/%s',
|
||||||
|
Env::$plugin_url,
|
||||||
|
Env::$temp_name,
|
||||||
|
basename($file)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getExportFile($format) {
|
||||||
|
return sprintf(
|
||||||
|
Env::$temp_path . '/MailPoet_export_%s.%s',
|
||||||
|
substr(md5(time()), 0, 4),
|
||||||
|
$format
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSubscriberCustomFields() {
|
||||||
|
return Helpers::arrayColumn(
|
||||||
|
CustomField::findArray(),
|
||||||
|
'name',
|
||||||
|
'id'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatSubscriberFields($subscriberFields, $subscriberCustomFields) {
|
||||||
$bootStrapMenu = new BootStrapMenu();
|
$bootStrapMenu = new BootStrapMenu();
|
||||||
$translatedFields = $bootStrapMenu->getSubscriberFields();
|
$translatedFields = $bootStrapMenu->getSubscriberFields();
|
||||||
return array_map(function ($field) use ($translatedFields) {
|
return array_map(function ($field) use (
|
||||||
return (isset($translatedFields[$field])) ?
|
$translatedFields, $subscriberCustomFields
|
||||||
|
) {
|
||||||
|
$field = (isset($translatedFields[$field])) ?
|
||||||
ucfirst($translatedFields[$field]) :
|
ucfirst($translatedFields[$field]) :
|
||||||
ucfirst($field);
|
ucfirst($field);
|
||||||
|
return (isset($subscriberCustomFields[$field])) ?
|
||||||
|
$subscriberCustomFields[$field] : $field;
|
||||||
}, $subscriberFields);
|
}, $subscriberFields);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function formatSubscriberData($subscriber, $subscriberCustomFields) {
|
||||||
|
return array_map(function ($field) use (
|
||||||
|
$subscriber, $subscriberCustomFields
|
||||||
|
) {
|
||||||
|
return (isset($subscriberCustomFields[$field])) ?
|
||||||
|
$subscriberCustomFields[$field] :
|
||||||
|
$subscriber[$field];
|
||||||
|
}, $this->subscriberFields);
|
||||||
|
}
|
||||||
|
|
||||||
function timeExecution() {
|
function timeExecution() {
|
||||||
$profilerEnd = microtime(true);
|
$profilerEnd = microtime(true);
|
||||||
return ($profilerEnd - $this->profilerStart) / 60;
|
return ($profilerEnd - $this->profilerStart) / 60;
|
||||||
|
@ -75,7 +75,7 @@ class Import {
|
|||||||
'updated' => count($updatedSubscribers),
|
'updated' => count($updatedSubscribers),
|
||||||
'segments' => $segments->getSegments()
|
'segments' => $segments->getSegments()
|
||||||
),
|
),
|
||||||
'profile' => $this->timeExecution()
|
'profiler' => $this->timeExecution()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,7 +165,7 @@ class Import {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function filterSubscriberStatus($subscribersData) {
|
function filterSubscriberStatus($subscribersData) {
|
||||||
if(!in_array('status', $this->subscriberFields)) return;
|
if(!in_array('status', $this->subscriberFields)) return $subscribersData;
|
||||||
$statuses = array(
|
$statuses = array(
|
||||||
'subscribed' => array(
|
'subscribed' => array(
|
||||||
'subscribed',
|
'subscribed',
|
||||||
@ -174,6 +174,11 @@ class Import {
|
|||||||
'1',
|
'1',
|
||||||
'true'
|
'true'
|
||||||
),
|
),
|
||||||
|
'unconfirmed' => array(
|
||||||
|
'unconfirmed',
|
||||||
|
0,
|
||||||
|
"0"
|
||||||
|
),
|
||||||
'unsubscribed' => array(
|
'unsubscribed' => array(
|
||||||
'unsubscribed',
|
'unsubscribed',
|
||||||
-1,
|
-1,
|
||||||
@ -183,12 +188,15 @@ class Import {
|
|||||||
);
|
);
|
||||||
$subscribersData['status'] = array_map(function ($state) use ($statuses) {
|
$subscribersData['status'] = array_map(function ($state) use ($statuses) {
|
||||||
if(in_array(strtolower($state), $statuses['subscribed'])) {
|
if(in_array(strtolower($state), $statuses['subscribed'])) {
|
||||||
return 'confirmed';
|
return 'subscribed';
|
||||||
}
|
}
|
||||||
if(in_array(strtolower($state), $statuses['unsubscribed'])) {
|
if(in_array(strtolower($state), $statuses['unsubscribed'])) {
|
||||||
return 'unsubscribed';
|
return 'unsubscribed';
|
||||||
}
|
}
|
||||||
return 'confirmed'; // make "subscribed" a default status
|
if(in_array(strtolower($state), $statuses['unconfirmed'])) {
|
||||||
|
return 'unconfirmed';
|
||||||
|
}
|
||||||
|
return 'subscribed'; // make "subscribed" a default status
|
||||||
}, $subscribersData['status']);
|
}, $subscribersData['status']);
|
||||||
return $subscribersData;
|
return $subscribersData;
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ if (!defined('ABSPATH')) exit;
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Plugin Name: MailPoet
|
* Plugin Name: MailPoet
|
||||||
* Version: 0.0.4
|
* Version: 0.0.5
|
||||||
* Plugin URI: http://www.mailpoet.com
|
* Plugin URI: http://www.mailpoet.com
|
||||||
* Description: MailPoet Newsletters.
|
* Description: MailPoet Newsletters.
|
||||||
* Author: MailPoet
|
* Author: MailPoet
|
||||||
@ -18,12 +18,12 @@ if (!defined('ABSPATH')) exit;
|
|||||||
*
|
*
|
||||||
* @package WordPress
|
* @package WordPress
|
||||||
* @author MailPoet
|
* @author MailPoet
|
||||||
* @since 0.0.4
|
* @since 0.0.5
|
||||||
*/
|
*/
|
||||||
|
|
||||||
require 'vendor/autoload.php';
|
require 'vendor/autoload.php';
|
||||||
|
|
||||||
define('MAILPOET_VERSION', '0.0.4');
|
define('MAILPOET_VERSION', '0.0.5');
|
||||||
|
|
||||||
$initializer = new Initializer(array(
|
$initializer = new Initializer(array(
|
||||||
'file' => __FILE__,
|
'file' => __FILE__,
|
||||||
|
@ -5,8 +5,7 @@
|
|||||||
},
|
},
|
||||||
"napa": {
|
"napa": {
|
||||||
"blob": "eligrey/Blob.js.git",
|
"blob": "eligrey/Blob.js.git",
|
||||||
"filesaver": "eligrey/FileSaver.js.git",
|
"filesaver": "eligrey/FileSaver.js.git"
|
||||||
"sticky-kit": "leafo/sticky-kit.git"
|
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"backbone": "1.2.3",
|
"backbone": "1.2.3",
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
define([
|
define([
|
||||||
'newsletter_editor/App',
|
'newsletter_editor/App',
|
||||||
'newsletter_editor/components/wordpress',
|
'newsletter_editor/components/wordpress',
|
||||||
'newsletter_editor/blocks/posts',
|
'newsletter_editor/blocks/posts'
|
||||||
], function(EditorApplication, WordpressComponent, PostsBlock) {
|
], function(EditorApplication, WordpressComponent, PostsBlock) {
|
||||||
|
|
||||||
describe('Posts', function () {
|
describe('Posts', function () {
|
||||||
@ -373,12 +373,7 @@ define([
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('when "title as list" is selected', function() {
|
describe('when "title as list" is selected', function() {
|
||||||
var model, view;
|
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
model = new (PostsBlock.PostsBlockModel)();
|
|
||||||
model.request = sinon.stub().returns({$el: {}});
|
|
||||||
view = new (PostsBlock.PostsBlockSettingsView)({model: model});
|
|
||||||
view.render();
|
|
||||||
view.$('.mailpoet_posts_display_type').val('titleOnly').change();
|
view.$('.mailpoet_posts_display_type').val('titleOnly').change();
|
||||||
view.$('.mailpoet_posts_title_format').val('ul').change();
|
view.$('.mailpoet_posts_title_format').val('ul').change();
|
||||||
});
|
});
|
||||||
|
@ -1,23 +1,237 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use MailPoet\Subscribers\ImportExport\Export;
|
use MailPoet\Config\Env;
|
||||||
|
use MailPoet\Models\CustomField;
|
||||||
|
use MailPoet\Models\Segment;
|
||||||
|
use MailPoet\Models\Subscriber;
|
||||||
|
use MailPoet\Models\SubscriberCustomField;
|
||||||
|
use MailPoet\Models\SubscriberSegment;
|
||||||
|
use MailPoet\Subscribers\ImportExport\Export\Export;
|
||||||
|
|
||||||
class ExportCest {
|
class ExportCest {
|
||||||
function __construct() {
|
function _before() {
|
||||||
|
$this->JSONdata = json_decode(file_get_contents(dirname(__FILE__) . '/ExportTestData.json'), true);
|
||||||
|
$this->subscriberFields = array(
|
||||||
|
'first_name' => 'First name',
|
||||||
|
'last_name' => 'Last name',
|
||||||
|
'email' => 'Email',
|
||||||
|
1 => 'Country'
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->subscribersData = array(
|
||||||
|
array(
|
||||||
|
'first_name' => 'Adam',
|
||||||
|
'last_name' => 'Smith',
|
||||||
|
'email' => 'adam@smith.com'
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'first_name' => 'Mary',
|
||||||
|
'last_name' => 'Jane',
|
||||||
|
'email' => 'mary@jane.com',
|
||||||
|
'status' => 'subscribed',
|
||||||
|
1 => 'Brazil'
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'first_name' => 'John',
|
||||||
|
'last_name' => 'Kookoo',
|
||||||
|
'email' => 'john@kookoo.com'
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'first_name' => 'Paul',
|
||||||
|
'last_name' => 'Newman',
|
||||||
|
'email' => 'paul@newman.com'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$this->customFieldsData = array(
|
||||||
|
array(
|
||||||
|
'name' => 'Country',
|
||||||
|
'type' => 'text'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$this->segmentsData = array(
|
||||||
|
array(
|
||||||
|
'name' => 'Newspapers'
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'name' => 'Journals'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
foreach ($this->subscribersData as $subscriber) {
|
||||||
|
if(isset($subscriber[1])) {
|
||||||
|
unset($subscriber[1]);
|
||||||
|
}
|
||||||
|
$entity = Subscriber::create();
|
||||||
|
$entity->hydrate($subscriber);
|
||||||
|
$entity->save();
|
||||||
|
}
|
||||||
|
foreach ($this->segmentsData as $customField) {
|
||||||
|
$entity = Segment::create();
|
||||||
|
$entity->hydrate($customField);
|
||||||
|
$entity->save();
|
||||||
|
}
|
||||||
|
foreach ($this->customFieldsData as $customField) {
|
||||||
|
$entity = CustomField::create();
|
||||||
|
$entity->hydrate($customField);
|
||||||
|
$entity->save();
|
||||||
|
}
|
||||||
|
$entity = SubscriberCustomField::create();
|
||||||
|
$entity->subscriber_id = 2;
|
||||||
|
$entity->custom_field_id = 1;
|
||||||
|
$entity->value = $this->subscribersData[1][1];
|
||||||
|
$entity->save();
|
||||||
|
$entity = SubscriberSegment::create();
|
||||||
|
$entity->subscriber_id = 1;
|
||||||
|
$entity->segment_id = 1;
|
||||||
|
$entity->save();
|
||||||
|
$entity = SubscriberSegment::create();
|
||||||
|
$entity->subscriber_id = 1;
|
||||||
|
$entity->segment_id = 2;
|
||||||
|
$entity->save();
|
||||||
|
$entity = SubscriberSegment::create();
|
||||||
|
$entity->subscriber_id = 2;
|
||||||
|
$entity->segment_id = 1;
|
||||||
|
$entity->save();
|
||||||
|
$entity = SubscriberSegment::create();
|
||||||
|
$entity->subscriber_id = 3;
|
||||||
|
$entity->segment_id = 2;
|
||||||
|
$entity->save();
|
||||||
|
$this->export = new Export($this->JSONdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
function itCanConstruct() {
|
function itCanConstruct() {
|
||||||
|
expect($this->export->exportConfirmedOption)
|
||||||
|
->equals(false);
|
||||||
|
expect($this->export->exportFormatOption)
|
||||||
|
->equals('csv');
|
||||||
|
expect($this->export->groupBySegmentOption)
|
||||||
|
->equals(false);
|
||||||
|
expect($this->export->segments)
|
||||||
|
->equals(
|
||||||
|
array(
|
||||||
|
1,
|
||||||
|
2
|
||||||
|
)
|
||||||
|
);
|
||||||
|
expect($this->export->subscribersWithoutSegment)
|
||||||
|
->equals(0);
|
||||||
|
expect($this->export->subscriberFields)
|
||||||
|
->equals(
|
||||||
|
array(
|
||||||
|
'email',
|
||||||
|
'first_name',
|
||||||
|
'1'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
preg_match(
|
||||||
|
'|' .
|
||||||
|
Env::$temp_path . '/MailPoet_export_[a-f0-9]{4}.' .
|
||||||
|
$this->export->exportFormatOption .
|
||||||
|
'|', $this->export->exportFile)
|
||||||
|
)->equals(1);
|
||||||
|
expect(
|
||||||
|
preg_match(
|
||||||
|
'|' .
|
||||||
|
Env::$plugin_url . '/' .
|
||||||
|
Env::$temp_name . '/' .
|
||||||
|
basename($this->export->exportFile) .
|
||||||
|
'|'
|
||||||
|
, $this->export->exportFileURL)
|
||||||
|
)->equals(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
function itCanGetSubscriberCustomFields() {
|
||||||
|
$source = CustomField::where('name', $this->customFieldsData[0]['name'])
|
||||||
|
->findOne();
|
||||||
|
$target = $this->export->getSubscriberCustomFields();
|
||||||
|
expect($target)->equals(array($source->id => $source->name));
|
||||||
|
}
|
||||||
|
|
||||||
|
function itCanFormatSubscriberFields() {
|
||||||
|
$formattedSubscriberFields = $this->export->formatSubscriberFields(
|
||||||
|
array_keys($this->subscriberFields),
|
||||||
|
$this->export->getSubscriberCustomFields()
|
||||||
|
);
|
||||||
|
expect($formattedSubscriberFields)
|
||||||
|
->equals(array_values($this->subscriberFields));
|
||||||
|
}
|
||||||
|
|
||||||
|
function itProperlyReturnsSubscriberCustomFields() {
|
||||||
|
$subscribers = $this->export->getSubscribers();
|
||||||
|
foreach ($subscribers as $subscriber) {
|
||||||
|
if($subscriber['email'] === $this->subscribersData[1]) {
|
||||||
|
expect($subscriber['Country'])
|
||||||
|
->equals($this->subscribersData[1][1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function itCanGetSubscribers() {
|
||||||
|
$this->export->segments = array(1);
|
||||||
|
$subscribers = $this->export->getSubscribers();
|
||||||
|
expect(count($subscribers))->equals(2);
|
||||||
|
$this->export->segments = array(2);
|
||||||
|
$subscribers = $this->export->getSubscribers();
|
||||||
|
expect(count($subscribers))->equals(2);
|
||||||
|
$this->export->segments = array(
|
||||||
|
1,
|
||||||
|
2
|
||||||
|
);
|
||||||
|
$subscribers = $this->export->getSubscribers();
|
||||||
|
expect(count($subscribers))->equals(3);
|
||||||
|
}
|
||||||
|
|
||||||
|
function itCanGroupSubscribersBySegments() {
|
||||||
|
$this->export->groupBySegmentOption = true;
|
||||||
|
$this->export->subscribersWithoutSegment = true;
|
||||||
|
$subscribers = $this->export->getSubscribers();
|
||||||
|
expect(count($subscribers))->equals(5);
|
||||||
|
}
|
||||||
|
|
||||||
|
function itCanGetSubscribersOnlyWithoutSegments() {
|
||||||
|
$this->export->segments = array(0);
|
||||||
|
$this->export->subscribersWithoutSegment = true;
|
||||||
|
$subscribers = $this->export->getSubscribers();
|
||||||
|
expect(count($subscribers))->equals(1);
|
||||||
|
expect($subscribers[0]['segment_name'])->equals('Not In List');
|
||||||
|
}
|
||||||
|
|
||||||
|
function itCanGetOnlyConfirmedSubscribers() {
|
||||||
|
$this->export->exportConfirmedOption = true;
|
||||||
|
$subscribers = $this->export->getSubscribers();
|
||||||
|
expect(count($subscribers))->equals(1);
|
||||||
|
expect($subscribers[0]['email'])
|
||||||
|
->equals($this->subscribersData[1]['email']);
|
||||||
|
}
|
||||||
|
|
||||||
|
function itCanGetSubscribersOnlyInSegments() {
|
||||||
|
SubscriberSegment::where('subscriber_id', 3)
|
||||||
|
->findOne()
|
||||||
|
->delete();
|
||||||
|
$subscribers = $this->export->getSubscribers();
|
||||||
|
expect(count($subscribers))->equals(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
function itCanProcess() {
|
function itCanProcess() {
|
||||||
|
$this->export->exportFile = $this->export->getExportFile('csv');
|
||||||
|
$this->export->exportFormatOption = 'csv';
|
||||||
|
$this->export->process();
|
||||||
|
$CSVFileSize = filesize($this->export->exportFile);
|
||||||
|
$this->export->exportFile = $this->export->getExportFile('xls');
|
||||||
|
$this->export->exportFormatOption = 'xls';
|
||||||
|
$this->export->process();
|
||||||
|
$XLSFileSize = filesize($this->export->exportFile);
|
||||||
|
expect($CSVFileSize)->greaterThan(0);
|
||||||
|
expect($XLSFileSize)->greaterThan(0);
|
||||||
|
expect($XLSFileSize)->greaterThan($CSVFileSize);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function _after() {
|
function _after() {
|
||||||
ORM::forTable(Subscriber::$_table)
|
ORM::raw_execute('TRUNCATE ' . Subscriber::$_table);
|
||||||
->deleteMany();
|
ORM::raw_execute('TRUNCATE ' . Segment::$_table);
|
||||||
ORM::forTable(SubscriberCustomField::$_table)
|
ORM::raw_execute('TRUNCATE ' . SubscriberSegment::$_table);
|
||||||
->deleteMany();
|
ORM::raw_execute('TRUNCATE ' . CustomField::$_table);
|
||||||
ORM::forTable(SubscriberSegment::$_table)
|
ORM::raw_execute('TRUNCATE ' . SubscriberCustomField::$_table);
|
||||||
->deleteMany();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"exportConfirmedOption": false,
|
||||||
|
"exportFormatOption": "csv",
|
||||||
|
"groupBySegmentOption": false,
|
||||||
|
"segments": [
|
||||||
|
"1",
|
||||||
|
"2"
|
||||||
|
],
|
||||||
|
"subscriberFields": [
|
||||||
|
"email",
|
||||||
|
"first_name",
|
||||||
|
"1"
|
||||||
|
]
|
||||||
|
}
|
@ -1,9 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use MailPoet\Subscribers\ImportExport\Import\Import;
|
|
||||||
use MailPoet\Models\Subscriber;
|
use MailPoet\Models\Subscriber;
|
||||||
use MailPoet\Models\SubscriberCustomField;
|
use MailPoet\Models\SubscriberCustomField;
|
||||||
use MailPoet\Models\SubscriberSegment;
|
use MailPoet\Models\SubscriberSegment;
|
||||||
|
use MailPoet\Subscribers\ImportExport\Import\Import;
|
||||||
use MailPoet\Util\Helpers;
|
use MailPoet\Util\Helpers;
|
||||||
|
|
||||||
class ImportCest {
|
class ImportCest {
|
||||||
@ -108,38 +108,39 @@ class ImportCest {
|
|||||||
function itCanFilterSubscriberState() {
|
function itCanFilterSubscriberState() {
|
||||||
$data = array(
|
$data = array(
|
||||||
'status' => array(
|
'status' => array(
|
||||||
'confirmed',
|
//subscribed
|
||||||
'subscribed',
|
|
||||||
'subscribed',
|
'subscribed',
|
||||||
'confirmed',
|
'confirmed',
|
||||||
1,
|
1,
|
||||||
'1',
|
'1',
|
||||||
'true',
|
'true',
|
||||||
|
//unconfirmed
|
||||||
|
'unconfirmed',
|
||||||
|
0,
|
||||||
|
"0",
|
||||||
|
//unsubscribed
|
||||||
'unsubscribed',
|
'unsubscribed',
|
||||||
-1,
|
-1,
|
||||||
'-1',
|
'-1',
|
||||||
'false',
|
'false'
|
||||||
'something',
|
|
||||||
'else'
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
$statuses = $this->import->filterSubscriberStatus($data);
|
$statuses = $this->import->filterSubscriberStatus($data);
|
||||||
expect($statuses)->equals(
|
expect($statuses)->equals(
|
||||||
array(
|
array(
|
||||||
'status' => array(
|
'status' => array(
|
||||||
'confirmed',
|
'subscribed',
|
||||||
'confirmed',
|
'subscribed',
|
||||||
'confirmed',
|
'subscribed',
|
||||||
'confirmed',
|
'subscribed',
|
||||||
'confirmed',
|
'subscribed',
|
||||||
'confirmed',
|
'unconfirmed',
|
||||||
'confirmed',
|
'unconfirmed',
|
||||||
|
'unconfirmed',
|
||||||
'unsubscribed',
|
'unsubscribed',
|
||||||
'unsubscribed',
|
'unsubscribed',
|
||||||
'unsubscribed',
|
'unsubscribed',
|
||||||
'unsubscribed',
|
'unsubscribed'
|
||||||
'confirmed',
|
|
||||||
'confirmed'
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
|||||||
<div class="mailpoet_tools"></div>
|
<div class="mailpoet_tools"></div>
|
||||||
<div class="mailpoet_content">
|
<div class="mailpoet_content">
|
||||||
<div class="mailpoet_automated_latest_content_block_overlay"></div>
|
<div class="mailpoet_automated_latest_content_block_overlay"></div>
|
||||||
<div class="mailpoet_automated_latest_content_block_posts"></div>
|
<div class="mailpoet_automated_latest_content_block_posts"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="mailpoet_block_highlight"></div>
|
<div class="mailpoet_block_highlight"></div>
|
||||||
|
@ -37,26 +37,6 @@
|
|||||||
|
|
||||||
<hr class="mailpoet_separator" />
|
<hr class="mailpoet_separator" />
|
||||||
|
|
||||||
<div class="mailpoet_form_field">
|
|
||||||
<div class="mailpoet_form_field_radio_option">
|
|
||||||
<label>
|
|
||||||
<input type="radio" name="mailpoet_automated_latest_content_display_type" class="mailpoet_automated_latest_content_display_type" value="excerpt" {{#ifCond model.displayType '==' 'excerpt'}}CHECKED{{/ifCond}}/>
|
|
||||||
<%= __('Excerpt') %>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="mailpoet_form_field_radio_option">
|
|
||||||
<label>
|
|
||||||
<input type="radio" name="mailpoet_automated_latest_content_display_type" class="mailpoet_automated_latest_content_display_type" value="full" {{#ifCond model.displayType '==' 'full'}}CHECKED{{/ifCond}}/>
|
|
||||||
<%= __('Full post') %>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="mailpoet_form_field_radio_option">
|
|
||||||
<label>
|
|
||||||
<input type="radio" name="mailpoet_automated_latest_content_display_type" class="mailpoet_automated_latest_content_display_type" value="titleOnly" {{#ifCond model.displayType '==' 'titleOnly'}}CHECKED{{/ifCond}} />
|
|
||||||
<%= __('Title only') %>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mailpoet_form_field">
|
<div class="mailpoet_form_field">
|
||||||
<a href="javascript:;" class="mailpoet_automated_latest_content_show_display_options"><%= __('Display options') %></a>
|
<a href="javascript:;" class="mailpoet_automated_latest_content_show_display_options"><%= __('Display options') %></a>
|
||||||
@ -66,6 +46,27 @@
|
|||||||
<a href="javascript:;" class="mailpoet_automated_latest_content_hide_display_options"><%= __('Hide display options') %></a>
|
<a href="javascript:;" class="mailpoet_automated_latest_content_hide_display_options"><%= __('Hide display options') %></a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="mailpoet_form_field">
|
||||||
|
<div class="mailpoet_form_field_radio_option">
|
||||||
|
<label>
|
||||||
|
<input type="radio" name="mailpoet_automated_latest_content_display_type" class="mailpoet_automated_latest_content_display_type" value="excerpt" {{#ifCond model.displayType '==' 'excerpt'}}CHECKED{{/ifCond}}/>
|
||||||
|
<%= __('Excerpt') %>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="mailpoet_form_field_radio_option">
|
||||||
|
<label>
|
||||||
|
<input type="radio" name="mailpoet_automated_latest_content_display_type" class="mailpoet_automated_latest_content_display_type" value="full" {{#ifCond model.displayType '==' 'full'}}CHECKED{{/ifCond}}/>
|
||||||
|
<%= __('Full post') %>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="mailpoet_form_field_radio_option">
|
||||||
|
<label>
|
||||||
|
<input type="radio" name="mailpoet_automated_latest_content_display_type" class="mailpoet_automated_latest_content_display_type" value="titleOnly" {{#ifCond model.displayType '==' 'titleOnly'}}CHECKED{{/ifCond}} />
|
||||||
|
<%= __('Title only') %>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="mailpoet_form_field">
|
<div class="mailpoet_form_field">
|
||||||
<div class="mailpoet_form_field_title"><%= __('Title Format') %></div>
|
<div class="mailpoet_form_field_title"><%= __('Title Format') %></div>
|
||||||
<div class="mailpoet_form_field_radio_option">
|
<div class="mailpoet_form_field_radio_option">
|
||||||
@ -215,7 +216,7 @@
|
|||||||
<%= __('Below text') %>
|
<%= __('Below text') %>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="mailpoet_form_field_title mailpoet_form_field_title_small mailpoet_form_field_title_inline"><%= __('Categories:') %></div>
|
<div class="mailpoet_form_field_title mailpoet_form_field_title_small mailpoet_form_field_title_inline"><%= __('Preceded by:') %></div>
|
||||||
<div class="mailpoet_form_field_input_option">
|
<div class="mailpoet_form_field_input_option">
|
||||||
<input type="text" class="mailpoet_input mailpoet_input_medium mailpoet_automated_latest_content_categories" value="{{ model.categoriesPrecededBy }}" />
|
<input type="text" class="mailpoet_input mailpoet_input_medium mailpoet_automated_latest_content_categories" value="{{ model.categoriesPrecededBy }}" />
|
||||||
</div>
|
</div>
|
||||||
@ -251,7 +252,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mailpoet_form_field">
|
<div class="mailpoet_form_field">
|
||||||
<div class="mailpoet_form_field_title mailpoet_form_field_title_small mailpoet_form_field_title_inline"><%= __('Sort by') %></div>
|
<div class="mailpoet_form_field_title mailpoet_form_field_title_small"><%= __('Sort by') %></div>
|
||||||
<div class="mailpoet_form_field_radio_option">
|
<div class="mailpoet_form_field_radio_option">
|
||||||
<label>
|
<label>
|
||||||
<input type="radio" name="mailpoet_automated_latest_content_sort_by" class="mailpoet_automated_latest_content_sort_by" value="newest" {{#ifCond model.sortBy '==' 'newest'}}CHECKED{{/ifCond}}/>
|
<input type="radio" name="mailpoet_automated_latest_content_sort_by" class="mailpoet_automated_latest_content_sort_by" value="newest" {{#ifCond model.sortBy '==' 'newest'}}CHECKED{{/ifCond}}/>
|
||||||
@ -268,7 +269,7 @@
|
|||||||
|
|
||||||
<div class="mailpoet_automated_latest_content_non_title_list_options {{#ifCond model.displayType '==' 'titleOnly'}}{{#ifCond model.titleFormat '==' 'ul'}}mailpoet_hidden{{/ifCond}}{{/ifCond}}">
|
<div class="mailpoet_automated_latest_content_non_title_list_options {{#ifCond model.displayType '==' 'titleOnly'}}{{#ifCond model.titleFormat '==' 'ul'}}mailpoet_hidden{{/ifCond}}{{/ifCond}}">
|
||||||
<div class="mailpoet_form_field">
|
<div class="mailpoet_form_field">
|
||||||
<div class="mailpoet_form_field_title mailpoet_form_field_title_small mailpoet_form_field_title_inline"><%= __('Show divider between posts') %></div>
|
<div class="mailpoet_form_field_title mailpoet_form_field_title_small"><%= __('Show divider between posts') %></div>
|
||||||
<div class="mailpoet_form_field_radio_option">
|
<div class="mailpoet_form_field_radio_option">
|
||||||
<label>
|
<label>
|
||||||
<input type="radio" name="mailpoet_automated_latest_content_show_divider"class="mailpoet_automated_latest_content_show_divider" value="true" {{#if model.showDivider}}CHECKED{{/if}}/>
|
<input type="radio" name="mailpoet_automated_latest_content_show_divider"class="mailpoet_automated_latest_content_show_divider" value="true" {{#if model.showDivider}}CHECKED{{/if}}/>
|
||||||
@ -281,7 +282,7 @@
|
|||||||
<%= __('No') %>
|
<%= __('No') %>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="mailpoet_form_field_input_option">
|
<div>
|
||||||
<a href="javascript:;" class="mailpoet_automated_latest_content_select_divider"><%= __('Select divider') %></a>
|
<a href="javascript:;" class="mailpoet_automated_latest_content_select_divider"><%= __('Select divider') %></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
{{/ifCond}}
|
{{/ifCond}}
|
||||||
|
|
||||||
<div class="mailpoet_form_field">
|
<div class="mailpoet_form_field">
|
||||||
|
<div class="mailpoet_form_field_title"><%= __('Alignment') %></div>
|
||||||
<div class="mailpoet_form_field_radio_option">
|
<div class="mailpoet_form_field_radio_option">
|
||||||
<label>
|
<label>
|
||||||
<input type="radio" name="alignment" class="mailpoet_field_button_alignment" value="left" {{#ifCond model.styles.block.textAlign '===' 'left'}}CHECKED{{/ifCond}}/>
|
<input type="radio" name="alignment" class="mailpoet_field_button_alignment" value="left" {{#ifCond model.styles.block.textAlign '===' 'left'}}CHECKED{{/ifCond}}/>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<div class="mailpoet_tools"></div>
|
<div class="mailpoet_tools"></div>
|
||||||
<div class="mailpoet_content">
|
<div class="mailpoet_content">
|
||||||
<%= __('Your posts will be inserted here') %>
|
<div class="mailpoet_posts_block_posts"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="mailpoet_block_highlight"></div>
|
<div class="mailpoet_block_highlight"></div>
|
||||||
|
@ -2,7 +2,9 @@
|
|||||||
<div class="mailpoet_settings_posts_selection"></div>
|
<div class="mailpoet_settings_posts_selection"></div>
|
||||||
<div class="mailpoet_settings_posts_display_options mailpoet_hidden"></div>
|
<div class="mailpoet_settings_posts_display_options mailpoet_hidden"></div>
|
||||||
<div class="mailpoet_settings_posts_controls">
|
<div class="mailpoet_settings_posts_controls">
|
||||||
|
<div class="mailpoet_form_field">
|
||||||
|
<a href="javascript:;" class="mailpoet_settings_posts_show_post_selection mailpoet_hidden"><%= __('Back to selection') %></a>
|
||||||
|
<a href="javascript:;" class="mailpoet_settings_posts_show_display_options"><%= __('Display options') %></a>
|
||||||
|
</div>
|
||||||
<input type="button" class="mailpoet_button mailpoet_button_primary mailpoet_settings_posts_insert_selected" value="<%= __('Insert selected') %>" />
|
<input type="button" class="mailpoet_button mailpoet_button_primary mailpoet_settings_posts_insert_selected" value="<%= __('Insert selected') %>" />
|
||||||
<a href="javascript:;" class="mailpoet_settings_posts_show_post_selection mailpoet_hidden"><%= __('Back to selection') %></a>
|
|
||||||
<a href="javascript:;" class="mailpoet_settings_posts_show_display_options"><%= __('Display options') %></a>
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -170,7 +170,7 @@
|
|||||||
<%= __('Below text') %>
|
<%= __('Below text') %>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="mailpoet_form_field_title mailpoet_form_field_title_small mailpoet_form_field_title_inline"><%= __('Categories:') %></div>
|
<div class="mailpoet_form_field_title mailpoet_form_field_title_small mailpoet_form_field_title_inline"><%= __('Preceded by:') %></div>
|
||||||
<div class="mailpoet_form_field_input_option">
|
<div class="mailpoet_form_field_input_option">
|
||||||
<input type="text" class="mailpoet_input mailpoet_input_medium mailpoet_posts_categories" value="{{ model.categoriesPrecededBy }}" />
|
<input type="text" class="mailpoet_input mailpoet_input_medium mailpoet_posts_categories" value="{{ model.categoriesPrecededBy }}" />
|
||||||
</div>
|
</div>
|
||||||
|
@ -13,6 +13,9 @@
|
|||||||
<option value="pending"><%= __('Pending Review') %></option>
|
<option value="pending"><%= __('Pending Review') %></option>
|
||||||
<option value="private"><%= __('Private') %></option>
|
<option value="private"><%= __('Private') %></option>
|
||||||
</select></div>
|
</select></div>
|
||||||
|
<div class="mailpoet_post_selection_filter_row">
|
||||||
|
<div class="mailpoet_form_field_title"><%= __('Categories & tags:') %></div>
|
||||||
|
</div>
|
||||||
<div class="mailpoet_post_selection_filter_row">
|
<div class="mailpoet_post_selection_filter_row">
|
||||||
<select class="mailpoet_select mailpoet_posts_categories_and_tags" multiple="multiple">
|
<select class="mailpoet_select mailpoet_posts_categories_and_tags" multiple="multiple">
|
||||||
{{#each terms}}
|
{{#each terms}}
|
||||||
|
@ -7,7 +7,11 @@
|
|||||||
'pageTitle': __('Newsletters'),
|
'pageTitle': __('Newsletters'),
|
||||||
'searchLabel': __('Search'),
|
'searchLabel': __('Search'),
|
||||||
'loadingItems': __('Loading newsletters...'),
|
'loadingItems': __('Loading newsletters...'),
|
||||||
'noItemsFound': __('No newsletters found.')
|
'noItemsFound': __('No newsletters found.'),
|
||||||
|
'selectAllLabel': __('All newsletters on this page are selected.'),
|
||||||
|
'selectedAllLabel': __('All %d newsletters are selected.'),
|
||||||
|
'selectAllLink': __('Select all pages.'),
|
||||||
|
'clearSelection': __('Clear selection.')
|
||||||
}) %>
|
}) %>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
|
24
views/update.html
Normal file
24
views/update.html
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<% extends 'layout.html' %>
|
||||||
|
|
||||||
|
<% block content %>
|
||||||
|
<div id="mailpoet_update">
|
||||||
|
<h2><%= __("What's new?") %></h2>
|
||||||
|
|
||||||
|
<p>Plugin version: <strong><%= settings.version %></strong></p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Current user:
|
||||||
|
<strong><%= current_user.user_nicename %></strong>
|
||||||
|
<<a href="mailto:<%= current_user.user_email %>">
|
||||||
|
<%=- current_user.user_email -%>
|
||||||
|
</a>>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<a
|
||||||
|
class="button button-primary"
|
||||||
|
href="<%= redirect_url %>"
|
||||||
|
>Take me to MailPoet</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<% endblock %>
|
@ -2,12 +2,23 @@
|
|||||||
|
|
||||||
<% block content %>
|
<% block content %>
|
||||||
<div id="mailpoet_welcome">
|
<div id="mailpoet_welcome">
|
||||||
<h2><%= __('Welcome welcome welcome!') %></h2>
|
<h2><%= __('Welcome!') %></h2>
|
||||||
|
|
||||||
<h3>Settings:</h3>
|
<p>Plugin version: <strong><%= settings.version %></strong></p>
|
||||||
<%= dump(settings) %>
|
|
||||||
|
|
||||||
<h3>Current user:</h3>
|
<p>
|
||||||
<%= dump(current_user) %>
|
Current user:
|
||||||
|
<strong><%= current_user.user_nicename %></strong>
|
||||||
|
<<a href="mailto:<%= current_user.user_email %>">
|
||||||
|
<%=- current_user.user_email -%>
|
||||||
|
</a>>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<a
|
||||||
|
class="button button-primary"
|
||||||
|
href="<%= redirect_url %>"
|
||||||
|
>Take me to MailPoet</a>
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<% endblock %>
|
<% endblock %>
|
||||||
|
@ -23,7 +23,7 @@ baseConfig = {
|
|||||||
'handlebars': 'handlebars/dist/handlebars.js',
|
'handlebars': 'handlebars/dist/handlebars.js',
|
||||||
'backbone.marionette': 'backbone.marionette/lib/backbone.marionette',
|
'backbone.marionette': 'backbone.marionette/lib/backbone.marionette',
|
||||||
'backbone.supermodel$': 'backbone.supermodel/build/backbone.supermodel.js',
|
'backbone.supermodel$': 'backbone.supermodel/build/backbone.supermodel.js',
|
||||||
'sticky-kit': 'sticky-kit/jquery.sticky-kit',
|
'sticky-kit': 'vendor_static/jquery.sticky-kit.js',
|
||||||
'interact$': 'interact.js/interact.js',
|
'interact$': 'interact.js/interact.js',
|
||||||
'spectrum$': 'spectrum-colorpicker/spectrum.js',
|
'spectrum$': 'spectrum-colorpicker/spectrum.js',
|
||||||
'blob$': 'blob/Blob.js',
|
'blob$': 'blob/Blob.js',
|
||||||
@ -166,9 +166,6 @@ config.push(_.extend({}, baseConfig, {
|
|||||||
'public.js'
|
'public.js'
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
/*plugins: [
|
|
||||||
new webpack.optimize.CommonsChunkPlugin('vendor', 'vendor.js'),
|
|
||||||
],*/
|
|
||||||
externals: {
|
externals: {
|
||||||
'jquery': 'jQuery'
|
'jquery': 'jQuery'
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user