├── index.php
├── wpml-config.xml
├── .eslintrc.js
├── .editorconfig
├── phpcs.xml
├── src
├── admin-notice-install-deps.php
├── functions.php
├── Admin.php
└── Bar.php
├── assets
└── src
│ ├── js
│ ├── cookies.js
│ ├── admin.js
│ ├── loader.js
│ └── script.js
│ └── css
│ └── bar.css
├── .github
└── workflows
│ └── check-php-syntax.yml
├── webpack.config.js
├── README.md
├── mailchimp-top-bar.php
├── create-version.sh
├── composer.lock
├── CHANGELOG.md
├── readme.txt
├── views
└── settings-page.php
└── LICENSE
/index.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | env: {
3 | browser: true,
4 | commonjs: true,
5 | es6: true
6 | },
7 | extends: [
8 | 'standard'
9 | ],
10 | globals: {
11 | Atomics: 'readonly',
12 | SharedArrayBuffer: 'readonly'
13 | },
14 | parserOptions: {
15 | ecmaVersion: 2018
16 | },
17 | rules: {
18 | 'no-prototype-builtins': 'off'
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # This file is for unifying the coding style for different editors and IDEs
2 | # editorconfig.org
3 |
4 | # WordPress Coding Standards
5 | # https://make.wordpress.org/core/handbook/coding-standards/
6 |
7 | root = true
8 |
9 | [*]
10 | charset = utf-8
11 | end_of_line = lf
12 | insert_final_newline = true
13 | trim_trailing_whitespace = true
14 | indent_style = space
15 | indent_size = 4
16 |
17 | [*.{yaml,yml}]
18 | indent_style = space
19 | indent_size = 2
20 |
21 | [*.js]
22 | indent_style = space
23 | indent_size = 2
24 |
25 | [*.md]
26 | trim_trailing_whitespace = false
27 |
28 | [{*.txt,wp-config-sample.php}]
29 | end_of_line = crlf
30 |
--------------------------------------------------------------------------------
/phpcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | rules
4 |
5 | src/
6 | mailchimp-top-bar.php
7 | *\.(html|css|js)
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/admin-notice-install-deps.php:
--------------------------------------------------------------------------------
1 |
13 |
14 |
%s in order to use %s.', 'mailchimp-top-bar'), $url, 'MailChimp for WordPress', 'MailChimp Top Bar'); ?>
15 |
16 | {
40 | return postcss([cssnano])
41 | .process(content, {
42 | from: path
43 | })
44 | .then((result) => {
45 | return result.css
46 | })
47 | }
48 | }
49 | ]
50 | })
51 | ]
52 | }
53 |
--------------------------------------------------------------------------------
/assets/src/js/admin.js:
--------------------------------------------------------------------------------
1 | const elSelectList = document.getElementById('select-mailchimp-list')
2 | const msgRequiresFields = document.getElementById('message-list-requires-fields')
3 |
4 | /*
5 | * Functions
6 | */
7 | function maybeShowRequiredFieldsNotice () {
8 | msgRequiresFields.style.display = 'none'
9 | const listId = elSelectList.value
10 | const xhr = new XMLHttpRequest()
11 | xhr.open('GET', window.ajaxurl + '?action=mc4wp_get_list_details&ids=' + listId, true)
12 | xhr.onload = function () {
13 | if (this.status >= 400) {
14 | console.error('Error retrieving list details')
15 | return
16 | }
17 | const lists = JSON.parse(this.responseText)
18 | // iterate over selected lists
19 | for (let i = 0; i < lists.length; i++) {
20 | const list = lists[i]
21 |
22 | // iterate over list fields
23 | for (let j = 0; j < list.merge_fields.length; j++) {
24 | const field = list.merge_fields[j]
25 |
26 | // if field other than EMAIL is required, show notice and stop loop
27 | if (field.tag !== 'EMAIL' && field.required) {
28 | msgRequiresFields.style.display = ''
29 | return
30 | }
31 | }
32 | }
33 | }
34 | xhr.send(null)
35 | }
36 |
37 | // init colorpickers
38 | window.jQuery('.mc4wp-color').wpColorPicker()
39 |
40 | // if a list changes, check which fields are required
41 | elSelectList.addEventListener('change', maybeShowRequiredFieldsNotice)
42 |
43 | // check right away
44 | maybeShowRequiredFieldsNotice()
45 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | MC4WP: Mailchimp Top Bar
2 | ==============
3 |
4 | Adds a beautiful and customizable Mailchimp opt-in bar to the top of your WordPress site.
5 |
6 | Requirements
7 | ------------
8 |
9 | - WordPress version 4.9 or later
10 | - PHP version 7.3 or later
11 |
12 |
13 | Installation
14 | ------------
15 |
16 | If you just want to install this plugin on your WordPress site, please download and install the latest version from WordPress.org: [Mailchimp Top Bar plugin on WordPress.org](https://wordpress.org/plugins/mailchimp-top-bar/installation/).
17 |
18 | To install the development version, take the following steps:
19 |
20 | 1. Clone the GitHub repository:
21 |
22 | ```
23 | git clone https://github.com/ibericode/mailchimp-top-bar.git
24 | ```
25 |
26 | 2. Install NPM dependencies:
27 |
28 | ```
29 | npm install
30 | ```
31 |
32 | 3. Generate plugin asset files:
33 |
34 | ```
35 | npm run build
36 | ```
37 |
38 | 5. Activate the plugin in your WordPress admin.
39 |
40 | Bugs
41 | ----
42 | If you think you've found a bug, [please open an issue here](https://github.com/ibericode/mailchimp-top-bar/issues?state=open)!
43 |
44 | Support
45 | -------
46 | This is a developer's portal for the Mailchimp Top Bar plugin and should not be used for support. Please visit the
47 | [Mailchimp Top Bar support forum on WordPress.org](https://wordpress.org/support/plugin/mailchimp-top-bar).
48 |
49 | If you need priority support, please purchase a [Mailchimp for WordPress Premium](https://www.mc4wp.com/) plugin license.
50 |
51 | License
52 | -------
53 | GPLv3 or later
54 |
--------------------------------------------------------------------------------
/src/functions.php:
--------------------------------------------------------------------------------
1 | '',
12 | 'enabled' => 1,
13 | 'show_to_administrators' => 1,
14 | 'cookie_length' => 365,
15 | 'color_bar' => '#ffcc00',
16 | 'color_text' => '#222222',
17 | 'color_button' => '#222222',
18 | 'color_button_text' => '#ffffff',
19 | 'disable_after_use' => 1,
20 | 'size' => 'medium',
21 | 'sticky' => 1,
22 | 'text_email_placeholder' => __('Your email address..', 'mailchimp-top-bar'),
23 | 'text_bar' => __('Sign-up now - don\'t miss the fun!', 'mailchimp-top-bar'),
24 | 'text_button' => __('Subscribe', 'mailchimp-top-bar'),
25 | 'redirect' => '',
26 | 'position' => 'top',
27 | 'double_optin' => 1,
28 | 'send_welcome' => 0,
29 | 'update_existing' => 0,
30 | 'text_subscribed' => __("Thanks, you're in! Please check your email inbox for a confirmation.", 'mailchimp-top-bar'),
31 | 'text_error' => __("Oops. Something went wrong.", 'mailchimp-top-bar'),
32 | 'text_invalid_email' => __('That email seems to be invalid.', 'mailchimp-top-bar'),
33 | 'text_already_subscribed' => __("You are already subscribed. Thank you!", 'mailchimp-top-bar'),
34 | 'disable_on_pages' => '',
35 | ];
36 |
37 | $options = (array) get_option('mailchimp_top_bar', []);
38 | $options = array_merge($defaults, $options);
39 |
40 | // for BC with MailChimp Top Bar v1.2.3, always fill text option keys
41 | $text_keys = [
42 | 'text_subscribed',
43 | 'text_error',
44 | 'text_invalid_email',
45 | 'text_already_subscribed'
46 | ];
47 |
48 | foreach ($text_keys as $text_key) {
49 | if (empty($options[ $text_key ]) && ! empty($defaults[ $text_key ])) {
50 | $options[ $text_key ] = $defaults[ $text_key ];
51 | }
52 | }
53 |
54 | return $options;
55 | }
56 |
--------------------------------------------------------------------------------
/mailchimp-top-bar.php:
--------------------------------------------------------------------------------
1 | .
30 | */
31 |
32 |
33 | defined('ABSPATH') or exit;
34 |
35 | add_action('plugins_loaded', function () {
36 | // check for PHP 7.3 or higher
37 | if (PHP_VERSION_ID < 70300) {
38 | return;
39 | }
40 |
41 | // check for MailChimp for WordPress (version 3.0 or higher)
42 | if (!defined('MC4WP_VERSION') || version_compare(MC4WP_VERSION, '3.0', '<')) {
43 | require __DIR__ . '/src/admin-notice-install-deps.php';
44 | return;
45 | }
46 |
47 |
48 | define('MAILCHIMP_TOP_BAR_FILE', __FILE__);
49 | define('MAILCHIMP_TOP_BAR_DIR', __DIR__);
50 | define('MAILCHIMP_TOP_BAR_VERSION', '1.7.3');
51 |
52 | require __DIR__ . '/src/functions.php';
53 |
54 | if (is_admin()) {
55 | require __DIR__ . '/src/Admin.php';
56 | $admin = new Mailchimp\TopBar\Admin();
57 | $admin->add_hooks();
58 | } else {
59 | require __DIR__ . '/src/Bar.php';
60 | $bar = new MailChimp\TopBar\Bar();
61 | add_action('wp', [$bar, 'init']);
62 | }
63 | }, 30);
64 |
--------------------------------------------------------------------------------
/assets/src/js/loader.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @param {HTMLElement} button
3 | */
4 | function getButtonText (button) {
5 | return button.innerHTML ? button.innerHTML : button.value
6 | }
7 |
8 | /**
9 | * @param {HTMLElement} button
10 | * @param {string} text
11 | */
12 | function setButtonText (button, text) {
13 | button.innerHTML ? button.innerHTML = text : button.value = text
14 | }
15 |
16 | /**
17 | * @param {HTMLFormElement} formElement
18 | */
19 | function Loader (formElement) {
20 | this.form = formElement
21 | this.button = formElement.querySelector('input[type="submit"],button[type="submit"]')
22 | this.char = '\u00B7'
23 |
24 | if (this.button) {
25 | this.originalButton = this.button.cloneNode(true)
26 | }
27 |
28 | this.start()
29 | }
30 |
31 | /**
32 | * @param {string} c
33 | */
34 | Loader.prototype.setCharacter = function (c) {
35 | this.char = c
36 | }
37 |
38 | /**
39 | * Start the loading indicator
40 | */
41 | Loader.prototype.start = function () {
42 | if (this.button) {
43 | // loading text
44 | const loadingText = this.button.getAttribute('data-loading-text')
45 | if (loadingText) {
46 | setButtonText(this.button, loadingText)
47 | return
48 | }
49 |
50 | // Show AJAX loader
51 | const styles = window.getComputedStyle(this.button)
52 | this.button.style.width = styles.width
53 | setButtonText(this.button, this.char)
54 | this.loadingInterval = window.setInterval(this.tick.bind(this), 500)
55 | } else {
56 | this.form.style.opacity = '0.5'
57 | }
58 | }
59 |
60 | /**
61 | * Single step in the loading indicator's "animation"
62 | */
63 | Loader.prototype.tick = function () {
64 | // count chars, start over at 5
65 | const text = getButtonText(this.button)
66 | const loadingChar = this.char
67 | setButtonText(this.button, text.length >= 5 ? loadingChar : text + ' ' + loadingChar)
68 | }
69 |
70 | /**
71 | * Stops the loading indicator
72 | */
73 | Loader.prototype.stop = function () {
74 | if (this.button) {
75 | this.button.style.width = this.originalButton.style.width
76 | const text = getButtonText(this.originalButton)
77 | setButtonText(this.button, text)
78 | window.clearInterval(this.loadingInterval)
79 | } else {
80 | this.form.style.opacity = ''
81 | }
82 | }
83 |
84 | export default Loader
85 |
--------------------------------------------------------------------------------
/create-version.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -euo pipefail
4 |
5 | # Check if VERSION argument was supplied
6 | if [ "$#" -lt 1 ]; then
7 | echo "1 parameters expected, $# found"
8 | echo "Usage: package.sh