diff --git a/RoboFile.php b/RoboFile.php
index 9c43104404..b02c7a3b2e 100644
--- a/RoboFile.php
+++ b/RoboFile.php
@@ -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(
diff --git a/assets/css/src/import.styl b/assets/css/src/import.styl
new file mode 100644
index 0000000000..63c38add18
--- /dev/null
+++ b/assets/css/src/import.styl
@@ -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
+
diff --git a/assets/js/src/import/import.js b/assets/js/src/import/import.js
new file mode 100644
index 0000000000..8abf0f5f7b
--- /dev/null
+++ b/assets/js/src/import/import.js
@@ -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();
+ });
+ }
+);
\ No newline at end of file
diff --git a/assets/js/src/import/import.jsx b/assets/js/src/import/import.jsx
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/lib/Config/Menu.php b/lib/Config/Menu.php
index b66995ed11..63fd1d4b24 100644
--- a/lib/Config/Menu.php
+++ b/lib/Config/Menu.php
@@ -1,5 +1,6 @@
renderer->render('newsletter/form.html', $data);
}
- function import() {
- echo $this->renderer->render('import.html');
+ function import() {
+ $import = new Import();
+ $data = $import->bootstrapImportMenu();
+
+ echo $this->renderer->render('import.html', $data);
}
+
function formEditor() {
$id = (isset($_GET['id']) ? (int)$_GET['id'] : 0);
diff --git a/lib/Import/Import.php b/lib/Import/Import.php
new file mode 100644
index 0000000000..6fdc467588
--- /dev/null
+++ b/lib/Import/Import.php
@@ -0,0 +1,103 @@
+ __("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;
+ }
+}
\ No newline at end of file
diff --git a/lib/Util/Helpers.php b/lib/Util/Helpers.php
new file mode 100644
index 0000000000..ec783ac027
--- /dev/null
+++ b/lib/Util/Helpers.php
@@ -0,0 +1,100 @@
+ '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)
+ );
+}
\ No newline at end of file
diff --git a/views/import.html b/views/import.html
index 2ca4813611..b543a7982b 100644
--- a/views/import.html
+++ b/views/import.html
@@ -1,5 +1,19 @@
<% extends 'layout.html' %>
<% block content %>
-
-<% endblock %>
+
+
<%= __('Import') %>
+
+ <% include 'import/step1.html' %>
+
+
+
+
+
+
+<%= stylesheet('import.css') %>
+
+<% endblock %>
\ No newline at end of file
diff --git a/views/import/step1.html b/views/import/step1.html
new file mode 100644
index 0000000000..1438643ce1
--- /dev/null
+++ b/views/import/step1.html
@@ -0,0 +1,154 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/webpack.config.js b/webpack.config.js
index e05281227f..0cbb5c1928 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -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: {