Tumbili: Mailchimp Signup for Gutenberg - Version 0.4

Version Description

  • WP 5.0 support
Download this release

Release Info

Developer gubbigubbi
Plugin Icon 128x128 Tumbili: Mailchimp Signup for Gutenberg
Version 0.4
Comparing to
See all releases

Version 0.4

assets/banner-772x250.jpg ADDED
Binary file
assets/icon-128x128.jpg ADDED
Binary file
assets/icon-256x256.jpg ADDED
Binary file
assets/reload.svg ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="iso-8859-1"?>
2
+ <!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
3
+ <svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
4
+ viewBox="0 0 489.533 489.533" style="enable-background:new 0 0 489.533 489.533;" xml:space="preserve">
5
+ <g>
6
+ <path d="M268.175,488.161c98.2-11,176.9-89.5,188.1-187.7c14.7-128.4-85.1-237.7-210.2-239.1v-57.6c0-3.2-4-4.9-6.7-2.9
7
+ l-118.6,87.1c-2,1.5-2,4.4,0,5.9l118.6,87.1c2.7,2,6.7,0.2,6.7-2.9v-57.5c87.9,1.4,158.3,76.2,152.3,165.6
8
+ c-5.1,76.9-67.8,139.3-144.7,144.2c-81.5,5.2-150.8-53-163.2-130c-2.3-14.3-14.8-24.7-29.2-24.7c-17.9,0-31.9,15.9-29.1,33.6
9
+ C49.575,418.961,150.875,501.261,268.175,488.161z"/>
10
+ </g>
11
+ <g>
12
+ </g>
13
+ <g>
14
+ </g>
15
+ <g>
16
+ </g>
17
+ <g>
18
+ </g>
19
+ <g>
20
+ </g>
21
+ <g>
22
+ </g>
23
+ <g>
24
+ </g>
25
+ <g>
26
+ </g>
27
+ <g>
28
+ </g>
29
+ <g>
30
+ </g>
31
+ <g>
32
+ </g>
33
+ <g>
34
+ </g>
35
+ <g>
36
+ </g>
37
+ <g>
38
+ </g>
39
+ <g>
40
+ </g>
41
+ </svg>
assets/screenshot-1.jpg ADDED
Binary file
assets/screenshot-2.jpg ADDED
Binary file
dist/blocks.build.js ADDED
@@ -0,0 +1 @@
 
