Skip to content

Commit dd0c828

Browse files
committed
Initial oAuth connect implementation.
1 parent 6b0f662 commit dd0c828

File tree

5 files changed

+272
-0
lines changed

5 files changed

+272
-0
lines changed

css/admin.css

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,3 +254,11 @@ th.mailchimp-connect {
254254
#mc-message {
255255
margin-top: 26px;
256256
}
257+
258+
/**
259+
* Mailchimp OAuth CSS
260+
*/
261+
.mailchimp-sf-oauth-section .oauth-error {
262+
display: block;
263+
color: #db3a1b;
264+
}

includes/mailchimp-admin.php

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
<?php
2+
/**
3+
* Admin functions for Mailchimp
4+
*
5+
* @package Mailchimp
6+
*/
7+
8+
/**
9+
* Admin functions for Mailchimp
10+
*/
11+
class MailChimp_Admin {
12+
13+
/**
14+
* The OAuth base endpoint
15+
*
16+
* @var string
17+
*/
18+
private $oauth_url = 'https://woocommerce.mailchimpapp.com';
19+
20+
/**
21+
* Initialize the class
22+
*/
23+
public function init() {
24+
add_action( 'wp_ajax_mailchimp_sf_oauth_start', array( $this, 'start_oauth_process' ) );
25+
add_action( 'wp_ajax_mailchimp_sf_oauth_finish', array( $this, 'finish_oauth_process' ) );
26+
}
27+
28+
29+
/**
30+
* Start the OAuth process.
31+
* This function is called via AJAX.
32+
* It start the OAuth process by the calling the oAuth middleware server and responding the response to the front-end.
33+
*/
34+
public function start_oauth_process() {
35+
// Validate the nonce and permissions.
36+
if (
37+
! current_user_can( 'manage_options' ) ||
38+
! isset( $_POST['nonce'] ) ||
39+
! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce'] ) ), 'mailchimp_sf_oauth_start_nonce' )
40+
) {
41+
wp_send_json_error( array( 'message' => esc_html__( 'You do not have permission to perform this action.', 'mailchimp' ) ) );
42+
}
43+
44+
// Generate a secret and send it to the OAuth server.
45+
$secret = uniqid( 'mailchimp_sf_' );
46+
$args = array(
47+
'domain' => site_url(),
48+
'secret' => $secret,
49+
);
50+
51+
$options = array(
52+
'headers' => array(
53+
'Content-type' => 'application/json',
54+
),
55+
'body' => wp_json_encode( $args ),
56+
);
57+
58+
$response = wp_remote_post( $this->oauth_url . '/api/start', $options );
59+
60+
// Check for errors.
61+
if ( $response instanceof WP_Error ) {
62+
wp_send_json_error( $response );
63+
}
64+
65+
// Send the response to the front-end.
66+
if ( 201 === $response['response']['code'] && ! empty( $response['body'] ) ) {
67+
set_site_transient( 'mailchimp_sf_oauth_secret', $secret, 60 * 60 );
68+
$result = json_decode( $response['body'], true );
69+
wp_send_json_success( $result );
70+
} else {
71+
if ( ! empty( $response['response'] ) ) {
72+
$response = $response['response'];
73+
}
74+
wp_send_json_error( $response );
75+
}
76+
}
77+
78+
/**
79+
* Finish the OAuth process.
80+
* This function is called via AJAX.
81+
* This function finishes the OAuth process by the sending temporary token back to the oAuth server.
82+
*/
83+
public function finish_oauth_process() {
84+
// Validate the nonce and permissions.
85+
if (
86+
! current_user_can( 'manage_options' ) ||
87+
! isset( $_POST['nonce'] ) ||
88+
! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce'] ) ), 'mailchimp_sf_oauth_finish_nonce' )
89+
) {
90+
wp_send_json_error( array( 'message' => esc_html__( 'You do not have permission to perform this action.', 'mailchimp' ) ) );
91+
}
92+
93+
$token = isset( $_POST['token'] ) ? sanitize_text_field( wp_unslash( $_POST['token'] ) ) : '';
94+
$args = array(
95+
'domain' => site_url(),
96+
'secret' => get_site_transient( 'mailchimp_sf_oauth_secret' ),
97+
'token' => $token,
98+
);
99+
100+
$options = array(
101+
'headers' => array(
102+
'Content-type' => 'application/json',
103+
),
104+
'body' => wp_json_encode( $args ),
105+
);
106+
$response = wp_remote_post( $this->oauth_url . '/api/finish', $options );
107+
108+
// Check for errors.
109+
if ( $response instanceof WP_Error ) {
110+
wp_send_json_error( $response );
111+
}
112+
113+
if ( 200 === $response['response']['code'] ) {
114+
delete_option( 'mc_api_key' );
115+
delete_option( 'mailchimp_sf_access_token' );
116+
delete_option( 'mailchimp_sf_data_center' );
117+
118+
delete_site_transient( 'mailchimp_sf_oauth_secret' );
119+
120+
// Save the access token and data center.
121+
$result = json_decode( $response['body'], true );
122+
if ( $result && ! empty( $result['access_token'] ) && ! empty( $result['data_center'] ) ) {
123+
update_option( 'mailchimp_sf_data_center', $result['data_center'] );
124+
update_option( 'mailchimp_sf_access_token', $result['access_token'] );
125+
126+
wp_send_json_success( true );
127+
} else {
128+
wp_send_json_error( array( 'message' => esc_html__( 'Invalid response from the server.', 'mailchimp' ) ) );
129+
}
130+
} else {
131+
wp_send_json_error( $response );
132+
}
133+
}
134+
}

