Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 0 additions & 75 deletions includes/class-convertkit-ajax.php

This file was deleted.

61 changes: 59 additions & 2 deletions includes/class-convertkit-output.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ class ConvertKit_Output {
*/
public function __construct() {

add_action( 'rest_api_init', array( $this, 'register_routes' ) );
add_action( 'init', array( $this, 'get_subscriber_id_from_request' ) );
add_action( 'wp', array( $this, 'maybe_tag_subscriber' ) );
add_action( 'template_redirect', array( $this, 'output_form' ) );
Expand All @@ -80,6 +81,62 @@ public function __construct() {

}

/**
* Register REST API routes.
*
* @since 3.1.7
*/
public function register_routes() {

// Register route to store the Kit subscriber's email's ID in a cookie.
register_rest_route(
'kit/v1',
'/subscriber/store-email-as-id-in-cookie',
array(
'methods' => WP_REST_Server::CREATABLE,
'args' => array(
// Email: Validate email is included in the request, a valid email address
// and sanitize the email address.
'email' => array(
'required' => true,
'validate_callback' => function ( $param ) {

return is_string( $param ) && is_email( $param );

},
'sanitize_callback' => 'sanitize_email',
),
),
'callback' => function ( $request ) {

// Get email address.
$email = $request->get_param( 'email' );

// Get subscriber ID.
$subscriber = new ConvertKit_Subscriber();
$subscriber_id = $subscriber->validate_and_store_subscriber_email( $email );

// Bail if an error occured i.e. API hasn't been configured.
if ( is_wp_error( $subscriber_id ) ) {
return rest_ensure_response( $subscriber_id );
}

// Return the subscriber ID.
return rest_ensure_response(
array(
'id' => $subscriber_id,
)
);

},

// No authentication required, as this is on the frontend site.
'permission_callback' => '__return_true',
)
);

}

/**
* Tags the subscriber, if:
* - a subscriber ID exists in the cookie or URL,
Expand Down Expand Up @@ -756,9 +813,9 @@ public function enqueue_scripts() {
'convertkit-js',
'convertkit',
array(
'ajaxurl' => admin_url( 'admin-ajax.php' ),
'ajaxurl' => rest_url( 'kit/v1/subscriber/store-email-as-id-in-cookie' ),
'debug' => $settings->debug_enabled(),
'nonce' => wp_create_nonce( 'convertkit' ),
'nonce' => wp_create_nonce( 'wp_rest' ),
'subscriber_id' => $this->subscriber_id,
)
);
Expand Down
1 change: 0 additions & 1 deletion includes/class-wp-convertkit.php
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,6 @@ private function initialize_global() {

$this->classes['admin_notices'] = new ConvertKit_Admin_Notices();
$this->classes['admin_refresh_resources'] = new ConvertKit_Admin_Refresh_Resources();
$this->classes['ajax'] = new ConvertKit_AJAX();
$this->classes['blocks_convertkit_broadcasts'] = new ConvertKit_Block_Broadcasts();
$this->classes['blocks_convertkit_content'] = new ConvertKit_Block_Content();
$this->classes['blocks_convertkit_formtrigger'] = new ConvertKit_Block_Form_Trigger();
Expand Down
5 changes: 2 additions & 3 deletions resources/frontend/js/convertkit.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,9 @@ function convertStoreSubscriberEmailAsIDInCookie(emailAddress) {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'X-WP-Nonce': convertkit.nonce,
},
body: new URLSearchParams({
action: 'convertkit_store_subscriber_email_as_id_in_cookie',
convertkit_nonce: convertkit.nonce,
email: emailAddress,
}),
})
Expand All @@ -50,7 +49,7 @@ function convertStoreSubscriberEmailAsIDInCookie(emailAddress) {

// Emit custom event with subscriber ID.
convertKitEmitCustomEvent('convertkit_user_subscribed', {
id: result.data.id,
id: result.id,
email: emailAddress,
});
})
Expand Down
116 changes: 116 additions & 0 deletions tests/Integration/RESTAPITest.php
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,122 @@ public function testRestrictContentSubscriberAuthenticationProductInvalidEmail()
$this->assertArrayHasKey( 'data', $data );
}

/**
* Test that the /wp-json/kit/v1/subscriber/store-email-as-id-in-cookie REST API route stores
* the subscriber ID in a cookie when a valid email address is given.
*
* @since 3.1.7
*/
public function testStoreEmailAsIDInCookie()
{
// Build request.
$request = new \WP_REST_Request( 'POST', '/kit/v1/subscriber/store-email-as-id-in-cookie' );
$request->set_header( 'Content-Type', 'application/json' );
$request->set_body_params(
[
'email' => $_ENV['CONVERTKIT_API_SUBSCRIBER_EMAIL'],
],
);

// Send request.
$response = rest_get_server()->dispatch( $request );

// Assert response is successful.
$this->assertSame( 200, $response->get_status() );

// Assert response data has the expected keys and data.
$data = $response->get_data();
$this->assertIsArray( $data );
$this->assertEquals( (int) $_ENV['CONVERTKIT_API_SUBSCRIBER_ID'], (int) $data['id'] );
}

/**
* Test that the /wp-json/kit/v1/subscriber/store-email-as-id-in-cookie REST API returns
* no subscriber ID when a non-subscriber email address is given.
*
* @since 3.1.7
*/
public function testStoreEmailAsIDInCookieWithNonSubscriberEmail()
{
// Build request.
$request = new \WP_REST_Request( 'POST', '/kit/v1/subscriber/store-email-as-id-in-cookie' );
$request->set_header( 'Content-Type', 'application/json' );
$request->set_body_params(
[
'email' => 'fail@kit.com',
],
);

// Send request.
$response = rest_get_server()->dispatch( $request );

// Assert response is successful.
$this->assertSame( 200, $response->get_status() );

// Assert response data has the expected keys and data.
$data = $response->get_data();
$this->assertIsArray( $data );
$this->assertEquals( 0, (int) $data['id'] );
}

/**
* Test that the /wp-json/kit/v1/subscriber/store-email-as-id-in-cookie REST API returns
* an error when no email address is given.
*
* @since 3.1.7
*/
public function testStoreEmailAsIDInCookieWithNoEmail()
{
// Build request.
$request = new \WP_REST_Request( 'POST', '/kit/v1/subscriber/store-email-as-id-in-cookie' );
$request->set_header( 'Content-Type', 'application/json' );
$request->set_body_params(
[
'email' => '',
],
);

// Send request.
$response = rest_get_server()->dispatch( $request );

// Assert response failed.
$this->assertSame( 400, $response->get_status() );

// Assert response data has the expected keys and data.
$data = $response->get_data();
$this->assertEquals( 'rest_invalid_param', $data['code'] );
$this->assertEquals( 'Invalid parameter(s): email', $data['message'] );
}

/**
* Test that the /wp-json/kit/v1/subscriber/store-email-as-id-in-cookie REST API returns
* an error when an invalid email address is given.
*
* @since 3.1.7
*/
public function testStoreEmailAsIDInCookieWithInvalidEmail()
{
// Build request.
$request = new \WP_REST_Request( 'POST', '/kit/v1/subscriber/store-email-as-id-in-cookie' );
$request->set_header( 'Content-Type', 'application/json' );
$request->set_body_params(
[
'email' => 'not-an-email',
],
);

// Send request.
$response = rest_get_server()->dispatch( $request );

// Assert response failed.
$this->assertSame( 400, $response->get_status() );

// Assert response data has the expected keys and data.
$data = $response->get_data();
$this->assertEquals( 'rest_invalid_param', $data['code'] );
$this->assertEquals( 'Invalid parameter(s): email', $data['message'] );
}

/**
* Act as an editor user.
*
Expand Down
1 change: 0 additions & 1 deletion wp-convertkit.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@
require_once CONVERTKIT_PLUGIN_PATH . '/includes/functions.php';
require_once CONVERTKIT_PLUGIN_PATH . '/includes/class-wp-convertkit.php';
require_once CONVERTKIT_PLUGIN_PATH . '/includes/class-convertkit-admin-notices.php';
require_once CONVERTKIT_PLUGIN_PATH . '/includes/class-convertkit-ajax.php';
require_once CONVERTKIT_PLUGIN_PATH . '/includes/class-convertkit-broadcasts-exporter.php';
require_once CONVERTKIT_PLUGIN_PATH . '/includes/class-convertkit-broadcasts-importer.php';
require_once CONVERTKIT_PLUGIN_PATH . '/includes/class-convertkit-cache-plugins.php';
Expand Down