1
+ !function(e){function t(r){if(n[r])return n[r].exports;var o=n[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,t),o.l=!0,o.exports}var n={};t.m=e,t.c=n,t.d=function(e,n,r){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:r})},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=0)}([function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});n(1)},function(e,t,n){"use strict";var r=n(2),o=(n.n(r),n(3)),l=(n.n(o),n(4)),a=n(5),i=wp.i18n.__;(0,wp.blocks.registerBlockType)("cgb/tumbili-mailchimp-for-gutenberg",{title:i("Tumbili: Mailchimp for Gutenberg"),icon:"email-alt",category:"common",keywords:[i("tumbili"),i("mailchimp")],attributes:l.a,edit:a.a,save:function(e){return e.attributes,e.className,null}})},function(e,t){},function(e,t){},function(e,t,n){"use strict";n.d(t,"a",function(){return r});var r={apiKey:{type:"string",default:""},listID:{type:"string",default:""},showFirstName:{type:"boolean",default:!1},showLastName:{type:"boolean",default:!1},buttonBackground:{type:"string",default:""},buttonColor:{type:"string",default:""}}},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!==typeof t&&"function"!==typeof t?e:t}function l(e,t){if("function"!==typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}var a=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),i=wp.element.Component,u=wp.editor,c=u.InspectorControls,m=u.PanelColorSettings,s=wp.components,p=s.PanelBody,f=s.TextControl,b=s.ToggleControl,w=wp.i18n.__,d=function(e){function t(){r(this,t);var e=o(this,(t.__proto__||Object.getPrototypeOf(t)).apply(this,arguments));return e.state={},e}return l(t,e),a(t,[{key:"render",value:function(){var e=this.props,t=e.attributes,n=t.showFirstName,r=t.showLastName,o=t.apiKey,l=t.listID,a=t.buttonBackground,i=t.buttonColor,u=e.className,s=e.setAttributes,d=void 0;n&&(d=wp.element.createElement("div",{className:"tumbili-form-control flex-grow"},wp.element.createElement("label",{htmlFor:"firstName"},"First Name",wp.element.createElement("input",{name:"firstName",type:"text"}))));var y=void 0;r&&(y=wp.element.createElement("div",{className:"tumbili-form-control flex-grow"},wp.element.createElement("label",{htmlFor:"lasttName"},"Last Name",wp.element.createElement("input",{name:"lastName",type:"text"}))));var g=wp.element.createElement("input",{style:{color:i,background:a},className:"tumbili-submit",type:"submit",value:"Submit"}),h=void 0;return h=o&&l?wp.element.createElement("div",{className:"display-flex tumbili-container"},d,y,wp.element.createElement("div",{className:"tumbili-form-control flex-grow"},wp.element.createElement("label",{htmlFor:"email"},"Email",wp.element.createElement("input",{name:"email",type:"email"}))),wp.element.createElement("div",{className:"tumbili-form-control flex-grow flex-is-at-bottom"},g)):wp.element.createElement("div",{className:u},"To get started please add an API Key & List ID."),wp.element.createElement("div",{className:u},wp.element.createElement(c,null,wp.element.createElement(p,{title:w("Form Options")},wp.element.createElement(f,{label:w("Mailchimp API Key"),value:o,onChange:function(e){return s({apiKey:e})}}),wp.element.createElement(f,{label:w("Mailchimp List ID"),value:l,onChange:function(e){return s({listID:e})}}),wp.element.createElement(b,{label:w("Show First Name?"),checked:n,onChange:function(e){return s({showFirstName:e})}}),wp.element.createElement(b,{label:w("Show Last Name?"),checked:r,onChange:function(e){return s({showLastName:e})}}),wp.element.createElement(m,{title:w("Color Settings"),colorSettings:[{value:a,onChange:function(e){return s({buttonBackground:e})},label:w("Button Background Color")},{value:i,onChange:function(e){return s({buttonColor:e})},label:w("Button Text Color")}]}))),h)}}]),t}(i);t.a=d}]);
dist/blocks.editor.build.css ADDED
@@ -0,0 +1 @@
 
