Files
formipay/includes/Thankyou.php
2025-08-21 20:39:34 +07:00

695 lines
28 KiB
PHP

<?php
namespace Formipay;
use Formipay\Traits\SingletonTrait;
if ( ! defined( 'ABSPATH' ) ) exit;
class Thankyou {
use SingletonTrait;
private $form_id;
private $order_data;
private $order_details;
private $form_submit;
protected function __construct() {
add_action( 'init', [$this, 'set_endpoint'], 999);
add_filter( 'query_vars', [$this, 'set_query_vars'], 899);
add_action( 'wp_enqueue_scripts', [$this, 'frontend_enqueue'] );
add_filter( 'pre_get_document_title', [$this, 'page_title'], 1012 );
add_action( 'template_redirect', [$this, 'check_parse_query'], 999 );
add_action( 'wp_ajax_request_access_link', [$this, 'request_access_link'] );
add_action( 'wp_ajax_nopriv_request_access_link', [$this, 'request_access_link'] );
}
public function set_endpoint() {
$slug = 'thankyou';
$formipay_settings = get_option('formipay_settings');
if(!empty($formipay_settings['thankyou_link'])){
$slug = $formipay_settings['thankyou_link'];
}
add_rewrite_rule(
'^'.$slug.'/([^/]*)/?',
'index.php?formipay-thankyou=1&formipay-token=$matches[1]',
'top'
);
flush_rewrite_rules();
}
public function set_query_vars($vars){
$vars[] = 'formipay-thankyou';
$vars[] = 'formipay-token';
return $vars;
}
public function check_parse_query() {
global $wp_query;
$formipay_settings = get_option('formipay_settings');
if(is_admin()) :
return;
endif;
if(
!is_admin() &&
is_array($wp_query->query) &&
array_key_exists('formipay-thankyou', $wp_query->query) &&
true === boolval($wp_query->query['formipay-thankyou'])
) :
$token_value = sanitize_text_field($wp_query->query['formipay-token']);
$token_manager = new \Formipay\Token();
// New token validation
if ($token_data = $token_manager->validate($token_value)) {
$this->form_id = $form_id = $token_data['form_id'];
$this->order_id = $order_id = $token_data['order_id'];
$token_manager->increment_usage($token_value);
}
else {
wp_die('Invalid access token');
}
$this->order = $order = formipay_get_order($order_id);
$this->order_details = $order['items'];
$this->form_submit = $order['form_data'];
$button_background_color = json_decode(formipay_get_post_meta($form_id, 'button_bg_color'), true );
$button_text_color = json_decode(formipay_get_post_meta($form_id, 'button_text_color'), true );
$button_border_color = json_decode( formipay_get_post_meta($form_id, 'button_border_color'), true );
include_once FORMIPAY_PATH . 'public/templates/thank-you.php';
exit;
endif;
}
public function process_order_meta() {
$order_meta = [];
if(!empty($this->order['meta_data'])){
foreach($this->order['meta_data'] as $meta_data){
$key = $meta_data['name'];
$value = $meta_data['value'];
$order_meta[$key] = $value;
}
}
return $order_meta;
}
public function access_method() {
$order_meta = $this->process_order_meta();
$access_method = 'magic_link';
if(isset($order_meta['access_method'])) {
$access_method = $order_meta['access_method'];
}
return $access_method;
}
public function frontend_enqueue() {
global $wp_query;
if(
is_array($wp_query->query) &&
array_key_exists('formipay-thankyou', $wp_query->query) &&
true === boolval($wp_query->query['formipay-thankyou'])
) :
wp_enqueue_style( 'bs-icons', FORMIPAY_URL . 'vendor/Bootstrap/bootstrap-icons.css', [], '1.11.1', 'all');
wp_enqueue_style( 'sweetalert2', FORMIPAY_URL . 'vendor/SweetAlert2/sweetalert2.min.css', [], '11.14.5', 'all');
wp_enqueue_style( 'formipay-form-style', FORMIPAY_URL . 'public/assets/css/form-style.css', [], FORMIPAY_VERSION, 'all' );
wp_enqueue_style( 'formipay-thankyou', FORMIPAY_URL . 'public/assets/css/thankyou.css', [], FORMIPAY_VERSION, 'all' );
wp_enqueue_script( 'jquery-blockui', FORMIPAY_URL . 'vendor/jQuery-UI/jquery.blockUI.min.js', ['jquery'], '2.7.0', true);
wp_enqueue_script( 'jquery-clipboard', FORMIPAY_URL . 'vendor/ClipboardJS/clipboard.min.js', ['jquery'], '2.0.11', true);
wp_enqueue_script( 'sweetalert2', FORMIPAY_URL . 'vendor/SweetAlert2/sweetalert2.min.js', ['jquery'], '11.14.5', true);
wp_enqueue_script( 'formipay-thankyou', FORMIPAY_URL . 'public/assets/js/thankyou.js', ['jquery'], FORMIPAY_VERSION, true );
wp_enqueue_script( 'formipay-access-request', FORMIPAY_URL . 'public/assets/js/access-link-request.js', ['jquery'], FORMIPAY_VERSION, true );
$order_id = $this->order['id'];
wp_localize_script( 'formipay-thankyou', 'formipay_thankyou', [
'ajax_url' => admin_url('admin-ajax.php'),
'order_id' => $this->order_id,
'access_method' => $this->access_method(),
'email_validation' => [
'error' => [
'message' => __( 'Input a valid email address', 'formipay' )
]
],
'nonce' => wp_create_nonce('formipay-thankyou-nonce')
] );
endif;
}
public function can_access() {
$order_id = $this->order['id'];
// $order_meta = $this->order['meta_data'];
$order_meta = $this->process_order_meta();
$order_ip_address = $order_meta['ip_address'];
$order_user_agent = $order_meta['user_agent'];
$order_device_type = $order_meta['device_type'];
$current_ip_address = isset($_SERVER['REMOTE_ADDR']) ? sanitize_text_field(wp_unslash($_SERVER['REMOTE_ADDR'])) : '';
$current_user_agent = isset($_SERVER['HTTP_USER_AGENT']) ? sanitize_text_field(wp_unslash($_SERVER['HTTP_USER_AGENT'])) : '';
$current_device_type = (isset($_SERVER['HTTP_USER_AGENT']) && strpos(sanitize_text_field(wp_unslash($_SERVER['HTTP_USER_AGENT'])), 'Mobile') !== false) ? 'Mobile' : 'Desktop';
$can_access = false;
if(
$order_ip_address === $current_ip_address &&
$order_user_agent === $current_user_agent &&
$order_device_type === $current_device_type
) {
$cookie = $this->get_cookie();
if(
!empty($order_meta['session_id']) &&
!empty($cookie) &&
isset($cookie[$order_id]) && $cookie[$order_id] == $order_meta['session_id']
){
$can_access = true;
}
}
return $can_access;
}
public function render_view() {
$thankyou_content = formipay_get_post_meta($this->form_id, 'thankyou_screen_content');
$formipay_order_statuses = formipay_order_status_list();
$this_order_status = $formipay_order_statuses[ $this->order['status']];
$buyer_name = '';
if(!empty(formipay_get_post_meta($this->form_id, 'buyer_name'))){
$buyer_name_field = formipay_get_post_meta($this->form_id, 'buyer_name');
if(!empty($this->order['form_data'])){
foreach($this->order['form_data'] as $_form_data){
if($_form_data['name'] == $buyer_name_field){
$buyer_name = $_form_data['value'];
break;
}
}
}
}
$shortcodes = [
'buyer_name' => $buyer_name,
'product_name' => get_the_title($this->form_id),
'order_id' => $this->order['id'],
'order_date' => $this->order['created_date'],
'order_total' => '<p data-copy-value="' . $this->order['total'] . '" style="margin-bottom: .25em;">' . formipay_price_format( $this->order['total'], $this->form_id ) . '</p>
<button class="formipay-copy-button" data-copy-text="Copy" data-copied-text="Copied" data-not-copied-text="Not copied!" style="font-size: 14px;">
<i class="bi bi-copy"></i>Copy
</button>',
'order_status' => $this_order_status,
'order_details' => $this->render_order_details(),
'form_submission' => $this->render_form_submit()
];
$shortcodes = apply_filters( 'formipay/thankyou/shortcodes', $shortcodes, $this->form_id, $this->order, 'thankyou' );
$replacements = [];
if(!empty($shortcodes)){
foreach($shortcodes as $key => $value){
$replacements['{{'.$key.'}}'] = $value;
}
}
$thankyou_content = strtr($thankyou_content, $replacements);
return $thankyou_content;
}
public function view_access() {
ob_start();
?>
<main class="formipay-thank-you" role="main">
<section class="formipay-content-wrapper receipt" aria-label="Order Receipt">
<div class="formipay-the-contents">
<?php echo wp_kses($this->render_view(), formipay_thankyoupage_allowed_html()); ?>
</div>
</section>
<?php if($this->access_items() !== '') { ?>
<section class="formipay-content-wrapper receipt downloads" aria-label="Downloads">
<div class="formipay-the-contents">
<?php echo $this->can_access() ? $this->access_items() : wp_kses($this->request_access(), formipay_thankyoupage_allowed_html()); ?>
</div>
</section>
<?php } ?>
</main>
<?php
$content = ob_get_contents();
ob_end_clean();
// echo $content;
echo wp_kses($content, formipay_thankyoupage_allowed_html());
// echo wp_kses_post( $content );
}
public function request_access() {
$formipay_settings = get_option('formipay_settings');
if($this->order['status'] !== 'completed') {
return;
}
$active_media = [];
if( formipay_get_post_meta($this->form_id, 'product_access_to_email') == 'on'){
$active_media[] = 'email';
}
$active_media = apply_filters('formipay/order/access/active-media', $active_media, $this->form_id);
ob_start();
?>
<div class="request-thumbnail">
<?php
echo wp_get_attachment_image( $formipay_settings['thankyou_page_restriction_thumbnail'], 'full', false, [
'width' => '120'
] );
?>
</div>
<h2 id="access-request-heading"><?php echo esc_html($formipay_settings['thankyou_page_restriction_title']); ?></h2>
<form action="" class="request-for-access">
<div class="formipay-field-group" style="margin-bottom: 1em;">
<?php if($this->access_method() == 'magic_link') { ?>
<input type="text" name="access-pass-request" id="access-pass"
class="formipay-input"
value="" placeholder="Input <?php echo esc_html( implode('/', $active_media) ); ?>" required>
<p>
<?php echo
esc_html(
str_replace('{{media}}', implode(',', $active_media) ,$formipay_settings['thankyou_page_restriction_message'])
);
?>
</p>
<?php } elseif($this->access_method() == 'static_password') { ?>
<input type="password" name="access_password" id="access-pass"
class="formipay-input"
value="" placeholder="Input <?php echo esc_html( 'Password' ); ?>" required>
<?php } ?>
</div>
<button type="submit" id="request_access_to_media" class="formipay-submit-button" disabled>
<?php echo esc_html( $formipay_settings['thankyou_page_restriction_button'] ); ?>
</button>
</form>
<?php
$content = ob_get_contents();
ob_end_clean();
return $content;
}
public function request_access_link() {
check_ajax_referer( 'formipay-thankyou-nonce', '_wpnonce' );
$pass = isset($_REQUEST['pass']) ? sanitize_text_field( wp_unslash($_REQUEST['pass']) ) : '';
$order_id = isset($_REQUEST['order']) ? intval($_REQUEST['order']) : 0;
$method = isset($_REQUEST['method']) ? sanitize_text_field( wp_unslash($_REQUEST['method']) ) : '';
$order = formipay_get_order($order_id);
$formipay_order = new Formipay_Order();
$formipay_get_order = $formipay_order->get($order_id);
$order_meta_data = maybe_unserialize($formipay_get_order->meta_data);
$valid = false;
// validate pass
if($method == 'magic_link'){
$email_field_name = formipay_get_post_meta($order['form_id'], 'notification_email_buyer_recipient');
// $email_purchase = $order['form_data'][$email_field_name];
$email_purchase = '';
foreach($order['form_data'] as $form_data){
if($form_data['name'] == $email_field_name){
$email_purchase = $form_data['value'];
break;
}
}
if($email_purchase !== $pass){
wp_send_json( [
'title' => __( 'Wrong email!', 'formipay' ),
'message' => __( 'You must enter an email address that matches the email you used during purchase.', 'formipay' ),
'icon' => 'error'
] );
}
$valid = true;
}
if($method == 'static_password'){
if(
!empty($order_meta_data['access_password']) &&
$pass !== $order_meta_data['access_password']
) {
wp_send_json([
'title' => __( 'Password is invalid', 'formipay' ),
'message' => __( 'Please input a valid password to access this page.', 'formipay' ),
'icon' => 'error'
]);
}
$valid = true;
}
if(!$valid){
wp_send_json([
'title' => __( 'Not provided access method', 'formipay' ),
'message' => __( 'Contact the web master for further information or try again.', 'formipay' ),
'icon' => 'error'
]);
}
// $order_meta_data = $order['meta_data'];
$user_agent = isset($_SERVER['HTTP_USER_AGENT']) ? sanitize_text_field( wp_unslash( $_SERVER['HTTP_USER_AGENT'] ) ) : '';
$order_meta_data['session_id'] = uniqid();
$order_meta_data['ip_address'] = isset($_SERVER['REMOTE_ADDR']) ? sanitize_text_field( wp_unslash($_SERVER['REMOTE_ADDR']) ) : '';
$order_meta_data['user_agent'] = $user_agent;
$order_meta_data['device_type'] = (strpos( $user_agent, 'Mobile') !== false) ? 'Mobile' : 'Desktop';
$update = $formipay_order->update(
$order['id'],
[
'meta_data' => $order_meta_data
]
);
if(is_wp_error( $update )){
wp_send_json( [
'title' => __( 'Failed!', 'formipay' ),
'message' => __( 'Something\'s happened. Contact the web master for further information or try again.', 'formipay' ),
'icon' => 'error'
] );
}
$cookie = $this->get_cookie();
$cookie[$order_id] = $order_meta_data['session_id'];
setcookie( 'fp_access', maybe_serialize($cookie), time() + 86400, '/' );
if($method == 'magic_link'){
do_action('formipay/notification/access/email', $order);
wp_send_json( [
'title' => __( 'Access Link Sent!', 'formipay' ),
'message' => __( 'Check your Inbox (or maybe Spam) to find a new access link so you can get digital access of this purchase.', 'formipay' ),
'icon' => 'success',
'action' => 'idle'
] );
}elseif($method == 'static_password') {
wp_send_json( [
'title' => __( 'Password is Valid!', 'formipay' ),
'message' => __( 'You will be redirected to new link. Please wait.', 'formipay' ),
'icon' => 'success',
'action' => 'reload'
] );
}
}
public function access_items() {
$content = '';
if($this->order['status'] == 'completed' && !empty( formipay_get_post_meta($this->form_id, 'product_accesses') ) ){
// $downloads = json_decode( formipay_get_post_meta($this->form_id, 'product_access_downloads'), true );
$accesses = explode(',', formipay_get_post_meta($this->form_id, 'product_accesses'));
if(!empty($accesses)){
ob_start();
foreach($accesses as $access){
$type = formipay_get_post_meta( $access, 'access_type' );
$button_text = formipay_get_post_meta( $access, 'button_text' );
if($type == 'download'){
$source = formipay_get_post_meta( $access, 'access_download_source' );
if($source == 'external'){
$link = formipay_get_post_meta( $access, 'access_url' );
$filesize = formipay_get_post_meta( $access, 'details_filesize' );
}elseif($source == 'wp_media'){
$attachment_id = formipay_get_post_meta( $access, 'access_attachment' );
$link = wp_get_attachment_url($attachment_id);
$filesize = size_format( filesize( get_attached_file( $attachment_id ) ), 2 );
}
}elseif($type == 'redirect'){
$link = formipay_get_post_meta( $access, 'access_redirect_url' );
$attachment_id = 0;
$filesize = '';
}
$image = formipay_attachment_icon($attachment_id);
if(!empty(formipay_get_post_meta($access, 'details_icon'))){
$image = wp_get_attachment_image(formipay_get_post_meta($access, 'details_icon'), 'thumbnail', false, [
'width' => '36',
'height' => '36'
]);
}
?>
<div class="formipay-single-download">
<?php echo wp_kses_post($image); ?>
<div class="formipay-download-information">
<div class="formipay-file-info">
<span class="formipay-file-title">
<?php echo esc_html(get_the_title( $access )); ?>
</span>
<?php if(false !== formipay_get_post_meta($access, 'details_short_description')) { ?>
<p class="formipay-access-item-description">
<?php echo esc_html(formipay_get_post_meta($access, 'details_short_description')); ?>
</p>
<?php } ?>
<?php if( '' !== $filesize){ ?>
<span class="formipay-file-size">
<?php echo esc_html($filesize); ?>
</span>
<?php } ?>
</div>
<a id="formipay-download-<?php echo esc_attr($access) ?>" class="formipay-download-button formipay-submit-button" href="<?php echo esc_url($link) ?>" <?php echo $type == 'download' ? 'download' : 'target="_blank"' ?>>
<?php echo esc_html($button_text); ?>
</a>
</div>
</div>
<?php
}
$content = '<div class="formipay-downloads">'.ob_get_contents().'</div>';
ob_end_clean();
}
}
return $content;
}
public function page_title($title) {
global $wp_query;
if(
is_array($wp_query->query) &&
array_key_exists('formipay-thankyou', $wp_query->query) &&
true === boolval($wp_query->query['formipay-thankyou'])
) :
$token = explode(':::', base64_decode($wp_query->query['formipay-token']));
$form_id = $token[0];
$order_id = $token[1];
$title = 'Thankyou' . ' for your order #' . $order_id;
endif;
return $title;
}
public function render_order_details() {
ob_start();
if(!empty($this->order_details)){
?>
<table id="order-details">
<tbody>
<?php
foreach($this->order_details as $detail){
$qty = '';
if(isset($detail['qty'])){
$qty = ' <i class="bi bi-x"></i> '.$detail['qty'];
}
?>
<tr>
<th><?php echo wp_kses_post($detail['item']) . wp_kses_post($qty); ?></th>
<td><?php echo esc_html(formipay_price_format($detail['subtotal'], $this->form_id)); ?></td>
</tr>
<?php
}
?>
<tr>
<th><?php echo esc_html__( 'Total', 'formipay' ); ?></th>
<td><b><?php echo esc_html(formipay_price_format($this->order['total'], $this->form_id)); ?></b></td>
</tr>
</tbody>
</table>
<?php
}
$content = ob_get_contents();
ob_get_clean();
return $content;
}
public function render_form_submit() {
ob_start();
if(!empty($this->form_submit)){
$field_config = formipay_get_post_meta($this->form_id, 'formipay_settings');
?>
<table id="order-submission-details">
<tbody>
<tr>
<th><?php echo esc_html__('Product', 'formipay'); ?></th>
<td><?php echo esc_html(get_the_title($this->form_id)); ?></td>
</tr>
<?php
$skip_row = array(
'form_id', 'payment', 'order_id', 'order_status', 'grand_total', 'order_date'
);
foreach($this->form_submit as $field){
// $field_label = $field_config['fields'][$field_name.'_config']['label'];
$field_name = $field['name'];
$field_value = $field['value'];
if(in_array($field_name, $skip_row)){
continue;
}
if(empty($field_value)){
continue;
}
switch ($field_name) {
case 'form_id':
$field_label = esc_html__( 'Form ID', 'formipay' );
break;
case 'qty':
$field_label = esc_html__( 'Quantity', 'formipay' );
break;
case 'coupon_code':
$field_label = esc_html__( 'Coupon Discount', 'formipay' );
break;
case 'payment':
$field_label = esc_html__( 'Payment', 'formipay' );
break;
case 'payment_gateway':
$field_label = esc_html__( 'Payment Method', 'formipay' );
// $field_value = ucwords(str_replace('_', ' ', $field_value));
$field_value = $field_value == 'cod' ? 'Cash on Delivery' : ucwords( str_replace(['-','_'], ' ', $field_value) );
break;
case 'order_id':
$field_label = esc_html__( 'Order ID', 'formipay' );
break;
case 'grand_total':
$field_label = esc_html__( 'Grand Total', 'formipay' );
$field_value = esc_html(formipay_price_format($field_value, $this->form_id));
break;
case 'order_status':
$field_label = esc_html__( 'Order Status', 'formipay' );
break;
case 'order_date':
$field_label = esc_html__( 'Order Date', 'formipay' );
break;
default:
// $field_label = $field_config['fields'][$field_name.'_config']['label'];
if(is_array($field_value)){
$field_value = $field_value['value'];
}
if(filter_var($field_value, FILTER_VALIDATE_EMAIL)){
$field_value = $field_value;
}elseif(strpos($field_value, ',') !== false){
$values = explode(',', $field_value);
$field_value = '';
foreach($values as $value){
$field_value .= '<span class="checkbox-span">'.$value.'</span> ';
}
}else{
$field_value = ucwords( str_replace(['-','_'], ' ', $field_value) );
}
break;
}
?>
<tr>
<th><?php echo esc_html($field_label) ?></th>
<td><?php echo wp_kses_post($field_value) ?></td>
</tr>
<?php
}
?>
</tbody>
</table>
<?php
}
$content = ob_get_contents();
ob_get_clean();
return $content;
}
public function get_cookie() {
$cookie = [];
if (!empty($_COOKIE['fp_access'])) {
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
$raw_value = wp_unslash($_COOKIE['fp_access']);
// Validate before unserializing
if (is_serialized($raw_value)) { // Use WordPress core function
$maybe = maybe_unserialize($raw_value);
// Type-check and sanitize array contents
if (is_array($maybe)) {
$cookie = array_map('sanitize_text_field', $maybe);
}
}
}
return $cookie;
}
}