- Adds import's step 1 method selection logic
This commit is contained in:
@ -65,7 +65,8 @@ class RoboFile extends \Robo\Tasks {
|
||||
'assets/css/src/admin.styl',
|
||||
'assets/css/src/newsletter_editor/newsletter_editor.styl',
|
||||
'assets/css/src/public.styl',
|
||||
'assets/css/src/rtl.styl'
|
||||
'assets/css/src/rtl.styl',
|
||||
'assets/css/src/import.styl'
|
||||
);
|
||||
|
||||
$this->_exec(join(' ', array(
|
||||
|
69
assets/css/src/import.styl
vendored
Normal file
69
assets/css/src/import.styl
vendored
Normal file
@ -0,0 +1,69 @@
|
||||
.mailpoet_hidden, .mailpoet_validation_error
|
||||
display none
|
||||
|
||||
.mailpoet_no-search
|
||||
.select2-search
|
||||
display none
|
||||
|
||||
.form-table
|
||||
th
|
||||
width 300px
|
||||
|
||||
#paste_input
|
||||
width 100%
|
||||
|
||||
input[type="radio"]
|
||||
margin-right 0.5em !important
|
||||
& + span
|
||||
margin-right 2.5em
|
||||
|
||||
span
|
||||
&.mailpoet_mailchimp-key-status
|
||||
&.mailpoet_mailchimp-ok
|
||||
&:before
|
||||
content "\2713"
|
||||
color #0e90d2
|
||||
margin-left 15px
|
||||
&.mailpoet_mailchimp-error
|
||||
&:before
|
||||
content "\2717"
|
||||
color #900
|
||||
margin-left 15px
|
||||
|
||||
#subscribers_data
|
||||
overflow auto
|
||||
table
|
||||
width auto
|
||||
td
|
||||
padding 0.5em
|
||||
& > table
|
||||
& > tbody
|
||||
& > td
|
||||
padding 0.5em
|
||||
& > tr
|
||||
&:nth-child(odd)
|
||||
background #f9f9f9
|
||||
.mailpoet_header
|
||||
text-transform uppercase
|
||||
font-weight 600
|
||||
text-decoration underline
|
||||
|
||||
#subscribers_data th:first-child, #subscribers_data td:first-child
|
||||
width 10em !important
|
||||
text-align center !important
|
||||
padding 0 1em 0 1em !important
|
||||
vertical-align inherit !important
|
||||
|
||||
.mailpoet_data_match
|
||||
color #0e90d2
|
||||
margin-left 0.25em
|
||||
|
||||
.mailpoet_import_error, .mailpoet_validation_error
|
||||
color #900
|
||||
|
||||
tr
|
||||
&.mailpoet_lists
|
||||
& > td
|
||||
& > a
|
||||
margin-left 15px
|
||||
|
78
assets/js/src/import/import.js
Normal file
78
assets/js/src/import/import.js
Normal file
@ -0,0 +1,78 @@
|
||||
define(
|
||||
[
|
||||
'backbone',
|
||||
'underscore',
|
||||
'jquery',
|
||||
'mailpoet',
|
||||
'handlebars',
|
||||
'papaparse'
|
||||
],
|
||||
function (
|
||||
Backbone,
|
||||
_,
|
||||
jQuery,
|
||||
MailPoet,
|
||||
Handlebars,
|
||||
Papa
|
||||
) {
|
||||
jQuery(document).ready(function () {
|
||||
// configure router
|
||||
router = new (Backbone.Router.extend({
|
||||
routes: {
|
||||
'': 'home',
|
||||
'step_1': 'step_1',
|
||||
'step_2': 'step_2',
|
||||
'step_3': 'step_3'
|
||||
},
|
||||
home: function () {
|
||||
this.navigate('step_1', {trigger: true});
|
||||
}
|
||||
}));
|
||||
|
||||
function show_current_step() {
|
||||
MailPoet.Notice.hide();
|
||||
MailPoet.Modal.loading(false);
|
||||
jQuery('#mailpoet_subscribers_import > div[id^="step_"]').hide();
|
||||
jQuery(location.hash).show();
|
||||
}
|
||||
|
||||
/*
|
||||
* STEP 1 (upload or copy/paste)
|
||||
*/
|
||||
router.on('route:step_1', function () {
|
||||
// render process button for each each method
|
||||
var method_process_template = Handlebars.compile(jQuery('#method_process_template').html());
|
||||
jQuery('.mailpoet_method_process').html(method_process_template());
|
||||
|
||||
// define reusable variables
|
||||
var current_step = jQuery(location.hash),
|
||||
select_method = jQuery('#select_method'),
|
||||
subscribers_paste_input = jQuery('#paste_input'),
|
||||
subscribers_paste_input_placeholder = subscribers_paste_input.data('placeholder').replace(/\\n/g, '\n'),
|
||||
subscribers_paste_process = jQuery('#method_paste > div.mailpoet_method_process').find('a.mailpoet_process'),
|
||||
subscribers_mailchimp_key = jQuery('#mailchimp_key'),
|
||||
subscribers_mailchimp_key_verify = jQuery('#mailchimp_key_verify'),
|
||||
subscribers_mailchimp_lists = jQuery('#mailchimp_lists'),
|
||||
subscribers_mailchimp_process = jQuery('#method_mailchimp > div.mailpoet_method_process').find('a.mailpoet_process'),
|
||||
subscribers_file_local = jQuery('#file_local'),
|
||||
subscribers_file_process = jQuery('#method_file > div.mailpoet_method_process').find('a.mailpoet_process');
|
||||
|
||||
// define method change behavior
|
||||
select_method.change(function () {
|
||||
MailPoet.Notice.hide();
|
||||
var available_methods = jQuery(':radio[name="select_method"]'),
|
||||
selected_method = available_methods.index(available_methods.filter(':checked'));
|
||||
// hide all methods
|
||||
current_step.find('.inside').children('div[id^="method_"]').hide();
|
||||
// show selected method
|
||||
current_step.find('.inside').children('div[id^="method_"]:eq(' + selected_method + ')').show();
|
||||
});
|
||||
|
||||
// start step 1
|
||||
show_current_step();
|
||||
});
|
||||
|
||||
Backbone.history.start();
|
||||
});
|
||||
}
|
||||
);
|
@ -1,5 +1,6 @@
|
||||
<?php
|
||||
namespace MailPoet\Config;
|
||||
use MailPoet\Import\Import;
|
||||
use \MailPoet\Models\Segment;
|
||||
use \MailPoet\Models\Setting;
|
||||
use \MailPoet\Models\Form;
|
||||
@ -213,9 +214,13 @@ class Menu {
|
||||
}
|
||||
|
||||
function import() {
|
||||
echo $this->renderer->render('import.html');
|
||||
$import = new Import();
|
||||
$data = $import->bootstrapImportMenu();
|
||||
|
||||
echo $this->renderer->render('import.html', $data);
|
||||
}
|
||||
|
||||
|
||||
function formEditor() {
|
||||
$id = (isset($_GET['id']) ? (int)$_GET['id'] : 0);
|
||||
$form = Form::findOne($id);
|
||||
|
103
lib/Import/Import.php
Normal file
103
lib/Import/Import.php
Normal file
@ -0,0 +1,103 @@
|
||||
<?php namespace MailPoet\Import;
|
||||
|
||||
use MailPoet\Models\CustomField;
|
||||
use MailPoet\Models\Segment;
|
||||
|
||||
class Import {
|
||||
|
||||
function getSegments() {
|
||||
return Segment::findArray();
|
||||
}
|
||||
|
||||
function getSubscriberCustomFields() {
|
||||
return CustomField::findArray();
|
||||
}
|
||||
|
||||
function getSubscriberFields() {
|
||||
return array(
|
||||
'subscriber_email' => __("Email"),
|
||||
'subscriber_firstname' => __("First name"),
|
||||
'subscriber_lastname' => __("Last name"),
|
||||
'subscriber_confirmed_ip' => __("IP address"),
|
||||
'subscriber_confirmed_at' => __("Subscription date"),
|
||||
'subscriber_state' => __("Status")
|
||||
);
|
||||
}
|
||||
|
||||
function formatSubscriberFields($subscriberFields) {
|
||||
return array_map(function ($fieldId, $fieldName) {
|
||||
return array(
|
||||
'id' => $fieldId,
|
||||
'name' => $fieldName,
|
||||
'type' => ($fieldId === 'subscriber_confirmed_at') ? 'date' : null,
|
||||
'custom' => false
|
||||
);
|
||||
}, array_keys($subscriberFields), $subscriberFields);
|
||||
}
|
||||
|
||||
function formatSubscriberCustomFields($subscriberCustomFields) {
|
||||
return array_map(function ($field) {
|
||||
return array(
|
||||
'id' => $field['id'],
|
||||
'name' => $field['name'],
|
||||
'label' => $field['name'],
|
||||
'type' => $field['type'],
|
||||
'custom' => true
|
||||
);
|
||||
}, $subscriberCustomFields);
|
||||
}
|
||||
|
||||
function formatSelect2Fields($subscriberFields, $subscriberCustomFields) {
|
||||
$data = array(
|
||||
array(
|
||||
'name' => __("Actions"),
|
||||
'children' => array(
|
||||
array(
|
||||
'id' => 'ignore',
|
||||
'name' => __("Ignore column..."),
|
||||
),
|
||||
array(
|
||||
'id' => 'create',
|
||||
'name' => __("Create new column...")
|
||||
),
|
||||
)
|
||||
),
|
||||
array(
|
||||
'name' => __("System columns"),
|
||||
'children' => $subscriberFields
|
||||
)
|
||||
);
|
||||
|
||||
if($subscriberCustomFields) {
|
||||
array_push($data, array(
|
||||
'name' => __("User columns"),
|
||||
'children' => $subscriberCustomFields
|
||||
));
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
function bootstrapImportMenu() {
|
||||
$data['segments'] = array_map(function ($segment) {
|
||||
return array(
|
||||
'id' => $segment['id'],
|
||||
'name' => $segment['name'],
|
||||
'text' => $segment['name']
|
||||
);
|
||||
}, $this->getSegments());
|
||||
|
||||
$data['subscriberFields'] = $this->formatSubscriberFields(
|
||||
$this->getSubscriberFields()
|
||||
);
|
||||
|
||||
$data['subscriberCustomFields'] = $this->formatSubscriberCustomFields(
|
||||
$this->getSubscriberCustomFields()
|
||||
);
|
||||
|
||||
$data['select2Fields'] = $this->formatSelect2Fields(
|
||||
$data['subscriberFields'],
|
||||
$data['subscriberCustomFields']
|
||||
);
|
||||
return $data;
|
||||
}
|
||||
}
|
100
lib/Util/Helpers.php
Normal file
100
lib/Util/Helpers.php
Normal file
@ -0,0 +1,100 @@
|
||||
<?php
|
||||
namespace MailPoet\Util;
|
||||
|
||||
/*
|
||||
* Matches each symbol of PHP date format standard
|
||||
* with jQuery equivalent codeword
|
||||
* @author Tristan Jahier
|
||||
*/
|
||||
function dateformat_PHP_to_jQueryUI($php_format) {
|
||||
$SYMBOLS_MATCHING = array(
|
||||
// Day
|
||||
'd' => 'dd',
|
||||
'D' => 'D',
|
||||
'j' => 'd',
|
||||
'l' => 'DD',
|
||||
'N' => '',
|
||||
'S' => '',
|
||||
'w' => '',
|
||||
'z' => 'o',
|
||||
// Week
|
||||
'W' => '',
|
||||
// Month
|
||||
'F' => 'MM',
|
||||
'm' => 'mm',
|
||||
'M' => 'M',
|
||||
'n' => 'm',
|
||||
't' => '',
|
||||
// Year
|
||||
'L' => '',
|
||||
'o' => '',
|
||||
'Y' => 'yy',
|
||||
'y' => 'y',
|
||||
// Time
|
||||
'a' => '',
|
||||
'A' => '',
|
||||
'B' => '',
|
||||
'g' => '',
|
||||
'G' => '',
|
||||
'h' => '',
|
||||
'H' => '',
|
||||
'i' => '',
|
||||
's' => '',
|
||||
'u' => ''
|
||||
);
|
||||
$jqueryui_format = "";
|
||||
$escaping = false;
|
||||
for ($i = 0; $i < strlen($php_format); $i++) {
|
||||
$char = $php_format[$i];
|
||||
if($char === '\\') // PHP date format escaping character
|
||||
{
|
||||
$i++;
|
||||
if($escaping) {
|
||||
$jqueryui_format .= $php_format[$i];
|
||||
} else {
|
||||
$jqueryui_format .= '\'' . $php_format[$i];
|
||||
}
|
||||
$escaping = true;
|
||||
} else {
|
||||
if($escaping) {
|
||||
$jqueryui_format .= "'";
|
||||
$escaping = false;
|
||||
}
|
||||
if(isset($SYMBOLS_MATCHING[$char])) {
|
||||
$jqueryui_format .= $SYMBOLS_MATCHING[$char];
|
||||
} else {
|
||||
$jqueryui_format .= $char;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $jqueryui_format;
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine maximum post size in bytes
|
||||
*/
|
||||
function get_maximum_post_size() {
|
||||
$maximum_post_size = ini_get('post_max_size');
|
||||
$maximum_post_size_bytes = (int) $maximum_post_size;
|
||||
$unit = strtolower($maximum_post_size[strlen($maximum_post_size) - 1]);
|
||||
switch ($unit) {
|
||||
case 'g':
|
||||
$maximum_post_size_bytes *= 1024;
|
||||
case 'm':
|
||||
$maximum_post_size_bytes *= 1024;
|
||||
case 'k':
|
||||
$maximum_post_size_bytes *= 1024;
|
||||
}
|
||||
|
||||
return $maximum_post_size_bytes;
|
||||
}
|
||||
|
||||
/*
|
||||
* Flatten multidimensional array
|
||||
*/
|
||||
function flatten_array($array) {
|
||||
return call_user_func_array(
|
||||
'array_merge_recursive', array_map('array_values', $array)
|
||||
);
|
||||
}
|
@ -1,5 +1,19 @@
|
||||
<% extends 'layout.html' %>
|
||||
|
||||
<% block content %>
|
||||
<div id="import"></div>
|
||||
<div id="mailpoet_subscribers_import" class="wrap">
|
||||
<h2 class="title"><%= __('Import') %></h2>
|
||||
<!-- STEP 1: method selection -->
|
||||
<% include 'import/step1.html' %>
|
||||
<!-- STEP 2: subscriber manipulation -->
|
||||
|
||||
<!-- STEP 3: results -->
|
||||
|
||||
</div>
|
||||
|
||||
<%= stylesheet('import.css') %>
|
||||
<script type="text/javascript">
|
||||
var maximum_parse_size = <%= maximumParseSize %>,
|
||||
maximum_parse_notice = "<%= __('Your CSV is over %s, and too big to process. Please split the file in two, or more.')|replace({'%s': maximumParseSize}) %>";
|
||||
</script>
|
||||
<% endblock %>
|
154
views/import/step1.html
Normal file
154
views/import/step1.html
Normal file
@ -0,0 +1,154 @@
|
||||
<div id="step_1" class="_mailpoet_hidden">
|
||||
<div class="inside">
|
||||
<!-- Method selection -->
|
||||
<table class="mailpoet_subscribers form-table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<%= __('How would you like to import subscribers?') %>
|
||||
</th>
|
||||
<td>
|
||||
<div id="select_method">
|
||||
<label>
|
||||
<input type="radio" name="select_method"><span><%= __('Copy paste in a text box') %></span>
|
||||
</label> <label>
|
||||
<input type="radio" name="select_method"><span><%= __('Upload a file') %></span>
|
||||
</label> <label>
|
||||
<input type="radio" name="select_method"><span><%= __('Import from MailChimp') %></php></span>
|
||||
</label>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<!-- Paste -->
|
||||
<div id="method_paste" class="mailpoet_hidden">
|
||||
<table class="mailpoet_subscribers form-table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label for="paste_input"> <%= __('Copy and paste your subscribers from Excel/Sheets') %>
|
||||
<p class="description">
|
||||
<%=
|
||||
__('This needs to be in CSV style. See [link]examples in our support site[/link].')
|
||||
|replace({
|
||||
'[link]': '<a target="_blank" href="http://support.mailpoet.com/knowledgebase/importing-subscribers-with-a-csv-file/main.html?utm_source=wpadmin&utm_campaign=import">',
|
||||
'[/link]': '</a>'
|
||||
})
|
||||
|raw
|
||||
%>
|
||||
</p>
|
||||
</label>
|
||||
</th>
|
||||
<td>
|
||||
<textarea id="paste_input" rows="15" data-placeholder="Email,Name\njohndoe@mailpoet.com,John Doe\njanedoe@mailpoet.com,Jane Doe\njohnny_smith@mailpoet.com,Johnny Smith" class="regular-text code"></textarea>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="mailpoet_method_process">
|
||||
<!-- WILL BE INSERTED: Next button & spam notice template -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- CSV file -->
|
||||
<div id="method_file" class="mailpoet_hidden">
|
||||
<table class="mailpoet_subscribers form-table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label for="file_local">
|
||||
<%= __('Upload a file') %>
|
||||
|
||||
<p class="description">
|
||||
<%=
|
||||
__('This needs to be in CSV style. See [link]examples in our support site[/link].')
|
||||
|replace({
|
||||
'[link]': '<a target="_blank" href="http://support.mailpoet.com/knowledgebase/importing-subscribers-with-a-csv-file/main.html?utm_source=wpadmin&utm_campaign=import">',
|
||||
'[/link]': '</a>'
|
||||
})
|
||||
|raw
|
||||
%>
|
||||
</p>
|
||||
</label>
|
||||
</th>
|
||||
<td>
|
||||
<input type="file" id="file_local">
|
||||
|
||||
<%= __( 'total max upload file size : %s' )|replace({'%s': maximumParseSize}) %>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="mailpoet_method_process">
|
||||
<!-- WILL BE INSERTED: Next button & spam notice template -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Mailchimp -->
|
||||
<div id="method_mailchimp" class="mailpoet_hidden">
|
||||
<table class="mailpoet_subscribers form-table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label for="mailchimp_key">
|
||||
<%= __('Enter you MailChimp API key') %>
|
||||
</label>
|
||||
</th>
|
||||
<td>
|
||||
<input type="text" id="mailchimp_key">
|
||||
<button id="mailchimp_key_verify" disabled><%= __('Verify') %></button>
|
||||
<span class="mailpoet_mailchimp-key-status"></span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="mailchimp_lists" class="mailpoet_hidden">
|
||||
<th scope="row">
|
||||
<label>
|
||||
<%= __('Select list(s)') %>
|
||||
</label>
|
||||
</th>
|
||||
<td>
|
||||
<input type="mailpoet_hidden" id="mailchimp_lists_select">
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="mailpoet_method_process">
|
||||
<!-- WILL BE INSERTED: Next button & spam notice template -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Next button & spam notice template -->
|
||||
<script id="method_process_template" type="text/x-handlebars-template">
|
||||
<table class="mailpoet_subscribers form-table mailpoet_hidden">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<%= ('Did these subscribers ask to be in your list?') %>
|
||||
<p class="description">
|
||||
<%= ('If the answer is "no", consider yourself a spammer.') %>
|
||||
<br/>
|
||||
<%=
|
||||
__('[link]Read more on support.mailpoet.com[/link].')
|
||||
|replace({
|
||||
'[link]': '<a target="_blank" href="http://support.mailpoet.com/knowledgebase/dont-import-subscribers-who-didnt-sign-up/#utm_source=wpadmin&utm_campaign=importwarning">',
|
||||
'[/link]': '</a>'
|
||||
})
|
||||
|raw
|
||||
%>
|
||||
</p>
|
||||
</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<a href="javascript:;"
|
||||
class="button-primary wysija mailpoet_process"><%= ('Next step') %> </a>
|
||||
</th>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</script>
|
||||
|
||||
</div>
|
||||
</div>
|
@ -27,7 +27,8 @@ baseConfig = {
|
||||
'interact$': 'interact.js/interact.js',
|
||||
'spectrum$': 'spectrum-colorpicker/spectrum.js',
|
||||
'blob$': 'blob/Blob.js',
|
||||
'filesaver$': 'filesaver/FileSaver.js'
|
||||
'filesaver$': 'filesaver/FileSaver.js',
|
||||
'papaparse': 'papaparse/papaparse.min.js'
|
||||
},
|
||||
},
|
||||
node: {
|
||||
|
Reference in New Issue
Block a user