Skip to content

Commit

Permalink
chore: add automatic confirmation cron
Browse files Browse the repository at this point in the history
  • Loading branch information
Soare-Robert-Daniel committed Aug 3, 2023
1 parent 65ade9d commit b5227a6
Show file tree
Hide file tree
Showing 5 changed files with 173 additions and 24 deletions.
3 changes: 3 additions & 0 deletions .fleet/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"toolchains": []
}
6 changes: 3 additions & 3 deletions inc/server/class-form-server.php
Original file line number Diff line number Diff line change
Expand Up @@ -186,9 +186,9 @@ public function register_routes() {
array(
array(
'methods' => WP_REST_Server::READABLE,
'callback' => array( $this, 'confirm_form' ),
'callback' => array( $this, 'confirm_form_submission'),
'permission_callback' => function ( $request ) {
$session = $request->get_param( 'stripe_session_id' );
$session = $request->get_param( 'stripe_checkout' );

if ( apply_filters( 'otter_form_session_confirmation', $session ) ) {
return __return_true();
Expand Down Expand Up @@ -331,7 +331,7 @@ public function frontend( $request ) {
* @param WP_REST_Request $request Form request.
* @return WP_Error|WP_HTTP_Response|WP_REST_Response
*/
public function confirm_form( $request ) {
public function confirm_form_submission( $request ) {

$response = new Form_Data_Response();

Expand Down
173 changes: 157 additions & 16 deletions plugins/otter-pro/inc/plugins/class-form-emails-storing.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,12 @@ public function init() {
add_action( 'save_post', array( $this, 'form_record_save_meta_box' ), 10, 2 );

add_filter( 'otter_form_record_confirm', array( $this, 'confirm_submission' ), 10, 2 );

add_action( 'transition_post_status', array( $this, 'apply_hooks_on_draft_transition' ), 10, 3 );
add_action( 'otter_form_update_record_meta_dump', array( $this, 'update_submission_dump_data' ), 10, 2 );
add_action( 'otter_form_automatic_confirmation', array( $this, 'move_old_stripe_draft_sessions_to_unread' ) );
add_filter( 'cron_schedules', array( $this, 'form_confirmation_schedule' ) );
add_action( 'wp', array( $this, 'schedule_automatic_confirmation' ) );
}

/**
Expand Down Expand Up @@ -716,13 +722,24 @@ public function fields_meta_box_markup( $post ) {
$meta = get_post_meta( $post->ID, self::FORM_RECORD_META_KEY, true );
$previous_field_option = '';


if ( empty( $meta ) ) {
return;
}

$inputs = array();
foreach ( $meta['inputs'] as $id => $field ) {
if ( empty( $field ) || 'stripe-field' === $field['type'] ) {
continue;
}

$inputs[ $id ] = $field;
}

?>
<table class="otter_form_record_meta form-table" style="border-spacing: 10px; width: 100%">
<tbody>
<?php foreach ( $meta['inputs'] as $id => $field ) { ?>
<?php foreach ( $inputs as $id => $field ) { ?>
<tr>
<th scope="row">
<label for="<?php echo esc_attr( $id ); ?>">
Expand Down Expand Up @@ -1120,7 +1137,7 @@ private function format_based_on_status( $content, $status ) {
*/
public function confirm_submission( $response, $request ) {

$session_id = $request->get_param( 'stripe_session_id' );
$session_id = $request->get_param( 'stripe_checkout' );

$stripe = new Stripe_API();

Expand Down Expand Up @@ -1154,11 +1171,35 @@ public function confirm_submission( $response, $request ) {
return $response;
}

$meta = get_post_meta( $record_id, self::FORM_RECORD_META_KEY, true );
wp_update_post(
array(
'ID' => $record_id,
'post_status' => 'unread',
)
);

$response->set_code( Form_Data_Response::SUCCESS_EMAIL_SEND );
$response->mark_as_success();

return $response;
}

/**
* Apply the 'after_submit' action when changing the status from 'draft' to 'unread'.
*
* @param string $new_status The new status.
* @param string $old_status The old status.
* @param WP_Post $post The post.
*/
public function apply_hooks_on_draft_transition( $new_status, $old_status, $post ) {
if ( 'draft' !== $old_status || self::FORM_RECORD_TYPE !== $post->post_type || $old_status === $new_status ) {
return;
}

$meta = get_post_meta( $post->ID, self::FORM_RECORD_META_KEY, true );

if ( ! isset( $meta['dump'] ) || empty( $meta['dump']['value'] ) ) {
$response->set_code( Form_Data_Response::ERROR_MISSING_DUMP_DATA );
return $response;
return;
}

$form_data = Form_Data_Request::create_from_dump( $meta['dump']['value'] );
Expand All @@ -1174,28 +1215,128 @@ public function confirm_submission( $response, $request ) {
( ! class_exists( 'ThemeIsle\GutenbergBlocks\Integration\Form_Data_Request' ) ) ||
! ( $form_data instanceof \ThemeIsle\GutenbergBlocks\Integration\Form_Data_Request )
) {
$response->set_code( Form_Data_Response::ERROR_RUNTIME_STRIPE_SESSION_VALIDATION );
return $response;
return;
}

do_action( 'otter_form_after_submit', $form_data );
}

if ( $form_data->has_error() ) {
$response->set_code( Form_Data_Response::ERROR_RUNTIME_STRIPE_SESSION_VALIDATION );
return $response;
/**
* Update the submission dump data.
*
* @param Form_Data_Request $form_data The form data.
* @param int $record_id The record ID.
*/
public function update_submission_dump_data( $form_data, $record_id ) {

if ( ! get_post( $record_id ) ) {
return;
}

wp_update_post(
$meta = get_post_meta( $record_id, self::FORM_RECORD_META_KEY, true );
$meta = is_array( $meta ) ? $meta : array();
$meta = array_merge(
$meta,
array(
'ID' => $record_id,
'post_status' => 'unread',
'dump' => array(
'label' => 'Dumped data',
'value' => $form_data->is_temporary_data() ? $form_data->dump_data() : array(),
),
)
);
update_post_meta( $record_id, self::FORM_RECORD_META_KEY, $meta );
}

$response->set_code( Form_Data_Response::SUCCESS_EMAIL_SEND );
$response->mark_as_success();
/**
* Move old drafts to unread.
*/
public function move_old_stripe_draft_sessions_to_unread() {
$now = current_time( 'mysql' );

// Calculate the time 15 minutes ago.
$time_15_minutes_ago = date( 'Y-m-d H:i:s', strtotime( '-15 minutes', strtotime( $now ) ) );

$args = array(
'post_type' => self::FORM_RECORD_TYPE,
'post_status' => 'draft',
'posts_per_page' => 10,
'orderby' => 'date',
'order' => 'DESC',
'date_query' => array(
'before' => $time_15_minutes_ago,
),
);

return $response;
$query = new WP_Query( $args );
if ( $query->have_posts() ) {

try {
$stripe = new Stripe_API();

while ( $query->have_posts() ) {
$query->the_post();

// Get the meta data.
$meta = get_post_meta( get_the_ID(), self::FORM_RECORD_META_KEY, true );

// Check if we have a Stripe session id in the meta dump data.
if ( ! isset( $meta['dump']['value']['metadata']['otter_form_stripe_checkout_session_id'] ) ) {
continue;
}

$stripe_checkout_session_id = $meta['dump']['value']['metadata']['otter_form_stripe_checkout_session_id'];

// Check if the session has status of paid.
$session = $stripe->create_request( 'get_session', $stripe_checkout_session_id );

if ( is_wp_error( $session ) ) {
continue;
}

$is_paid = isset( $session->payment_status ) && 'paid' === $session->payment_status;

if ( ! $is_paid ) {
continue;
}

wp_update_post(
array(
'ID' => get_the_ID(),
'post_status' => 'unread',
)
);
}
} catch ( \Exception $e ) {
// Do nothing.
return;
}
}
}

/**
* Add a new cron schedule for automatic submission confirmation.
*
* @param array $schedules The schedules.
* @return array
*/
public function form_confirmation_schedule( $schedules ) {
$schedules['otter_every_hour'] = array(

This comment has been minimized.

Copy link
@selul

selul Aug 3, 2023

Contributor

This comment has been minimized.

Copy link
@Soare-Robert-Daniel

Soare-Robert-Daniel Aug 3, 2023

Author Contributor

Yes it is. But for now it is still in development. I was thinking that maybe 6 hours will be a good value. Will be removed if the final value is already in core 👌

'interval' => HOUR_IN_SECONDS,
'display' => esc_html__( 'Every hour', 'otter-blocks' ),
);

return $schedules;
}

/**
* Schedule the automatic confirmation.
*
* @return void
*/
public function schedule_automatic_confirmation() {
if ( ! wp_next_scheduled( 'otter_form_confirmation' ) ) {
wp_schedule_event( time(), 'otter_every_hour', 'otter_form_automatic_confirmation' );
}
}

/**
Expand Down
9 changes: 7 additions & 2 deletions plugins/otter-pro/inc/plugins/class-form-pro-features.php
Original file line number Diff line number Diff line change
Expand Up @@ -610,7 +610,7 @@ public function create_stripe_session( $form_data ) {

$permalink = add_query_arg(
array(
'stripe_session_id' => '{CHECKOUT_SESSION_ID}',
'stripe_checkout' => '{CHECKOUT_SESSION_ID}', // Testing mode.
),
$form_data->get_payload_field( 'postUrl' )
);
Expand All @@ -634,7 +634,7 @@ public function create_stripe_session( $form_data ) {
$raw_metadata = $this->prepare_webhook_payload( array(), $form_data, null );
$metadata = array();
foreach ( $raw_metadata as $key => $value ) {
$metadata[ mb_substr( $key, 0, 40 ) ] = mb_substr( wp_json_encode( $value ), 0, 500 );
$metadata[ mb_substr( $key, 0, 40 ) ] = mb_substr( is_string( $value ) ? $value : wp_json_encode( $value ), 0, 500 );
}
$metadata['otter_form_record_id'] = $form_data->metadata['otter_form_record_id'];

Expand All @@ -652,6 +652,11 @@ public function create_stripe_session( $form_data ) {
return $form_data;
}

$form_data->metadata['otter_form_stripe_checkout_session_id'] = $session->id;
$form_data->metadata['otter_form_stripe_payment_intent_id'] = $session->payment_intent;

do_action( 'otter_form_update_record_meta_dump', $form_data, $form_data->metadata['otter_form_record_id'] );

$form_data->metadata['frontend_external_confirmation_url'] = $session->url;

return $form_data;
Expand Down
6 changes: 3 additions & 3 deletions src/blocks/frontend/form/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,22 @@ let saveMode = 'permanent';

const hasStripeConfirmation = () => {
const urlParams = new URLSearchParams( window.location.search );
return urlParams.has( 'stripe_session_id' );
return urlParams.has( 'stripe_checkout' );
};

const confirmRecord = async() => {

// Get the record id from the URL
const urlParams = new URLSearchParams( window.location.search );
const stripeSessionId = urlParams.get( 'stripe_session_id' );
const stripeSessionId = urlParams.get( 'stripe_checkout' );

console.log( 'Session ID: ' + stripeSessionId ); // TODO: remove after QA.

const formURlEndpoint = ( window?.themeisleGutenbergForm?.root || ( window.location.origin + '/wp-json/' ) ) + 'otter/v1/form/confirm';

console.log( 'Making a request for ' + formURlEndpoint ); // TODO: remove after QA.

return await fetch( formURlEndpoint + `?stripe_session_id=${stripeSessionId}`, {
return await fetch( formURlEndpoint + `?stripe_checkout=${stripeSessionId}`, {
method: 'GET',
credentials: 'include'
});
Expand Down

0 comments on commit b5227a6

Please sign in to comment.