- Adds import's step 1 method selection logic

This commit is contained in:
MrCasual
2015-10-23 09:50:13 -04:00
parent 0b1fc8f6c3
commit 20a6e6d6de
10 changed files with 531 additions and 6 deletions

View File

@ -65,7 +65,8 @@ class RoboFile extends \Robo\Tasks {
'assets/css/src/admin.styl', 'assets/css/src/admin.styl',
'assets/css/src/newsletter_editor/newsletter_editor.styl', 'assets/css/src/newsletter_editor/newsletter_editor.styl',
'assets/css/src/public.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( $this->_exec(join(' ', array(

69
assets/css/src/import.styl vendored Normal file
View 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

View 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();
});
}
);

View File

@ -1,5 +1,6 @@
<?php <?php
namespace MailPoet\Config; namespace MailPoet\Config;
use MailPoet\Import\Import;
use \MailPoet\Models\Segment; use \MailPoet\Models\Segment;
use \MailPoet\Models\Setting; use \MailPoet\Models\Setting;
use \MailPoet\Models\Form; use \MailPoet\Models\Form;
@ -212,9 +213,13 @@ class Menu {
echo $this->renderer->render('newsletter/form.html', $data); echo $this->renderer->render('newsletter/form.html', $data);
} }
function import() { function import() {
echo $this->renderer->render('import.html'); $import = new Import();
$data = $import->bootstrapImportMenu();
echo $this->renderer->render('import.html', $data);
} }
function formEditor() { function formEditor() {
$id = (isset($_GET['id']) ? (int)$_GET['id'] : 0); $id = (isset($_GET['id']) ? (int)$_GET['id'] : 0);

103
lib/Import/Import.php Normal file
View 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
View 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)
);
}

View File

@ -1,5 +1,19 @@
<% extends 'layout.html' %> <% extends 'layout.html' %>
<% block content %> <% block content %>
<div id="import"></div> <div id="mailpoet_subscribers_import" class="wrap">
<% endblock %> <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
View 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">
&nbsp;
<%= __( '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>

View File

@ -27,7 +27,8 @@ baseConfig = {
'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',
'filesaver$': 'filesaver/FileSaver.js' 'filesaver$': 'filesaver/FileSaver.js',
'papaparse': 'papaparse/papaparse.min.js'
}, },
}, },
node: { node: {