1
+ .tumbili-submit{color:#fff;padding:6px 9px;font-size:13px;-webkit-transition:all 0.5s ease;-o-transition:all 0.5s ease;transition:all 0.5s ease;border-width:0px}.tumbili-submit:hover,.tumbili-submit:active{background-color:#753a10}
dist/blocks.style.build.css ADDED
@@ -0,0 +1 @@
 
1
+ .tumbili-form,.wp-block-cgb-tumbili-mailchimp-for-gutenberg{margin:0 auto;position:relative}.display-flex{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap}.display-flex>*{padding-left:.6rem;padding-right:.6rem}.flex-grow{-ms-flex-positive:1;flex-grow:1}.flex-is-at-bottom{display:-ms-flexbox;display:flex;-ms-flex-align:end;align-items:end}.tumbili-form-control{margin-bottom:1rem}.tumbili-form-control input,.tumbili-form-control label{display:block}.tumbili-form-control input{width:100%}.tumbili-submit{width:100%;background-color:#8b4513;border-color:#8b4513}.tumbili-submit .tumbili-loader{display:inline-block;margin-right:0.5rem}.tumbili-submit .tumbili-loader.is-hiding{width:0;margin-right:0;display:none}.tumbili-response{text-align:center;position:absolute;width:100%;max-width:440px;top:50%;left:50%;-webkit-transform:translateY(-50%) translateX(-50%);-ms-transform:translateY(-50%) translateX(-50%);transform:translateY(-50%) translateX(-50%);padding:0.5rem;-webkit-box-shadow:0 4px 8px 0 rgba(0,0,0,0.12),0 2px 4px 0 rgba(0,0,0,0.08);box-shadow:0 4px 8px 0 rgba(0,0,0,0.12),0 2px 4px 0 rgba(0,0,0,0.08);border-radius:0.25rem}.tumbili-response:after{content:'';background-image:url("../assets/reload.svg");background-size:24px 24px;height:24px;width:24px;margin-left:0.5rem;display:inline-block;vertical-align:middle}.tumbili-container{-webkit-transition:all 0.3s ease;-o-transition:all 0.3s ease;transition:all 0.3s ease;margin-bottom:-1rem}.isSubmitting input{-webkit-filter:blur(1px);filter:blur(1px)}.will-animate{-webkit-transition:all 400ms;-o-transition:all 400ms;transition:all 400ms}.is-showing{opacity:1}.is-hiding{opacity:0;visibility:hidden}@-webkit-keyframes ball-pulse-sync{33%{-webkit-transform:translateY(7px);transform:translateY(7px)}66%{-webkit-transform:translateY(-7px);transform:translateY(-7px)}100%{-webkit-transform:translateY(0);transform:translateY(0)}}@keyframes ball-pulse-sync{33%{-webkit-transform:translateY(7px);transform:translateY(7px)}66%{-webkit-transform:translateY(-7px);transform:translateY(-7px)}100%{-webkit-transform:translateY(0);transform:translateY(0)}}.ball-pulse-sync>div:nth-child(1){-webkit-animation:ball-pulse-sync 0.7s -.14s infinite ease-in-out;animation:ball-pulse-sync 0.7s -.14s infinite ease-in-out}.ball-pulse-sync>div:nth-child(2){-webkit-animation:ball-pulse-sync 0.7s -.07s infinite ease-in-out;animation:ball-pulse-sync 0.7s -.07s infinite ease-in-out}.ball-pulse-sync>div:nth-child(3){-webkit-animation:ball-pulse-sync 0.7s 0s infinite ease-in-out;animation:ball-pulse-sync 0.7s 0s infinite ease-in-out}.ball-pulse-sync>div{background-color:#fff;width:8px;height:8px;border-radius:100%;margin:2px;-webkit-animation-fill-mode:both;animation-fill-mode:both;display:inline-block}
plugin.php ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Plugin Name: Tumbili: Mailchimp Signup for Gutenberg
4
+ * Plugin URI: https://github.com/gubbigubbi/tumbili-mailchimp
5
+ * Description: Easily add a mailchimp signup form to your editor.
6
+ * Author: gubbigubbi
7
+ * Author URI: https://github.com/gubbigubbi/
8
+ * Version: 0.4
9
+ * License: GPL2+
10
+ * License URI: http://www.gnu.org/licenses/gpl-2.0.txt
11
+ *
12
+ * @package CGB
13
+ */
14
+
15
+ // Exit if accessed directly.
16
+ if ( ! defined( 'ABSPATH' ) ) {
17
+ exit;
18
+ }
19
+
20
+ /**
21
+ * Block Initializer.
22
+ */
23
+ require_once plugin_dir_path( __FILE__ ) . 'src/init.php';
readme.txt ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ === Plugin Name ===
2
+ Contributors: gubbigubbi
3
+ Tags: gutenberg, mailchimp, mailchimp signup, mailchimp form
4
+ Requires at least: 4.9.6
5
+ Tested up to: 5.0
6
+ Stable tag: 0.4
7
+ Requires PHP: 5.4
8
+ License: GPLv2 or later
9
+ License URI: https://www.gnu.org/licenses/gpl-2.0.html
10
+
11
+ Easily and instantly preview your mailchimp feed live within the new editor experience. Adjust settings as neededm such as the number of columns and the spacing. More features to come!
12
+
13
+ == Description ==
14
+
15
+ ## Tumbili: Mailchimp Signup for Gutenberg
16
+ Easily and instantly preview your mailchimp feed live within the new editor (Gutenberg) experience. Adjust settings as neededm such as the number of columns and the spacing. More features to come.
17
+
18
+ ###Want to see a feature?
19
+ ###### Feel free to tweet and say 👋 at me [@RhysClay](https://twitter.com/rhysclay/)
20
+
21
+ == Installation ==
22
+
23
+ Firstly make sure that you have the Gutenberg plugin installed.
24
+
25
+ 1. Install the tumbili plugin either via the WordPress plugin directory, or by uploading the files to your web server (in the /wp-content/plugins/ directory).
26
+ 1. Activate the tumbili plugin through the 'Plugins' screen in WordPress
27
+ 1. Get your Mailchimp API key and List ID: To do this login to mailchimp and [follow these steps] (https://medium.com/@arcomito/grabbing-your-mailchimp-api-key-and-list-id-for-mailchimp-integration-22ef4b20792f)
28
+ 1. Add the tumbili block to your editor, paste the API key/List ID into the block settings.
29
+ 1. Your mailchimp signup form will now show in the editor, adjust the settings to see how it will look before publishing.
30
+
31
+ == Frequently Asked Questions ==
32
+
33
+ = How about X feature? =
34
+
35
+ We will continue adding features as requested. If you have a killer idea for a feature submit a support request and we will see what we can do.
36
+ Note: we plan to release a premium version of the plugin which will likely receive new features first - this helps offset the cost of our development time.
37
+
38
+ = The feed looks funny in I10 (Or other old browser)
39
+
40
+ This plugin is laid out using Flexbox, we do not have plans to support older browsers as we believe they are holding back the web. However we can (if requested) release some code which you can add to your site's custom css in order to support certain browsers.
41
+
42
+ == Screenshots ==
43
+
44
+ 1. Adding the tumbili block to the editor and adjusting the settings.
45
+ 2. Your signup form as it appears on the front end.
46
+
47
+ == Changelog ==
48
+
49
+ = 0.4 =
50
+ * WP 5.0 support
51
+
52
+ = 0.3 =
53
+ * Update to allow for multiple forms in one page
54
+
55
+ = 0.2 =
56
+ * Update to sanitize form data
57
+
58
+ = 0.1 =
59
+ * First release.
src/client.js ADDED
@@ -0,0 +1,156 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ //
2
+ // DOM READY SCRIPT
3
+ //
4
+ var domIsReady = (function(domIsReady) {
5
+ var isBrowserIeOrNot = function() {
6
+ return (!document.attachEvent || typeof document.attachEvent === "undefined" ? 'not-ie' : 'ie');
7
+ }
8
+
9
+ domIsReady = function(callback) {
10
+ if(callback && typeof callback === 'function'){
11
+ if(isBrowserIeOrNot() !== 'ie') {
12
+ document.addEventListener("DOMContentLoaded", function() {
13
+ return callback();
14
+ });
15
+ } else {
16
+ document.attachEvent("onreadystatechange", function() {
17
+ if(document.readyState === "complete") {
18
+ return callback();
19
+ }
20
+ });
21
+ }
22
+ } else {
23
+ console.error('The callback is not a function!');
24
+ }
25
+ }
26
+
27
+ return domIsReady;
28
+ })(domIsReady || {});
29
+
30
+ //
31
+ // DOM IS READY
32
+ //
33
+ (function(document, window, domIsReady, undefined) {
34
+ domIsReady(function() {
35
+
36
+ function tumbiliSubmitForm( evt ) {
37
+ const form = evt.target;
38
+ const loader = document.querySelector( '.tumbili-loader' );
39
+ const data = {};
40
+
41
+ data.fname = form.querySelector( '.tumbiliFName' ) ?
42
+ form
43
+ .querySelector( '.tumbiliFName' )
44
+ .value :
45
+ '';
46
+
47
+ data.lname = form.querySelector( '.tumbiliLName' ) ?
48
+ form
49
+ .querySelector( '.tumbiliLName' )
50
+ .value :
51
+ '';
52
+
53
+ data.email = form.querySelector( '.tumbiliEmail' ) ?
54
+ form
55
+ .querySelector( '.tumbiliEmail' )
56
+ .value :
57
+ '';
58
+
59
+ data.apikey = form.dataset.apikey;
60
+ data.listID = form.dataset.listid;
61
+ data.dc = form.dataset.apikey.split( '-' )[ 1 ];
62
+
63
+ sendRequestViaAJAX( data, form, loader );
64
+ }
65
+
66
+ function sendRequestViaAJAX( formData, form, loader ) {
67
+ var data = 'action=tumbili_mailchimp_add_subscriber&formData[apikey]=' + formData.apikey + '&formData[listID]=' + formData.listID + '&formData[dc]=' + formData.dc + '&formData[fname]=' + formData.fname + '&formData[lname]=' + formData.lname + '&formData[email]=' + formData.email;
68
+
69
+ var serialized_data = encodeURI( data );
70
+
71
+ var xhr = new XMLHttpRequest();
72
+ var url = tumbili.ajax_url;
73
+
74
+ form.classList.toggle( 'isSubmitting' );
75
+ loader.classList.toggle( 'is-hiding' );
76
+
77
+ xhr.open( "POST", url, true);
78
+ xhr.setRequestHeader( 'Accept', 'application/json, text/javascript, */*; q=0.01' );
79
+ xhr.setRequestHeader( 'Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8' );
80
+ xhr.setRequestHeader( 'X-Requested-With', 'XMLHttpRequest' );
81
+
82
+ xhr.responseType = 'json';
83
+ xhr.onerror = function(){
84
+ console.log( 'Error: Do something else...' );
85
+ }
86
+ xhr.onprogress = function () {
87
+ console.log( 'status:LOADING', xhr.status, ' STATE', xhr.readyState, ' RESPONSE', JSON.parse(xhr.response) );
88
+ };
89
+ xhr.onload = function ( response ) {
90
+ if (this.status == 200) {
91
+ form.classList.toggle( 'isSubmitting' );
92
+ loader.classList.toggle( 'is-hiding' );
93
+ console.log( 'status:DONE', xhr.status, ' STATE', xhr.readyState, 'NoParseResponse', this.response ); // JSON response
94
+ var mailchimpResponse = this.response;
95
+ showApiResult( mailchimpResponse );
96
+ }
97
+ };
98
+ xhr.send( serialized_data );
99
+ }
100
+
101
+ function showApiResult( response ) {
102
+ console.log( response );
103
+ let title;
104
+
105
+ if ( response.status === 400 ) {
106
+ switch ( response.title ) {
107
+ case 'Forgotten Email Not Subscribed':
108
+ title =
109
+ 'Looks like you unsubscribed from this list previously, please contact us to resubscribe';
110
+ break;
111
+ case 'Member Exists':
112
+ title = '😄 Looks you are already subscribed';
113
+ break;
114
+ default:
115
+ title = `Oops something wen't wrong: ${ response.title }`;
116
+ }
117
+ } else {
118
+ title =
119
+ '🎉 You have subscribed. Please check your inbox for confirmation.';
120
+ }
121
+
122
+ toggleForm( title );
123
+ }
124
+
125
+
126
+ function toggleForm( title = '' ) {
127
+ const formContainer = document.querySelector( '.tumbili-container' );
128
+ const responseContainer = document.querySelector( '.tumbili-response' );
129
+ formContainer.classList.toggle( 'is-hiding' );
130
+ responseContainer.classList.toggle( 'is-hiding' );
131
+ responseContainer.innerHTML = title;
132
+ }
133
+
134
+
135
+ var docForms = document.querySelectorAll('form');
136
+ var formTumbili = document.querySelectorAll('.tumbili-form');
137
+ for (var i = 0; i < docForms.length; i++) {
138
+ console.log('docForms[i]: ', docForms[i]);
139
+ if ( docForms[i].classList.contains( 'tumbili-form' ) ) {
140
+ console.log('tumbili-form!!!!');
141
+ this.addEventListener( 'submit', function( evt ) {
142
+ evt.preventDefault();
143
+ tumbiliSubmitForm( evt );
144
+ } );
145
+ }
146
+ }
147
+
148
+
149
+ if ( document.querySelector( '.tumbili-response' ) ) {
150
+ document.querySelector( '.tumbili-response' ).onclick = function() {
151
+ toggleForm();
152
+ };
153
+ }
154
+
155
+ });
156
+ })(document, window, domIsReady);
src/init.php ADDED
@@ -0,0 +1,87 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Blocks Initializer
4
+ *
5
+ * Enqueue CSS/JS of all the blocks.
6
+ *
7
+ * @since 1.0.0
8
+ * @package CGB
9
+ */
10
+
11
+ // Exit if accessed directly.
12
+ if ( ! defined( 'ABSPATH' ) ) {
13
+ exit;
14
+ }
15
+
16
+ // Constants
17
+ define( 'TUMBILI_PLUGIN_PATH', plugin_dir_path( __FILE__ ) );
18
+
19
+ /**
20
+ * Enqueue Gutenberg block assets for both frontend + backend.
21
+ *
22
+ * `wp-blocks`: includes block type registration and related functions.
23
+ *
24
+ * @since 1.0.0
25
+ */
26
+ function tumbili_block_assets() {
27
+ // Styles.
28
+ wp_enqueue_style(
29
+ 'tumbili-style-css', // Handle.
30
+ plugins_url( 'dist/blocks.style.build.css', dirname( __FILE__ ) ), // Block style CSS.
31
+ array( 'wp-editor' ) // Dependency to include the CSS after it.
32
+ // filemtime( plugin_dir_path( __DIR__ ) . 'dist/blocks.style.build.css' ) // Version: filemtime — Gets file modification time.
33
+ );
34
+ } // End function tumbili_block_assets().
35
+
36
+ // Hook: Frontend assets.
37
+ add_action( 'enqueue_block_assets', 'tumbili_block_assets' );
38
+
39
+ /**
40
+ * Enqueue assets for the frontend only
41
+ */
42
+
43
+ function tumbili_client_assets() {
44
+ wp_enqueue_script( 'tumbili-js', plugins_url( 'src/client.js', dirname( __FILE__ ) ), array(), true );
45
+
46
+ wp_localize_script( 'tumbili-js', 'tumbili', array(
47
+ 'ajax_url' => admin_url( 'admin-ajax.php' )
48
+ ));
49
+ }
50
+
51
+ add_action( 'wp_enqueue_scripts', 'tumbili_client_assets' );
52
+
53
+ /**
54
+ * Enqueue Gutenberg block assets for backend editor.
55
+ *
56
+ * `wp-blocks`: includes block type registration and related functions.
57
+ * `wp-element`: includes the WordPress Element abstraction for describing the structure of your blocks.
58
+ * `wp-i18n`: To internationalize the block's text.
59
+ *
60
+ * @since 1.0.0
61
+ */
62
+ function tumbili_editor_assets() {
63
+ // Scripts.
64
+ wp_enqueue_script(
65
+ 'tumbili-block-js', // Handle.
66
+ plugins_url( '/dist/blocks.build.js', dirname( __FILE__ ) ), // Block.build.js: We register the block here. Built with Webpack.
67
+ array( 'wp-blocks', 'wp-i18n', 'wp-element', 'wp-editor' ), // Dependencies, defined above.
68
+ // filemtime( plugin_dir_path( __DIR__ ) . 'dist/blocks.build.js' ), // Version: filemtime — Gets file modification time.
69
+ true // Enqueue the script in the footer.
70
+ );
71
+
72
+ // Styles.
73
+ wp_enqueue_style(
74
+ 'tumbili-block-editor-css', // Handle.
75
+ plugins_url( 'dist/blocks.editor.build.css', dirname( __FILE__ ) ), // Block editor CSS.
76
+ array( 'wp-edit-blocks' ) // Dependency to include the CSS after it.
77
+ // filemtime( plugin_dir_path( __DIR__ ) . 'dist/blocks.editor.build.css' ) // Version: filemtime — Gets file modification time.
78
+ );
79
+ } // End function tumbili_editor_assets().
80
+
81
+ // Hook: Editor assets.
82
+ add_action( 'enqueue_block_editor_assets', 'tumbili_editor_assets' );
83
+
84
+ /**
85
+ * Server Side Rendering
86
+ */
87
+ require_once( TUMBILI_PLUGIN_PATH . './server.php' );
src/server.php ADDED
@@ -0,0 +1,164 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ register_block_type('cgb/tumbili-mailchimp-for-gutenberg', array(
3
+ 'render_callback' => 'tumbili_render_callback',
4
+ 'attributes' => array(
5
+ 'formAction' => array(
6
+ 'type' => 'string',
7
+ 'default' => '',
8
+ ),
9
+ 'apiKey' => array(
10
+ 'type' => 'string',
11
+ 'default' => '',
12
+ ),
13
+ 'listID' => array(
14
+ 'type' => 'string',
15
+ 'default' => '',
16
+ ),
17
+ 'showFirstName' => array(
18
+ 'type' => 'boolean',
19
+ 'default' => false,
20
+ ),
21
+ 'showLastName' => array(
22
+ 'type' => 'boolean',
23
+ 'default' => false,
24
+ ),
25
+ 'buttonColor' => array(
26
+ 'type' => 'string',
27
+ 'default' => '',
28
+ ),
29
+ 'buttonBackground' => array(
30
+ 'type' => 'string',
31
+ 'default' => '',
32
+ ),
33
+ )
34
+ )
35
+ );
36
+
37
+ /**
38
+ * Post to Mailchimp
39
+ */
40
+ add_action( 'wp_ajax_nopriv_tumbili_mailchimp_add_subscriber', 'tumbili_mailchimp_add_subscriber' );
41
+ add_action( 'wp_ajax_tumbili_mailchimp_add_subscriber', 'tumbili_mailchimp_add_subscriber' );
42
+
43
+ // TODO: Could some of this data be passed with a render callback???
44
+ function tumbili_mailchimp_add_subscriber( ) {
45
+
46
+ $formData = $_POST['formData'];
47
+
48
+ // Sanitize data
49
+ $api_key = sanitize_key($formData['apikey']);
50
+ $datacenter = sanitize_text_field($formData['dc']);
51
+ $list_id = sanitize_key($formData['listID']);
52
+ $errors = array();
53
+ $data = array();
54
+ $first_name = $formData['fname'] ? sanitize_text_field($formData['fname']) : '';
55
+ $last_name = $formData['lname'] ? sanitize_text_field($formData['lname']) : '';
56
+ $email = sanitize_email($formData['email']);
57
+ $status = 'pending';
58
+ // if ( !empty($_POST['status']) ) {
59
+ // $status = $_POST['status'];
60
+ // }
61
+
62
+ $url = "https://{$datacenter}.api.mailchimp.com/3.0/lists/{$list_id}/members/";
63
+ $auth = base64_encode( 'user:'.esc_attr($api_key) );
64
+ $response = [];
65
+
66
+ $data = array(
67
+ 'email_address' => esc_attr($email),
68
+ 'status' => esc_attr($status),
69
+ 'merge_fields' => array(
70
+ 'FNAME' => esc_attr($first_name),
71
+ 'LNAME' => esc_attr($last_name)
72
+ )
73
+ );
74
+
75
+ $response = json_encode(tumbili_fetchData(esc_attr($url), $data, $auth));
76
+ echo $response;
77
+ wp_die();
78
+ }
79
+
80
+ function tumbili_fetchData($url, $data, $auth) {
81
+
82
+ $data_string = json_encode($data);
83
+
84
+ $args = array(
85
+ 'method' => 'POST',
86
+ 'headers' => array(
87
+ 'Content-Type' => 'application/json',
88
+ 'Content-Length' => strlen($data_string),
89
+ 'Authorization' => 'Basic '.$auth
90
+ ),
91
+ 'body' => json_encode($data),
92
+ );
93
+
94
+ $request = wp_remote_post( $url, $args);
95
+
96
+ if(is_wp_error( $request )) {
97
+ return false;
98
+ }
99
+
100
+ return json_decode( $request['body'] );
101
+ }
102
+
103
+
104
+ /**
105
+ * Server side rendering functions
106
+ */
107
+ function tumbili_render_callback( array $attributes ){
108
+
109
+ $formAction = $attributes[ 'formAction' ];
110
+ $apiKey = $attributes[ 'apiKey' ];
111
+ $listID = $attributes[ 'listID' ] ;
112
+ $showFirstName = $attributes[ 'showFirstName' ];
113
+ $showLastName = $attributes[ 'showLastName' ];
114
+ $buttonBackground = $attributes[ 'buttonBackground' ];
115
+ $buttonColor = $attributes[ 'buttonColor' ];
116
+
117
+ $firstName = '';
118
+ $lastName = '';
119
+
120
+ if($showFirstName) {
121
+ $firstName .= '
122
+ <div class="tumbili-form-control flex-grow">
123
+ <label for="firstName">First Name<input name="firstName" class="tumbiliFName" type="text"></label>
124
+ </div>';
125
+ }
126
+
127
+ if($showLastName) {
128
+ $lastName .= '
129
+ <div class="tumbili-form-control flex-grow">
130
+ <label for="lastName">Last Name<input name="lastName" class="tumbiliLName" type="text"></label>
131
+ </div>';
132
+ }
133
+
134
+ $markup = '<form class="tumbili-form" data-apikey="'.$apiKey.'" data-listid="'.$listID.'" action="'.$formAction.'" method="post" class="wp-block-cgb-tumbili-mailchimp-for-gutenberg">';
135
+
136
+ $markup .= '<a class="tumbili-response will-animate is-hiding"></a>';
137
+ $markup .= '<div class="display-flex tumbili-container will-animate">';
138
+
139
+ $markup .= $firstName;
140
+ $markup .= $lastName;
141
+
142
+ $markup .= '
143
+ <div class="tumbili-form-control flex-grow">
144
+ <label for="email">Email<input class="tumbiliEmail" name="email" type="email"></label>
145
+ </div>
146
+ <div class="flex-grow flex-is-at-bottom tumbili-form-control">
147
+ <button style="background-color: '.$buttonBackground.'; color: '.$buttonColor.'; border-color: '.$buttonBackground.'" class="tumbili-submit" value="Submit" type="submit">
148
+ <div class="tumbili-loader will-animate is-hiding">
149
+ <div class="loader-inner ball-pulse-sync">
150
+ <div></div>
151
+ <div></div>
152
+ <div></div>
153
+ </div>
154
+ </div>
155
+ Submit
156
+ </button>
157
+ </div>
158
+
159
+
160
+ ';
161
+
162
+
163
+ return "{$markup}</div></form></form>";
164
+ }