File "FrmSquareLiteEventsController.php"
Full Path: /home/adniftyx/public_html/wp-content/plugins/formidable/square/controllers/FrmSquareLiteEventsController.php
File size: 7.33 KB
MIME-type: text/x-php
Charset: utf-8
<?php
if ( ! defined( 'ABSPATH' ) ) {
die( 'You are not allowed to call this page directly.' );
}
class FrmSquareLiteEventsController {
/**
* @var string
*/
public static $events_to_skip_option_name = 'frm_square_events_to_skip';
/**
* @var object|null
*/
private $event;
/**
* Tell Square Connect API that the request came through by flushing early before processing.
* Flushing early allows the API to end the request earlier.
*
* @since 6.22
*
* @return void
*/
private function flush_response() {
ob_start();
// Get the size of the output.
$size = ob_get_length();
// Disable compression (in case content length is compressed).
header( 'Content-Encoding: none' );
// Set the content length of the response.
header( 'Content-Length: ' . $size );
// Close the connection.
header( 'Connection: close' );
// Flush all output.
ob_end_flush();
@ob_flush();
flush();
}
/**
* @return void
*/
public function process_events() {
$this->flush_response();
$unprocessed_event_ids = FrmSquareLiteConnectHelper::get_unprocessed_event_ids();
if ( $unprocessed_event_ids ) {
$this->process_event_ids( $unprocessed_event_ids );
}
wp_send_json_success();
}
/**
* @since 6.22
*
* @param array<string> $event_ids
*
* @return void
*/
private function process_event_ids( $event_ids ) {
foreach ( $event_ids as $event_id ) {
if ( $this->should_skip_event( $event_id ) ) {
continue;
}
set_transient( 'frm_square_last_process_' . $event_id, time(), 60 );
$this->event = FrmSquareLiteConnectHelper::get_event( $event_id );
if ( is_object( $this->event ) ) {
$this->handle_event();
$this->track_handled_event( $event_id );
FrmSquareLiteConnectHelper::process_event( $event_id );
} else {
$this->count_failed_event( $event_id );
}
}
}
/**
* @since 6.22
*
* @param string $event_id
*
* @return bool True if the event should be skipped.
*/
private function should_skip_event( $event_id ) {
if ( $this->last_attempt_to_process_event_is_too_recent( $event_id ) ) {
return true;
}
$option = get_option( self::$events_to_skip_option_name );
return is_array( $option ) && in_array( $event_id, $option, true );
}
/**
* @param string $event_id
*
* @return bool
*/
private function last_attempt_to_process_event_is_too_recent( $event_id ) {
$last_process_attempt = get_transient( 'frm_square_last_process_' . $event_id );
return is_numeric( $last_process_attempt ) && $last_process_attempt > time() - 60;
}
/**
* @since 6.22
*
* @param string $event_id
*
* @return void
*/
private function count_failed_event( $event_id ) {
$transient_name = 'frm_square_failed_event_' . $event_id;
$transient = get_transient( $transient_name );
$failed_count = is_int( $transient ) ? $transient + 1 : 1;
$maximum_retries = 3;
if ( $failed_count >= $maximum_retries ) {
$this->track_handled_event( $event_id );
} else {
set_transient( $transient_name, $failed_count, 4 * DAY_IN_SECONDS );
}
}
/**
* Track an event to no longer process.
* This is called for successful events, and also for failed events after a number of retries.
*
* @since 6.22
*
* @param string $event_id
*
* @return void
*/
private function track_handled_event( $event_id ) {
$option = get_option( self::$events_to_skip_option_name );
if ( is_array( $option ) ) {
if ( count( $option ) > 1000 ) {
// Prevent the option from getting too big by removing the front item before adding the next.
array_shift( $option );
}
} else {
$option = array();
}
$option[] = $event_id;
update_option( self::$events_to_skip_option_name, $option, false );
}
/**
* @return void
*/
private function handle_event() {
switch ( $this->event->type ) {
case 'payment.created':
$payment_id = $this->event->data->id;
$subscription = FrmSquareLiteConnectHelper::get_subscription_id_for_payment( $payment_id );
if ( is_object( $subscription ) && isset( $subscription->id ) ) {
$subscription_id = $subscription->id;
$this->add_subscription_payment( $subscription_id );
}
break;
case 'payment.updated':
$payment_id = $this->event->data->id;
$frm_payment = new FrmTransLitePayment();
$payment = $frm_payment->get_one_by( $payment_id, 'receipt_id' );
if ( $payment ) {
$status = $this->event->data->object->payment->status;
if ( 'COMPLETED' === $status && 'complete' !== $payment->status ) {
$payment_values = (array) $payment;
$payment_values['status'] = 'complete';
$frm_payment->update( $payment->id, $payment_values );
FrmTransLiteActionsController::trigger_payment_status_change(
array(
'status' => 'complete',
'payment' => $payment,
)
);
}
return;
}
break;
case 'subscription.updated':
$subscription_id = $this->event->data->id;
$frm_sub = new FrmTransLiteSubscription();
$sub = $frm_sub->get_one_by( $subscription_id, 'sub_id' );
if ( $sub ) {
$status = $this->event->data->object->subscription->status;
if ( 'DEACTIVATED' === $status ) {
$status = 'canceled';
FrmTransLiteSubscriptionsController::change_subscription_status(
array(
'status' => $status,
'sub' => $sub,
)
);
}
}
break;
}//end switch
}
/**
* Add a payment row for the payments table.
*
* @param string $subscription_id The Square ID for the current subscription.
*
* @return void
*/
private function add_subscription_payment( $subscription_id ) {
$payment_id = $this->event->data->id;
$frm_payment = new FrmTransLitePayment();
$payment = $frm_payment->get_one_by( $payment_id, 'receipt_id' );
if ( $payment ) {
// Avoid adding the same payment twice.
return;
}
$frm_sub = new FrmTransLiteSubscription();
$sub = $frm_sub->get_one_by( $subscription_id, 'sub_id' );
if ( ! $sub ) {
return;
}
$payment_object = $this->event->data->object->payment;
if ( 'JPY' === $payment_object->amount_money->currency ) {
// Japanese does not include the additional 2 digits.
$amount = $payment_object->amount_money->amount;
} else {
$amount = number_format( floatval( $payment_object->amount_money->amount ) / 100, 2 );
}
$begin_date = gmdate( 'Y-m-d' );
$expire_date = '0000-00-00';
$subscription = FrmSquareLiteConnectHelper::get_subscription( $sub->sub_id );
if ( is_object( $subscription ) ) {
if ( ! empty( $subscription->start_date ) ) {
$begin_date = gmdate( 'Y-m-d', strtotime( $subscription->start_date ) );
}
if ( ! empty( $subscription->charged_through_date ) ) {
$expire_date = gmdate( 'Y-m-d', strtotime( $subscription->charged_through_date ) );
$frm_sub->update(
$sub->id,
array( 'next_bill_date' => gmdate( 'Y-m-d', strtotime( $expire_date ) ) )
);
}
}
$frm_payment = new FrmTransLitePayment();
$frm_payment->create(
array(
'paysys' => 'square',
'amount' => $amount,
'status' => 'authorized',
'item_id' => $sub->item_id,
'action_id' => $sub->action_id,
'receipt_id' => $payment_id,
'sub_id' => $sub->id,
'test' => 'test' === FrmSquareLiteAppHelper::active_mode() ? 1 : 0,
'begin_date' => $begin_date,
'expire_date' => $expire_date,
)
);
}
}