js/admin.js

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
/* eslint-disable no-console */
2+
(function ($) {
3+
const params = window.mailchimp_sf_admin_params || {};
4+
const oauthBaseUrl = 'https://woocommerce.mailchimpapp.com';
5+
6+
/**
7+
* Open Mailchimp OAuth popup.
8+
*
9+
* @param {string} token - Token from the Oauth service.
10+
*/
11+
function openMailChimpOauthPopup(token) {
12+
const startUrl = `${oauthBaseUrl}/auth/start/${token}`;
13+
const width = 800;
14+
const height = 600;
15+
const screenSizes = window.screen || { width: 1024, height: 768 };
16+
const left = (screenSizes.width - width) / 2;
17+
const top = (screenSizes.height - height) / 4;
18+
const windowOptions = `toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=no, copyhistory=no, width=${
19+
width
20+
}, height=${height}, top=${top}, left=${left}, domain=${oauthBaseUrl.replace('https://', '')}`;
21+
22+
// Open Mailchimp OAuth popup.
23+
const popup = window.open(startUrl, params.oauth_window_name, windowOptions);
24+
25+
if (popup == null) {
26+
// TODO: Handle popup blocked.
27+
console.error('Popup blocked. Please enable popups for this site.');
28+
} else {
29+
// Handle popup opened.
30+
const oauthInterval = window.setInterval(function () {
31+
if (popup.closed) {
32+
// Clear interval.
33+
window.clearInterval(oauthInterval);
34+
// TODO: Hide/show error/loading messages.
35+
36+
// Check status of OAuth connection.
37+
$.post(`${oauthBaseUrl}/api/status/${token}`, function (statusData) {
38+
if (statusData && statusData.status === 'accepted') {
39+
const finishData = {
40+
action: 'mailchimp_sf_oauth_finish',
41+
nonce: params.oauth_finish_nonce,
42+
token,
43+
};
44+
45+
// Finish OAuth connection and save token.
46+
$.post(params.ajax_url, finishData, function (finishResponse) {
47+
if (finishResponse.success) {
48+
// Token is saved in the database, reload the page to reflect the changes.
49+
window.location.reload();
50+
} else {
51+
console.log(
52+
'Error calling OAuth finish endpoint. Data:',
53+
finishResponse,
54+
);
55+
}
56+
}).fail(function () {
57+
console.error('Error calling OAuth finish endpoint.');
58+
});
59+
} else {
60+
console.log(
61+
'Error calling OAuth status endpoint. No credentials provided at login popup? Data:',
62+
statusData,
63+
);
64+
}
65+
}).fail(function () {
66+
console.error('Error calling OAuth status endpoint.');
67+
});
68+
}
69+
}, 250);
70+
}
71+
}
72+
73+
$(window).on('load', function () {
74+
// Mailchimp OAuth connection.
75+
$('#mailchimp_sf_oauth_connect').click(function () {
76+
$('.mailchimp-sf-oauth-section .oauth-error').html('');
77+
$.post(
78+
params.ajax_url,
79+
{
80+
action: 'mailchimp_sf_oauth_start',
81+
nonce: params.oauth_start_nonce,
82+
},
83+
function (response) {
84+
if (response.success && response.data && response.data.token) {
85+
// Open Mailchimp OAuth popup.
86+
openMailChimpOauthPopup(response.data.token);
87+
} else {
88+
// eslint-disable-next-line no-console
89+
console.error(response.data);
90+
if (response.data && response.data.message) {
91+
$('.mailchimp-sf-oauth-section .oauth-error').html(
92+
response.data.message,
93+
);
94+
} else {
95+
$('.mailchimp-sf-oauth-section .oauth-error').html(
96+
'An error occurred. Please try again.',
97+
);
98+
}
99+
}
100+
},
101+
).fail(function () {
102+
$('.mailchimp-sf-oauth-section .oauth-error').html(
103+
'An error occurred. Please try again.',
104+
);
105+
});
106+
});
107+
});
108+
})(jQuery);

