Skip to content

Commit c50e774

Browse files
authored
Merge pull request #269 from Kit/add-meta-key-property
Add `meta_key` property to Coupons and Products
2 parents 5998160 + adc6167 commit c50e774

15 files changed

Lines changed: 377 additions & 8 deletions

admin/class-ckwc-admin-coupon.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,13 @@ class CKWC_Admin_Coupon extends CKWC_Admin_Post_Type {
2424
*/
2525
public $post_type = 'shop_coupon';
2626

27+
/**
28+
* The Meta Key to store the settings for the Post Type.
29+
*
30+
* @since 2.1.0
31+
*
32+
* @var string
33+
*/
34+
public $meta_key = 'ckwc_subscription';
35+
2736
}

admin/class-ckwc-admin-order.php

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
<?php
2+
/**
3+
* ConvertKit Admin Order class.
4+
*
5+
* @package CKWC
6+
* @author ConvertKit
7+
*/
8+
9+
/**
10+
* Registers a metabox on WooCommerce Orders and saves its settings when the
11+
* Order is saved in the WordPress Administration interface.
12+
*
13+
* @package CKWC
14+
* @author ConvertKit
15+
*/
16+
class CKWC_Admin_Order extends CKWC_Admin_Post_Type {
17+
18+
/**
19+
* The Post Type to register the metabox and settings against.
20+
*
21+
* @since 2.1.0
22+
*
23+
* @var string
24+
*/
25+
public $post_type = 'woocommerce_page_wc-orders';
26+
27+
/**
28+
* The Meta Key to store the settings for the Post Type.
29+
*
30+
* @since 2.1.0
31+
*
32+
* @var string
33+
*/
34+
public $meta_key = 'ckwc_opt_in';
35+
36+
/**
37+
* Constructor
38+
*
39+
* @since 2.1.0
40+
*/
41+
public function __construct() {
42+
43+
// Orders uses a different hook for saving.
44+
add_action( 'woocommerce_process_shop_order_meta', array( $this, 'save' ) );
45+
46+
// Call parent constructor.
47+
parent::__construct();
48+
49+
}
50+
51+
/**
52+
* Displays a meta box on WooCommerce Order screen.
53+
*
54+
* @since 2.1.0
55+
*
56+
* @param WC_Order $order Order.
57+
*/
58+
public function display_meta_box( $order ) {
59+
60+
// Get order meta.
61+
$opt_in = $order->get_meta( 'ckwc_opt_in', true ) === 'yes' ? true : false;
62+
$opted_in = $order->get_meta( 'ckwc_opted_in', true ) === 'yes' ? true : false;
63+
64+
// Load meta box view.
65+
require_once CKWC_PLUGIN_PATH . '/views/backend/post-type/order-meta-box.php';
66+
67+
}
68+
69+
/**
70+
* Saves the opt in setting for the WooCommerce Order.
71+
*
72+
* @since 2.1.0
73+
*
74+
* @param int $order_id Order ID.
75+
*/
76+
public function save( $order_id ) {
77+
78+
// Bail if no nonce field exists.
79+
if ( ! isset( $_POST['ckwc_nonce'] ) ) {
80+
return;
81+
}
82+
83+
// Bail if the nonce verification fails.
84+
if ( ! wp_verify_nonce( sanitize_key( wp_unslash( $_POST['ckwc_nonce'] ) ), 'ckwc' ) ) {
85+
return;
86+
}
87+
88+
// Bail if no opt in value exists.
89+
if ( ! isset( $_POST['ckwc_opt_in'] ) ) {
90+
return;
91+
}
92+
93+
// Get order.
94+
$order = wc_get_order( $order_id );
95+
96+
// Get opt in value.
97+
$ckwc_opt_in = ( $_POST['ckwc_opt_in'] === 'yes' ? 'yes' : '' );
98+
99+
// Update metadata.
100+
$order->update_meta_data( $this->meta_key, $ckwc_opt_in );
101+
$order->save();
102+
103+
}
104+
105+
}

