From 541696863e070a65fe0bcbc2cedda9df13d76642 Mon Sep 17 00:00:00 2001 From: Jonathan Labreuille Date: Mon, 2 Nov 2015 19:01:01 +0100 Subject: [PATCH] Form editor - new/edit in forms listing goes to editor - fixed editor dependencies (via Webpack) - updated forms table schema - saving/loading a form works --- assets/css/src/form_editor.styl | 3 + assets/js/src/forms/list.jsx | 22 ++- lib/Config/Menu.php | 19 ++- lib/Config/Migrator.php | 2 +- lib/Form/Block/{base.php => Base.php} | 0 lib/Form/Block/{checkbox.php => Checkbox.php} | 0 lib/Form/Block/{date.php => Date.php} | 0 lib/Form/Block/{divider.php => Divider.php} | 0 lib/Form/Block/{html.php => Html.php} | 0 lib/Form/Block/{input.php => Input.php} | 0 lib/Form/Block/{lists.php => Lists.php} | 0 lib/Form/Block/{radio.php => Radio.php} | 0 lib/Form/Block/{select.php => Select.php} | 0 lib/Form/Block/{submit.php => Submit.php} | 0 lib/Form/Block/{textarea.php => Textarea.php} | 0 lib/Form/Util/{export.php => Export.php} | 0 lib/Form/Util/{styles.php => Styles.php} | 0 lib/Models/Form.php | 4 + lib/Router/Forms.php | 65 +++++++- views/form/editor.html | 144 ++++++++---------- webpack.config.js | 9 +- 21 files changed, 175 insertions(+), 93 deletions(-) rename lib/Form/Block/{base.php => Base.php} (100%) rename lib/Form/Block/{checkbox.php => Checkbox.php} (100%) rename lib/Form/Block/{date.php => Date.php} (100%) rename lib/Form/Block/{divider.php => Divider.php} (100%) rename lib/Form/Block/{html.php => Html.php} (100%) rename lib/Form/Block/{input.php => Input.php} (100%) rename lib/Form/Block/{lists.php => Lists.php} (100%) rename lib/Form/Block/{radio.php => Radio.php} (100%) rename lib/Form/Block/{select.php => Select.php} (100%) rename lib/Form/Block/{submit.php => Submit.php} (100%) rename lib/Form/Block/{textarea.php => Textarea.php} (100%) rename lib/Form/Util/{export.php => Export.php} (100%) rename lib/Form/Util/{styles.php => Styles.php} (100%) diff --git a/assets/css/src/form_editor.styl b/assets/css/src/form_editor.styl index cb5915edfa..67ed105838 100644 --- a/assets/css/src/form_editor.styl +++ b/assets/css/src/form_editor.styl @@ -1,3 +1,6 @@ +@require 'codemirror/lib/codemirror.css' +@require 'codemirror/theme/neo.css' + icons = '../img/form_editor_icons.png' handle_icon = '../img/handle.png' diff --git a/assets/js/src/forms/list.jsx b/assets/js/src/forms/list.jsx index 3b69454ed0..3f0c2a828b 100644 --- a/assets/js/src/forms/list.jsx +++ b/assets/js/src/forms/list.jsx @@ -86,7 +86,7 @@ const item_actions = [ label: 'Edit', link: function(item) { return ( - Edit + Edit ); } }, @@ -117,7 +117,19 @@ const bulk_actions = [ ]; const FormList = React.createClass({ - renderItem: function(form, actions) { + createForm() { + MailPoet.Ajax.post({ + endpoint: 'forms', + action: 'save', + data: { + name: "New form" + } + }).done(function(response) { + window.location = + 'admin.php?page=mailpoet-form-editor&id='+ parseInt(response, 10); + }) + }, + renderItem(form, actions) { let row_classes = classNames( 'manage-column', 'column-primary', @@ -151,7 +163,11 @@ const FormList = React.createClass({ return (

- Forms New + Forms New

__('My new form') ); - - $id = (isset($_POST['id']) ? (int)$_POST['id'] : 0); + $id = (isset($_GET['id']) ? (int)$_GET['id'] : 0); $form = Form::findOne($id); if($form !== false) { + $segments = $form->segments(); $form = $form->asArray(); + $form['segments'] = array_map(function($segment) { + return $segment['id']; + }, $segments->findArray()); } - $data['form'] = $form; - $data['segments'] = Segment::findArray(); + $data = array( + 'form' => $form, + 'pages' => Pages::getAll(), + 'segments' => Segment::findArray(), + 'styles' => FormRenderer::getStyles($form) + ); + echo $this->renderer->render('form/editor.html', $data); } } diff --git a/lib/Config/Migrator.php b/lib/Config/Migrator.php index 199f3a76b3..768b74801e 100644 --- a/lib/Config/Migrator.php +++ b/lib/Config/Migrator.php @@ -211,7 +211,7 @@ class Migrator { $attributes = array( 'id mediumint(9) NOT NULL AUTO_INCREMENT,', 'name varchar(90) NOT NULL,', - 'body longtext,', + 'data longtext,', 'created_at TIMESTAMP NOT NULL DEFAULT 0,', 'deleted_at TIMESTAMP NULL DEFAULT NULL,', 'updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,', diff --git a/lib/Form/Block/base.php b/lib/Form/Block/Base.php similarity index 100% rename from lib/Form/Block/base.php rename to lib/Form/Block/Base.php diff --git a/lib/Form/Block/checkbox.php b/lib/Form/Block/Checkbox.php similarity index 100% rename from lib/Form/Block/checkbox.php rename to lib/Form/Block/Checkbox.php diff --git a/lib/Form/Block/date.php b/lib/Form/Block/Date.php similarity index 100% rename from lib/Form/Block/date.php rename to lib/Form/Block/Date.php diff --git a/lib/Form/Block/divider.php b/lib/Form/Block/Divider.php similarity index 100% rename from lib/Form/Block/divider.php rename to lib/Form/Block/Divider.php diff --git a/lib/Form/Block/html.php b/lib/Form/Block/Html.php similarity index 100% rename from lib/Form/Block/html.php rename to lib/Form/Block/Html.php diff --git a/lib/Form/Block/input.php b/lib/Form/Block/Input.php similarity index 100% rename from lib/Form/Block/input.php rename to lib/Form/Block/Input.php diff --git a/lib/Form/Block/lists.php b/lib/Form/Block/Lists.php similarity index 100% rename from lib/Form/Block/lists.php rename to lib/Form/Block/Lists.php diff --git a/lib/Form/Block/radio.php b/lib/Form/Block/Radio.php similarity index 100% rename from lib/Form/Block/radio.php rename to lib/Form/Block/Radio.php diff --git a/lib/Form/Block/select.php b/lib/Form/Block/Select.php similarity index 100% rename from lib/Form/Block/select.php rename to lib/Form/Block/Select.php diff --git a/lib/Form/Block/submit.php b/lib/Form/Block/Submit.php similarity index 100% rename from lib/Form/Block/submit.php rename to lib/Form/Block/Submit.php diff --git a/lib/Form/Block/textarea.php b/lib/Form/Block/Textarea.php similarity index 100% rename from lib/Form/Block/textarea.php rename to lib/Form/Block/Textarea.php diff --git a/lib/Form/Util/export.php b/lib/Form/Util/Export.php similarity index 100% rename from lib/Form/Util/export.php rename to lib/Form/Util/Export.php diff --git a/lib/Form/Util/styles.php b/lib/Form/Util/Styles.php similarity index 100% rename from lib/Form/Util/styles.php rename to lib/Form/Util/Styles.php diff --git a/lib/Models/Form.php b/lib/Models/Form.php index b107085a5f..aba10e0617 100644 --- a/lib/Models/Form.php +++ b/lib/Models/Form.php @@ -57,6 +57,10 @@ class Form extends Model { $form = self::findOne((int)$data['id']); } + if(!empty($data['data'])) { + $data['data'] = json_encode($data['data']); + } + if($form === false) { $form = self::create(); $form->hydrate($data); diff --git a/lib/Router/Forms.php b/lib/Router/Forms.php index ebf66b7fbf..8d907e488b 100644 --- a/lib/Router/Forms.php +++ b/lib/Router/Forms.php @@ -75,13 +75,72 @@ class Forms { } } - if($form === false) { - wp_send_json($form->getValidationErrors()); + if($form !== false && $form->id()) { + wp_send_json($form->id()); } else { - wp_send_json(true); + wp_send_json($form); } } + function save_editor($data = array()) { + $form_id = (isset($data['id']) ? (int)$data['id'] : 0); + $form_data = (isset($data['form']) ? $data['form'] : array()); + + if(empty($form_data)) { + // error + wp_send_json(false); + } else { + // check if the form is displayed as a widget (we'll display a different "saved!" message in this case) + $is_widget = false; + $widgets = get_option('widget_mailpoet_form'); + if(!empty($widgets)) { + foreach($widgets as $widget) { + if(isset($widget['form']) && (int)$widget['form'] === $form_id) { + $is_widget = true; + break; + } + } + } + + // check if the user gets to pick his own lists or if it's selected by the admin + $has_list_selection = false; + + + $blocks = (isset($form_data['body']) ? $form_data['body'] : array()); + if(!empty($blocks)) { + foreach ($blocks as $i => $block) { + if($block['type'] === 'list') { + $has_list_selection = true; + if(!empty($block['params']['values'])) { + $list_selection = array_map(function($segment) { + return (int)$segment['id']; + }, $block['params']['values']); + } + break; + } + } + } + + // check list selectio + if($has_list_selection === true) { + $form_data['lists_selected_by'] = 'user'; + } else { + $form_data['lists_selected_by'] = 'admin'; + } + } + + $form = Form::createOrUpdate(array( + 'id' => $form_id, + 'data' => $form_data + )); + + // response + wp_send_json(array( + 'result' => ($form !== false), + 'is_widget' => $is_widget + )); +} + function restore($id) { $result = false; diff --git a/views/form/editor.html b/views/form/editor.html index 7309efcbfb..b2f11f895a 100644 --- a/views/form/editor.html +++ b/views/form/editor.html @@ -34,28 +34,31 @@
+

- <%= __('This form adds subscribers to these lists:') %> + <%= __('This form adds subscribers to these segments:') %>

- <% for segment in segments %> - + <% endfor %> - -

- <%= __('You have to select at least 1 list') %> -

+

  @@ -71,6 +75,7 @@ type="radio" name="on_success" value="page" + <% if(on_success == 'page') %>checked="checked"<% endif %> /><%= __('Go to page') %>

@@ -93,10 +98,10 @@ >

@@ -173,8 +178,10 @@
<%= javascript( + 'vendor.js', 'lib/prototype.min.js', 'lib/scriptaculous.min.js', + 'form_editor_lib.js', 'form_editor.js' )%> @@ -309,20 +316,26 @@ // save change if necessary if(new_value !== '' && current_value !== new_value) { - console.log('TODO: form->save', { - form: <%= form.id | default(0) %>, - form_name: new_value, + MailPoet.Ajax.post({ + endpoint: 'forms', + action: 'save', + data: { + id: $('#mailpoet_form_id').val(), + name: new_value + } + }).done(function(response) { + MailPoet.Notice.success( + "<%= __('Form name successfully updated!') %>" + ); }); - MailPoet.Notice.success("<%= __('Form name successfully updated!') %>"); } } } // on dom loaded $(function() { - // load form - WysijaForm.load(<%= form | json_encode | raw %>); + WysijaForm.load(<%= form.data | raw %>); // save form $('#mailpoet_form_save').on('click', function() { @@ -349,58 +362,35 @@ mailpoet_form_export(); function mailpoet_form_save(callback) { - console.log('TODO: form->save'); - - // if there is a callback, call it! - if(callback !== undefined) { - callback(); - } - /*mailpoet_post_json('form_save.php', { - form: <%= form.form %>, - data: WysijaForm.save() - }, function(response) { - if(response.result === false) { - var error = null; - if(response.error !== undefined) { - // display custom error message - error = $('.mailpoet_error[data-error="'+response.error+'"]'); - } - - if(error !== null) { - $(error).show(); - } else { - // display unknown error message - MailPoet.Notice.error("<%= __('An unknown error occurred. Please try again or get in touch with our support.') %>", { scroll: true }); - } - } else { - // if there is a callback, call it! - if(callback !== undefined) { - callback(); - } else { - // otherwise display a success message - - $success_message = str_replace(array( - '[link_widget]', - '[/link_widget]' - ), array( - '', - '' - ), - __('Saved! Add this form to [link_widget]a widget[/link_widget].') - ); - ?> - var success_message = ""; - - if(response.is_widget === true) { - success_message = ""; - } - - // display success message and scroll to it - MailPoet.Notice.hide(true); - MailPoet.Notice.success(success_message, { scroll: true, static: true }); - } + MailPoet.Ajax.post({ + endpoint: 'forms', + action: 'save_editor', + data: { + id: $('#mailpoet_form_id').val(), + form: WysijaForm.save() } - });*/ + }).done(function(response) { + var message = null; + + if(response.is_widget === true) { + message = "<%= __('Saved! The changes are already active in your widget.') %>"; + } else { + message = "<%= __('Saved! Add this form to %1$sa widget%2$s.') | format("", '') | raw %>"; + } + + if(message !== null) { + MailPoet.Notice.hide(); + MailPoet.Notice.success(message, { + scroll: true, + static: true + }); + } + + // if there is a callback, call it! + if(callback !== undefined) { + callback(); + } + }); } // toolbar: on success toggle @@ -505,15 +495,15 @@ }); // toolbar: list selection - var selected_lists = <%= form.segments | json_encode | raw %>; - var selected_lists_ids = []; - if(selected_lists !== null) { - selected_lists_ids = selected_lists.map(function(segment) { + var selected_segments = <%= form.segments | json_encode | raw %>; + var selected_segments_ids = []; + if(selected_segments !== null) { + selected_segments_ids = selected_segments.map(function(segment) { return parseInt(segment.id, 10); }); } // enable select2 for list selection - $('select[name="lists"]').select2({ + $('#mailpoet_form_segments').select2({ width:'100%', templateResult: function(item) { if(item.element && item.element.selected) { @@ -522,7 +512,7 @@ return item.text; } } - }); + }).select2('val', <%= form.segments | json_encode | raw %>); // subscriber meta fields var meta_fields = [ diff --git a/webpack.config.js b/webpack.config.js index b7a80bef89..811ae574bf 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -35,6 +35,10 @@ baseConfig = { test: /\.jsx$/, loader: 'babel-loader' }, + { + include: require.resolve('codemirror'), + loader: 'expose-loader?CodeMirror', + }, { include: require.resolve('backbone'), loader: 'expose-loader?Backbone', @@ -79,8 +83,8 @@ config.push(_.extend({}, baseConfig, { 'settings/tabs.js' ], form_editor_lib: [ - 'select2', - 'codemirror' + 'codemirror', + 'codemirror/mode/css/css' ], newsletter_editor: [ 'underscore', @@ -159,7 +163,6 @@ config.push(_.extend({}, baseConfig, { 'select2', 'blob', 'filesaver', - 'newsletter_editor/communicationsFix.js', 'newsletter_editor/App', 'newsletter_editor/components/config.js',