mailchimp.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,11 @@
5858
// Upgrade routines.
5959
require_once 'mailchimp_upgrade.php';
6060

61+
// Init Admin functions
62+
require_once plugin_dir_path( __FILE__ ) . 'includes/mailchimp-admin.php';
63+
$admin = new MailChimp_Admin();
64+
$admin->init();
65+
6166
/**
6267
* Do the following plugin setup steps here
6368
*
@@ -146,6 +151,18 @@ function mailchimp_admin_page_scripts( $hook_suffix ) {
146151

147152
wp_enqueue_style( 'mailchimp_sf_admin_css', MCSF_URL . 'css/admin.css', array(), true );
148153
wp_enqueue_script( 'showMe', MCSF_URL . 'js/hidecss.js', array( 'jquery' ), MCSF_VER, true );
154+
wp_enqueue_script( 'mailchimp_sf_admin', MCSF_URL . 'js/admin.js', array( 'jquery' ), MCSF_VER, true );
155+
156+
wp_localize_script(
157+
'mailchimp_sf_admin',
158+
'mailchimp_sf_admin_params',
159+
array(
160+
'ajax_url' => esc_url( admin_url( 'admin-ajax.php' ) ),
161+
'oauth_start_nonce' => wp_create_nonce( 'mailchimp_sf_oauth_start_nonce' ),
162+
'oauth_finish_nonce' => wp_create_nonce( 'mailchimp_sf_oauth_finish_nonce' ),
163+
'oauth_window_name' => esc_html__( 'Mailchimp For WordPress OAuth', 'mailchimp' ),
164+
)
165+
);
149166
}
150167

151168
add_action( 'admin_enqueue_scripts', 'mailchimp_admin_page_scripts', 10, 1 );

views/setup_page.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,11 @@
7575
</tr>
7676
</form>
7777
</table>
78+
<div class="mailchimp-sf-oauth-section">
79+
<!-- TODO: Update design and content here -->
80+
<button class="button" id="mailchimp_sf_oauth_connect" href="#"><?php esc_html_e( 'Connect Account', 'mailchimp' ); ?></button>
81+
<p><span class="oauth-error"></span></p>
82+
</div>
7883
</div>
7984
</div>
8085

0 commit comments

Comments
 (0)