admin/class-ckwc-admin-post-type.php

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,15 @@ class CKWC_Admin_Post_Type {
2626
*/
2727
public $post_type = '';
2828

29+
/**
30+
* The Meta Key to store the settings for the Post Type.
31+
*
32+
* @since 2.1.0
33+
*
34+
* @var string
35+
*/
36+
public $meta_key = '';
37+
2938
/**
3039
* Holds the WooCommerce Integration instance for this Plugin.
3140
*
@@ -110,7 +119,7 @@ public function add_meta_boxes() {
110119
*
111120
* @since 1.0.0
112121
*
113-
* @param WP_Post $post Post Type (e.g. Product, Coupon).
122+
* @param WC_Order|WP_Post $post Post Type (e.g. Product, Coupon).
114123
*/
115124
public function display_meta_box( $post ) {
116125

@@ -128,17 +137,17 @@ public function display_meta_box( $post ) {
128137

129138
// Get current subscription setting and other settings to render the subscription dropdown field.
130139
$subscription = array(
131-
'id' => 'ckwc_subscription',
140+
'id' => $this->meta_key,
132141
'class' => 'ckwc-select2 widefat',
133-
'name' => 'ckwc_subscription',
134-
'value' => get_post_meta( $post->ID, 'ckwc_subscription', true ),
142+
'name' => $this->meta_key,
143+
'value' => get_post_meta( $post->ID, $this->meta_key, true ),
135144
'forms' => $forms,
136145
'tags' => $tags,
137146
'sequences' => $sequences,
138147
);
139148

140149
// Load meta box view.
141-
require_once CKWC_PLUGIN_PATH . '/views/backend/post-type/meta-box.php';
150+
require_once CKWC_PLUGIN_PATH . '/views/backend/post-type/' . str_replace( '_', '-', $post->post_type ) . '-meta-box.php';
142151

143152
}
144153

@@ -178,12 +187,12 @@ public function save( $post_id ) {
178187
}
179188

180189
// Bail if no Form / Tag option exists in POST data.
181-
if ( ! isset( $_POST['ckwc_subscription'] ) ) {
190+
if ( ! isset( $_POST[ $this->meta_key ] ) ) {
182191
return;
183192
}
184193

185194
// Save Post's settings.
186-
update_post_meta( $post_id, 'ckwc_subscription', sanitize_text_field( wp_unslash( $_POST['ckwc_subscription'] ) ) );
195+
update_post_meta( $post_id, $this->meta_key, sanitize_text_field( wp_unslash( $_POST[ $this->meta_key ] ) ) );
187196

188197
}
189198

admin/class-ckwc-admin-product.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,13 @@ class CKWC_Admin_Product extends CKWC_Admin_Post_Type {
2424
*/
2525
public $post_type = 'product';
2626

27+
/**
28+
* The Meta Key to store the settings for the Post Type.
29+
*
30+
* @since 2.1.0
31+
*
32+
* @var string
33+
*/
34+
public $meta_key = 'ckwc_subscription';
35+
2736
}

includes/class-ckwc-order.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ public function __construct() {
7272
}
7373

7474
// Subscribe customer's email address to a form, tag or sequence.
75+
add_action( 'woocommerce_process_shop_order_meta', array( $this, 'maybe_subscribe_customer' ), 99999, 1 );
7576
add_action( 'woocommerce_checkout_update_order_meta', array( $this, 'maybe_subscribe_customer' ), 99999, 1 );
7677
add_action( 'woocommerce_order_status_changed', array( $this, 'maybe_subscribe_customer' ), 99999, 3 );
7778

includes/class-wp-ckwc.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ private function initialize_admin() {
157157

158158
$this->classes['admin_bulk_edit'] = new CKWC_Admin_Bulk_Edit();
159159
$this->classes['admin_coupon'] = new CKWC_Admin_Coupon();
160+
$this->classes['admin_order'] = new CKWC_Admin_Order();
160161
$this->classes['admin_plugin'] = new CKWC_Admin_Plugin();
161162
$this->classes['admin_product'] = new CKWC_Admin_Product();
162163
$this->classes['admin_quick_edit'] = new CKWC_Admin_Quick_Edit();

tests/EndToEnd/subscribe/order-completed/SubscribeOnOrderCompletedEventCest.php

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -491,6 +491,60 @@ public function testOptInDisabledWithNoFormAndSimpleProduct(EndToEndTester $I)
491491
$I->apiCheckSubscriberDoesNotExist($I, $result['email_address']);
492492
}
493493

494+
/**
495+
* Test that the Customer is subscribed to Kit with the Form defined in the Plugin settings
496+
* and the Sequence defined in the Product when a manual order is created, its status is set to completed,
497+
* and the opt in setting is enabled.
498+
*
499+
* @since 2.1.0
500+
*
501+
* @param EndToEndTester $I Tester.
502+
*/
503+
public function testOptInWithManualOrder(EndToEndTester $I)
504+
{
505+
// Enable Integration and define its Access and Refresh Tokens.
506+
$I->setupConvertKitPlugin(
507+
$I,
508+
subscriptionEvent: 'completed',
509+
subscription: 'form:' . $_ENV['CONVERTKIT_API_FORM_ID'],
510+
);
511+
512+
// Create Product.
513+
$productID = $I->wooCommerceCreateSimpleProduct($I, 'course:' . $_ENV['CONVERTKIT_API_SEQUENCE_ID']);
514+
515+
// Create Manual Order.
516+
$result = $I->wooCommerceCreateManualOrder(
517+
$I,
518+
productID: $productID,
519+
productName: 'Simple Product',
520+
orderStatus: 'wc-completed',
521+
optIn: true,
522+
);
523+
524+
// Confirm that the email address was now added to Kit.
525+
$subscriber = $I->apiCheckSubscriberExists(
526+
$I,
527+
emailAddress: $result['email_address'],
528+
);
529+
530+
// Unsubscribe the email address, so we restore the account back to its previous state.
531+
$I->apiUnsubscribe($subscriber['id']);
532+
533+
// Check that the Order's Notes include a note from the Plugin confirming the Customer was subscribed to the Form.
534+
$I->wooCommerceOrderNoteExists(
535+
$I,
536+
orderID: $result['order_id'],
537+
noteText: 'Customer subscribed to the Form: ' . $_ENV['CONVERTKIT_API_FORM_NAME'] . ' [' . $_ENV['CONVERTKIT_API_FORM_ID'] . ']'
538+
);
539+
540+
// Check that the Order's Notes include a note from the Plugin confirming the Customer was subscribed to the Sequence.
541+
$I->wooCommerceOrderNoteExists(
542+
$I,
543+
orderID: $result['order_id'],
544+
noteText: 'Customer subscribed to the Sequence: ' . $_ENV['CONVERTKIT_API_SEQUENCE_NAME'] . ' [' . $_ENV['CONVERTKIT_API_SEQUENCE_ID'] . ']'
545+
);
546+
}
547+
494548
/**
495549
* Deactivate and reset Plugin(s) after each test, if the test passes.
496550
* We don't use _after, as this would provide a screenshot of the Plugin

tests/EndToEnd/subscribe/order-pending-payment/SubscribeOnOrderPendingPaymentEventCest.php

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,60 @@ public function testOptInDisabledWithNoFormAndSimpleProduct(EndToEndTester $I)
407407
$I->apiCheckSubscriberDoesNotExist($I, $result['email_address']);
408408
}
409409

410+
/**
411+
* Test that the Customer is subscribed to Kit with the Form defined in the Plugin settings
412+
* and the Sequence defined in the Product when a manual order is created, its status is set to pending payment,
413+
* and the opt in setting is enabled.
414+
*
415+
* @since 2.1.0
416+
*
417+
* @param EndToEndTester $I Tester.
418+
*/
419+
public function testOptInWithManualOrder(EndToEndTester $I)
420+
{
421+
// Enable Integration and define its Access and Refresh Tokens.
422+
$I->setupConvertKitPlugin(
423+
$I,
424+
subscriptionEvent: 'pending',
425+
subscription: 'form:' . $_ENV['CONVERTKIT_API_FORM_ID'],
426+
);
427+
428+
// Create Product.
429+
$productID = $I->wooCommerceCreateSimpleProduct($I, 'course:' . $_ENV['CONVERTKIT_API_SEQUENCE_ID']);
430+
431+
// Create Manual Order.
432+
$result = $I->wooCommerceCreateManualOrder(
433+
$I,
434+
productID: $productID,
435+
productName: 'Simple Product',
436+
orderStatus: 'wc-pending',
437+
optIn: true,
438+
);
439+
440+
// Confirm that the email address was now added to Kit.
441+
$subscriber = $I->apiCheckSubscriberExists(
442+
$I,
443+
emailAddress: $result['email_address'],
444+
);
445+
446+
// Unsubscribe the email address, so we restore the account back to its previous state.
447+
$I->apiUnsubscribe($subscriber['id']);
448+
449+
// Check that the Order's Notes include a note from the Plugin confirming the Customer was subscribed to the Form.
450+
$I->wooCommerceOrderNoteExists(
451+
$I,
452+
orderID: $result['order_id'],
453+
noteText: 'Customer subscribed to the Form: ' . $_ENV['CONVERTKIT_API_FORM_NAME'] . ' [' . $_ENV['CONVERTKIT_API_FORM_ID'] . ']'
454+
);
455+
456+
// Check that the Order's Notes include a note from the Plugin confirming the Customer was subscribed to the Sequence.
457+
$I->wooCommerceOrderNoteExists(
458+
$I,
459+
orderID: $result['order_id'],
460+
noteText: 'Customer subscribed to the Sequence: ' . $_ENV['CONVERTKIT_API_SEQUENCE_NAME'] . ' [' . $_ENV['CONVERTKIT_API_SEQUENCE_ID'] . ']'
461+
);
462+
}
463+
410464
/**
411465
* Deactivate and reset Plugin(s) after each test, if the test passes.
412466
* We don't use _after, as this would provide a screenshot of the Plugin

tests/EndToEnd/subscribe/order-processing/SubscribeOnOrderProcessingEventCest.php

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -835,6 +835,60 @@ public function testCustomerIsNotResubscribedWhenOrderStatusChanges(EndToEndTest
835835
$I->apiCheckSubscriberDoesNotExist($I, $result['email_address']);
836836
}
837837

838+
/**
839+
* Test that the Customer is subscribed to Kit with the Form defined in the Plugin settings
840+
* and the Sequence defined in the Product when a manual order is created, its status is set to processing,
841+
* and the opt in setting is enabled.
842+
*
843+
* @since 2.1.0
844+
*
845+
* @param EndToEndTester $I Tester.
846+
*/
847+
public function testOptInWithManualOrder(EndToEndTester $I)
848+
{
849+
// Enable Integration and define its Access and Refresh Tokens.
850+
$I->setupConvertKitPlugin(
851+
$I,
852+
subscriptionEvent: 'processing',
853+
subscription: 'form:' . $_ENV['CONVERTKIT_API_FORM_ID'],
854+
);
855+
856+
// Create Product.
857+
$productID = $I->wooCommerceCreateSimpleProduct($I, 'course:' . $_ENV['CONVERTKIT_API_SEQUENCE_ID']);
858+
859+
// Create Manual Order.
860+
$result = $I->wooCommerceCreateManualOrder(
861+
$I,
862+
productID: $productID,
863+
productName: 'Simple Product',
864+
orderStatus: 'wc-processing',
865+
optIn: true,
866+
);
867+
868+
// Confirm that the email address was now added to Kit.
869+
$subscriber = $I->apiCheckSubscriberExists(
870+
$I,
871+
emailAddress: $result['email_address'],
872+
);
873+
874+
// Unsubscribe the email address, so we restore the account back to its previous state.
875+
$I->apiUnsubscribe($subscriber['id']);
876+
877+
// Check that the Order's Notes include a note from the Plugin confirming the Customer was subscribed to the Form.
878+
$I->wooCommerceOrderNoteExists(
879+
$I,
880+
orderID: $result['order_id'],
881+
noteText: 'Customer subscribed to the Form: ' . $_ENV['CONVERTKIT_API_FORM_NAME'] . ' [' . $_ENV['CONVERTKIT_API_FORM_ID'] . ']'
882+
);
883+
884+
// Check that the Order's Notes include a note from the Plugin confirming the Customer was subscribed to the Sequence.
885+
$I->wooCommerceOrderNoteExists(
886+
$I,
887+
orderID: $result['order_id'],
888+
noteText: 'Customer subscribed to the Sequence: ' . $_ENV['CONVERTKIT_API_SEQUENCE_NAME'] . ' [' . $_ENV['CONVERTKIT_API_SEQUENCE_ID'] . ']'
889+
);
890+
}
891+
838892
/**
839893
* Deactivate and reset Plugin(s) after each test, if the test passes.
840894
* We don't use _after, as this would provide a screenshot of the Plugin

0 commit comments

Comments
 (0)