first commit

This commit is contained in:
dwindown
2025-08-21 20:39:34 +07:00
commit 58c1497171
576 changed files with 177044 additions and 0 deletions

View File

@@ -0,0 +1,797 @@
<?php
namespace Formipay\Notification;
use Formipay\Traits\SingletonTrait;
// Exit if accessed directly
if ( ! defined( 'ABSPATH' ) ) exit;
class Email extends Notification {
use SingletonTrait;
private $formipay_settings;
private $order_data;
private $payment_timeout;
private $email_template = null;
protected function __construct() {
add_action('formipay/notification/order/email', [$this, 'notification'] );
add_action('formipay/notification/access/email', [$this, 'access_link'] );
add_action('formipay/notification/order/email/trigger-event', [$this, 'send_email'], 999 );
$this->formipay_settings = get_option('formipay_settings');
}
private function get_email_template() {
if ($this->email_template === null) {
$this->email_template = file_get_contents(FORMIPAY_PATH . 'notification/email_templates/email-page-template.html');
}
return $this->email_template;
}
public function notification($order_data) {
$formipay_settings = $this->formipay_settings;
$this->order_data = $order_data;
$recipient_type = apply_filters('formipay/notification/recipients', ['admin', 'buyer'] );
$order_status = str_replace('-', '_', $this->order_data['status']);
foreach($recipient_type as $recipient){
if(
false !== boolval($formipay_settings['notification_email_'.$recipient.'_'.$order_status.'_toggle']) &&
!empty($formipay_settings['notification_email_'.$recipient.'_'.$order_status.'_title']) &&
!empty($formipay_settings['notification_email_'.$recipient.'_'.$order_status.'_content'])
) {
$recipient_email = '';
$buyer_email_field = formipay_get_post_meta($this->order_data['form_id'], 'buyer_email');
if($recipient == 'admin' && false !== boolval($formipay_settings['notification_email_admin_recipient'])){
$recipient_email = $formipay_settings['notification_email_admin_recipient'];
}elseif( $recipient == 'buyer' && !empty($buyer_email_field)) {
$recipient_email = $this->order_data['form_data'][$buyer_email_field];
}
if( '' !== $recipient_email ){
$args = [
'order_id' => $this->order_data['id'],
'recipient_type' => $recipient,
'media' => 'email',
'notification_data' => [
'to' => $recipient_email,
'subject' => $formipay_settings['notification_email_'.$recipient.'_'.$order_status.'_title'],
'content' => $this->process_content($recipient)
],
'meta_data' => [
'request_date' => formipay_date('Y-m-d H:i:s')
]
];
$notification_id = parent::insert_notification_data($args);
if(false !== $notification_id){
wp_schedule_single_event( time() + 15, 'formipay/notification/order/email/trigger-event', [$notification_id] );
}
}
}
do_action( 'formipay/notification/order/email/trigger', $recipient, $order_data);
}
}
public function send_email($notification_id) {
$get = parent::get_notification_data_by_id($notification_id);
if(false !== $get){
$metadata = maybe_unserialize( $get->meta_data );
$get_data = maybe_unserialize( $get->notification_data );
$status = $get->status;
if(!empty($get_data)){
$send_mail = wp_mail(
sanitize_email( $get_data['to'] ),
$get_data['subject'],
$get_data['content'],
array('Content-Type: text/html; charset=UTF-8')
);
if(!is_wp_error($send_mail)){
$status = 'sent';
}else{
$status = 'error';
$metadata['error_message'] = $send_mail->get_error_messages();
}
$metadata['update_date'] = formipay_date('Y-m-d H:i:s');
$args = [
'status' => $status,
'meta_data' => $metadata
];
\Formipay_Notification::update_notification_data($notification_id, $args);
}
}
}
public function access_link($order_data) {
$formipay_settings = $this->formipay_settings;
$this->order_data = $order_data;
$buyer_email_field = formipay_get_post_meta($order_data['form_id'], 'notification_email_buyer_recipient');
if(
!empty($formipay_settings['notification_email_access_link_title']) &&
!empty($formipay_settings['notification_email_access_link_content']) &&
!empty($buyer_email_field)
) {
$recipient = 'buyer';
$recipient_email = '';
foreach($order_data['form_data'] as $form_data){
if($form_data['name'] == $buyer_email_field){
$recipient_email = $form_data['value'];
break;
}
}
if( '' !== $recipient_email ){
$send_mail = wp_mail(
sanitize_email( $recipient_email ),
$formipay_settings['notification_email_access_link_title'],
$this->process_content('buyer', 'access_link'),
array('Content-Type: text/html; charset=UTF-8')
);
}
}
do_action( 'formipay/notification/access/email/trigger', $recipient, $order_data);
}
public function process_content($recipient, $context='order') {
$formipay_settings = $this->formipay_settings;
$order_status = str_replace('-', '_', $this->order_data['status']);
$order_body_template = $formipay_settings['notification_email_' . $recipient . '_' . $order_status . '_content'];
$accesslink_body_template = $formipay_settings['notification_email_access_link_content'];
$body_template = $context == 'order' ? $order_body_template : $accesslink_body_template;
$buyer_name = formipay_get_post_meta($this->order_data['form_id'], 'buyer_name');
if(!empty($buyer_name)){
$buyer_name_field = $buyer_name;
$buyer_name = $this->order_data['form_data'][$buyer_name_field]['value'];
}
// Prepare the replacements for shortcodes
$replacements = [
'{{image_logo}}' => $this->get_image_logo(),
'{{email_content}}' => $this->get_content($body_template, $context),
'{{action_button}}' => $context == 'order' ? $this->get_action_button($recipient) : '',
'{{footer_message}}' => $this->get_footer_message(),
'{{social_links}}' => $this->get_social_links()
];
// Load the email template
$email_template = $this->get_email_template();
// Replace the shortcodes in the email template
$email_template = strtr($email_template, $replacements);
return $email_template;
}
private function get_content_depracated($body_template, $context) {
$form_id = $this->order_data['form_id'];
$order_data = $this->order_data;
$formipay_settings = $this->formipay_settings;
// Cache frequently used settings and meta values
$buyer_name_field = formipay_get_post_meta($form_id, 'buyer_name');
$payment_gateway = $order_data['form_data']['payment_gateway'];
$payment_timeout = !empty($formipay_settings[$payment_gateway . '_timeout'])
? formipay_date($order_data['created_date'] . ' + ' . $formipay_settings[$payment_gateway . '_timeout'] . ' minutes')
: '';
$lines = explode('<p><br></p>', $body_template);
$content = '';
foreach ($lines as $line) {
$line = trim($line);
if (strpos($line, '{{order_details}}') !== false) {
$content .= '<tr class="wp-block-editor-paragraphblock-v1">
<td valign="top" style="color:#5f5f5f;letter-spacing:0;word-break:normal;font-size: 1rem;padding:1rem 0;background-color:#ffffff;">';
$content .= $this->convert_order_details();
$content .= '</td></tr>';
} else {
$content .= '<tr class="wp-block-editor-paragraphblock-v1">
<td valign="top" style="color:#5f5f5f;letter-spacing:0;word-break:normal;font-size: 1rem;padding:1rem 2rem;background-color:#ffffff;">';
// Replace placeholders with actual data
$replacements = [
'{{buyer_name}}' => !empty($buyer_name_field) ? $order_data['form_data'][$buyer_name_field] : '',
'{{order_id}}' => $order_data['id'],
'{{order_status}}' => $order_data['status'],
'{{payment_timeout}}' => $payment_timeout
];
$line = strtr( $line, $replacements );
if ($context === 'access_link') {
$meta_data = $order_data['meta_data'];
$meta_session_id = '';
foreach($meta_data as $meta){
if($meta['name'] == 'session_id'){
$meta_session_id = $meta['value'];
break;
}
}
$thankyou_link = 'thankyou';
if(isset($formipay_settings['thankyou_link']) && !empty($formipay_settings['thankyou_link'])){
$thankyou_link = $formipay_settings['thankyou_link'];
}
$access_link = site_url('/'.$thankyou_link.'/' . base64_encode("$form_id:::{$order_data['id']}:::{$meta_session_id}"));
$line = str_replace(
[
'{{access_link}}',
'{{access_button}}'
],
[
$access_link,
$this->get_action_button('buyer', 'access_link', ['url' => $access_link, 'label' => 'Access Link'])
],
$line
);
}
$content .= $line;
$content .= '</td></tr>';
}
}
return $content;
}
private function get_content($body_template, $context) {
$form_id = $this->order_data['form_id'];
$order_data = $this->order_data;
$formipay_settings = $this->formipay_settings;
// Cache frequently used settings and meta values
$buyer_name_field = formipay_get_post_meta($form_id, 'buyer_name');
$payment_gateway = $order_data['form_data']['payment_gateway']['label'];
$this->payment_timeout = $payment_timeout = !empty($formipay_settings[$payment_gateway . '_timeout'])
? formipay_date($order_data['created_date'] . ' + ' . $formipay_settings[$payment_gateway . '_timeout'] . ' minutes')
: '';
$lines = explode('</p>', $body_template);
$content = '';
foreach ($lines as $line) {
$line = trim(str_replace('<p>', '', $line));
if(in_array($line, ['', '<br>'])) {
continue;
}
if (strpos($line, '{{order_details}}') !== false) {
$content .= '<table border="0" cellpadding="10" cellspacing="0" class="heading_block block-3" role="presentation" style="mso-table-lspace: 0pt; mso-table-rspace: 0pt;" width="100%">
<tr>
<td class="pad">
<h3 style="margin: 0; color: #101112; direction: ltr; font-family: Arial, Helvetica, sans-serif; font-size: 14px; font-weight: 700; letter-spacing: normal; line-height: 120%; text-align: left; margin-top: 1rem; margin-bottom: 0; mso-line-height-alt: 28.799999999999997px;">
<span class="tinyMce-placeholder" style="word-break: break-word;">' . __( 'Order Details', 'formipay' ) . '</span>
</h3>
</td>
</tr>
</table>';
$content .= $this->convert_order_details();
} elseif (strpos($line, '{{order_items}}') !== false) {
$content .= '<table border="0" cellpadding="10" cellspacing="0" class="heading_block block-3" role="presentation" style="mso-table-lspace: 0pt; mso-table-rspace: 0pt;" width="100%">
<tr>
<td class="pad">
<h3 style="margin: 0; color: #101112; direction: ltr; font-family: Arial, Helvetica, sans-serif; font-size: 14px; font-weight: 700; letter-spacing: normal; line-height: 120%; text-align: left; margin-top: 1rem; margin-bottom: 0; mso-line-height-alt: 28.799999999999997px;">
<span class="tinyMce-placeholder" style="word-break: break-word;">' . __( 'Order Items', 'formipay' ) . '</span>
</h3>
</td>
</tr>
</table>';
$content .= $this->convert_order_items();
} elseif (strpos($line, '{{buyer_details}}') !== false) {
$content .= '<table border="0" cellpadding="10" cellspacing="0" class="heading_block block-3" role="presentation" style="mso-table-lspace: 0pt; mso-table-rspace: 0pt;" width="100%">
<tr>
<td class="pad">
<h3 style="margin: 0; color: #101112; direction: ltr; font-family: Arial, Helvetica, sans-serif; font-size: 14px; font-weight: 700; letter-spacing: normal; line-height: 120%; text-align: left; margin-top: 1rem; margin-bottom: 0; mso-line-height-alt: 28.799999999999997px;">
<span class="tinyMce-placeholder" style="word-break: break-word;">' . __( 'Buyer Details', 'formipay' ) . '</span>
</h3>
</td>
</tr>
</table>';
$content .= $this->convert_buyer_details();
} else {
$content .= '<table border="0" cellpadding="10" cellspacing="0" class="paragraph_block block-12" role="presentation" style="mso-table-lspace: 0pt; mso-table-rspace: 0pt; word-break: break-word;" width="100%"><tr><td class="pad"><div style="color:#101112;direction:ltr;font-family:Arial, Helvetica, sans-serif;font-size:16px;font-weight:400;letter-spacing:0px;line-height:120%;text-align:left;mso-line-height-alt:19.2px;">';
// Replace placeholders with actual data
$replacements = [
'{{buyer_name}}' => !empty($buyer_name_field) ? $order_data['form_data'][$buyer_name_field]['value'] : '',
'{{order_id}}' => $order_data['id'],
'{{order_status}}' => $order_data['status'],
'{{payment_timeout}}' => $payment_timeout
];
$line = strtr( $line, $replacements );
if ($context === 'access_link') {
$meta_data = $order_data['meta_data'];
$meta_session_id = '';
foreach($meta_data as $meta){
if($meta['name'] == 'session_id'){
$meta_session_id = $meta['value'];
break;
}
}
$thankyou_link = 'thankyou';
if(isset($formipay_settings['thankyou_link']) && !empty($formipay_settings['thankyou_link'])){
$thankyou_link = $formipay_settings['thankyou_link'];
}
$token = Token::generate(
$order_data['id'],
$form_id,
900 // 15-minute expiration
);
$access_link = site_url('/'.$thankyou_link.'/' . $token);
$line = str_replace(
[
'{{access_link}}',
'{{access_button}}'
],
[
$access_link,
$this->get_action_button('buyer', 'access_link', ['url' => $access_link, 'label' => __('Access Link', 'formipay')])
],
$line
);
}
$content .= $line;
$content .= '</div></td></tr></table>';
}
}
return $content;
}
// Function to get the logo image
private function get_image_logo() {
$formipay_settings = $this->formipay_settings;
if(empty($formipay_settings['notification_email_logo'])){
return;
}
$logo_url = wp_get_attachment_image_url($formipay_settings['notification_email_logo'], 'full');
if(false == $logo_url){
return;
}
/**
* Template Baru
*/
return '<table border="0" cellpadding="0" cellspacing="0" class="image_block block-1" role="presentation" style="mso-table-lspace: 0pt; mso-table-rspace: 0pt; margin: 2rem 0;" width="100%">
<tr>
<td class="pad" style="width:100%;">
<div align="center" class="alignment" style="line-height:10px">
<div style="max-width: 480px;">
' . wp_get_attachment_image($formipay_settings['notification_email_logo'], 'full', false, array(
'style' => 'display: block; height: auto; border: 0;',
'width' => '360'
)) . '
</div>
</div>
</td>
</tr>
</table>';
}
// Function to convert order details
private function convert_order_details_depracated() {
if(empty($this->order_data['items'])){
return;
}
$button_background_color = json_decode(formipay_get_post_meta($this->order_data['form_id'], 'button_bg_color'), true );
ob_start();
?>
<table role="presentation" align="left" border="0" class="single-column" width="320" style="width:100%;float:left;border-collapse:collapse !important" cellspacing="0" cellpadding="0">
<tbody>
<?php foreach($this->order_data['items'] as $item){ ?>
<tr class="wp-block-editor-paragraphblock-v1" style="border-bottom: 1px solid #CECECE">
<td valign="top" style="padding:20px 20px 20px 2rem;background-color:#ffffff">
<p class="paragraph" style="font-size:1rem;margin:0;color:#5f5f5f;letter-spacing:0;word-break:normal;">
<span style="font-weight: bold; line-height: 1.25rem;" class="bold"><?php echo esc_html($item['item']); ?></span>
</p>
</td>
<td valign="top" style="padding:20px 2rem 20px 20px;background-color:#ffffff">
<p class="paragraph" style="font-size:1rem;margin:0;color:#5f5f5f;letter-spacing:0;word-break:normal;text-align:right;min-width:175px;">
<?php echo esc_html(formipay_price_format($item['subtotal'], $this->order_data['form_id'])); ?>
</p>
</td>
</tr>
<?php } ?>
</tbody>
<tfoot>
<tr class="wp-block-editor-paragraphblock-v1">
<td valign="top" style="padding:20px 20px 20px 2rem;background-color:#ffffff">
<p class="paragraph" style="font-size:1rem;margin:0;color:#5f5f5f;letter-spacing:0;word-break:normal;">
<span style="font-weight: bold; line-height: 1.25rem;" class="bold"><?php echo esc_html__('Total', 'formipay'); ?></span>
</p>
</td>
<td valign="top" style="padding:20px 2rem 20px 20px;background-color:#ffffff;min-width:175px;">
<p class="paragraph" style="color:<?php echo esc_html($button_background_color['active']); ?>;text-align:right;font-size:1.5rem;margin:0;letter-spacing:0;word-break:normal;">
<span style="font-weight: bold" class="bold">
<?php echo esc_html(formipay_price_format($this->order_data['total'], $this->order_data['form_id'])); ?>
</span>
</p>
</td>
</tr>
</tfoot>
</table>
<?php
$order_details_html = ob_get_contents();
ob_end_clean();
return $order_details_html;
}
// Function to convert order details
private function convert_order_details() {
if(empty($this->order_data['items'])){
return;
}
$button_background_color = json_decode(formipay_get_post_meta($this->order_data['form_id'], 'button_bg_color'), true );
ob_start();
?>
<table border="0" cellpadding="10" cellspacing="0" class="table_block block-4" role="presentation" style="mso-table-lspace: 0pt; mso-table-rspace: 0pt;" width="100%">
<tr>
<td class="pad" style="padding: 0;">
<div style="border: 1px solid #cccccc; border-radius: 15px; padding: 15px;">
<table style="mso-table-lspace: 0pt; mso-table-rspace: 0pt; border-collapse: collapse; width: 100%; table-layout: fixed; direction: ltr; background-color: transparent; font-family: Arial, Helvetica, sans-serif; font-weight: 400; color: #101112; text-align: left; letter-spacing: 0px;" width="100%">
<tbody style="vertical-align: top; font-size: 16px; line-height: 120%;">
<tr>
<td style="padding: 10px; word-break: break-word; border-top: 0px solid #dddddd; border-right: 0px solid #dddddd; border-bottom: 0px solid #dddddd; border-left: 0px solid #dddddd;" width="50%"><?php echo esc_html__( 'Order ID', 'formipay' ); ?></td>
<td style="padding: 10px; word-break: break-word; border-top: 0px solid #dddddd; border-right: 0px solid #dddddd; border-bottom: 0px solid #dddddd; border-left: 0px solid #dddddd; text-align: right;" width="50%"><?php echo intval($this->order_data['id']); ?></td>
</tr>
<tr>
<td style="padding: 10px; word-break: break-word; border-top: 0px solid #dddddd; border-right: 0px solid #dddddd; border-bottom: 0px solid #dddddd; border-left: 0px solid #dddddd;" width="50%"><?php echo esc_html__( 'Order Status', 'formipay' ); ?></td>
<td style="padding: 10px; word-break: break-word; border-top: 0px solid #dddddd; border-right: 0px solid #dddddd; border-bottom: 0px solid #dddddd; border-left: 0px solid #dddddd; text-align: right;" width="50%"><?php echo esc_html($this->order_data['status']); ?></td>
</tr>
<tr>
<td style="padding: 10px; word-break: break-word; border-top: 0px solid #dddddd; border-right: 0px solid #dddddd; border-bottom: 0px solid #dddddd; border-left: 0px solid #dddddd;" width="50%"><?php echo esc_html__( 'Payment Timeout', 'formipay' ); ?></td>
<td style="padding: 10px; word-break: break-word; border-top: 0px solid #dddddd; border-right: 0px solid #dddddd; border-bottom: 0px solid #dddddd; border-left: 0px solid #dddddd; text-align: right;" width="50%"><?php echo esc_html($this->payment_timeout); ?> </td>
</tr>
</tbody>
</table>
</div>
</td>
</tr>
</table>
<?php
$order_details_html = ob_get_contents();
ob_end_clean();
return $order_details_html;
}
// Function to convert order items
private function convert_order_items() {
if(empty($this->order_data['items'])){
return;
}
$button_background_color = json_decode(formipay_get_post_meta($this->order_data['form_id'], 'button_bg_color'), true );
ob_start();
?>
<table border="0" cellpadding="10" cellspacing="0" class="table_block block-6" role="presentation" style="mso-table-lspace: 0pt; mso-table-rspace: 0pt;" width="100%">
<tr>
<td class="pad" style="padding: 0;">
<div style="border: 1px solid #cccccc; border-radius: 15px; padding: 15px;">
<table style="mso-table-lspace: 0pt; mso-table-rspace: 0pt; border-collapse: collapse; width: 100%; table-layout: fixed; direction: ltr; background-color: transparent; font-family: Arial, Helvetica, sans-serif; font-weight: 400; color: #101112; text-align: left; letter-spacing: 0px;" width="100%">
<thead style="vertical-align: top; font-size: 16px; line-height: 120%;">
<tr>
<th style="padding: 10px; word-break: break-word; border-top: 0px solid #dddddd; border-right: 0px solid #dddddd; border-bottom: 0px solid #dddddd; border-left: 0px solid #dddddd;" width="50%"><?php echo esc_html__( 'Item', 'formipay' ); ?></th>
<th style="padding: 10px; word-break: break-word; border-top: 0px solid #dddddd; border-right: 0px solid #dddddd; border-bottom: 0px solid #dddddd; border-left: 0px solid #dddddd; text-align: right;" width="50%"><?php echo esc_html__( 'Amount', 'formipay' ); ?></th>
</tr>
</thead>
<tbody style="vertical-align: top; font-size: 16px; line-height: 120%;">
<?php foreach($this->order_data['items'] as $item){ ?>
<tr>
<td style="padding: 10px; word-break: break-word; border-top: 0px solid #dddddd; border-right: 0px solid #dddddd; border-bottom: 0px solid #dddddd; border-left: 0px solid #dddddd;" width="50%"><?php echo esc_html($item['item']); ?></td>
<td style="padding: 10px; word-break: break-word; border-top: 0px solid #dddddd; border-right: 0px solid #dddddd; border-bottom: 0px solid #dddddd; border-left: 0px solid #dddddd; text-align: right;" width="50%"><?php echo esc_html(formipay_price_format($item['subtotal'], $this->order_data['form_id'])); ?></td>
</tr>
<?php } ?>
<tr style="border-top: 1px solid #ccc">
<td style="padding: 10px; word-break: break-word; border-top: 0px solid #dddddd; border-right: 0px solid #dddddd; border-bottom: 0px solid #dddddd; border-left: 0px solid #dddddd;" width="50%">
<strong style="color: <?php echo esc_html($button_background_color['regular']); ?>;"><?php echo esc_html__( 'Total', 'formipay' ); ?></strong>
</td>
<td style="padding: 10px; word-break: break-word; border-top: 0px solid #dddddd; border-right: 0px solid #dddddd; border-bottom: 0px solid #dddddd; border-left: 0px solid #dddddd; text-align: right;" width="50%">
<strong style="color: <?php echo esc_html($button_background_color['regular']); ?>;"><?php echo esc_html(formipay_price_format($this->order_data['total'], $this->order_data['form_id'])); ?></strong>
</td>
</tr>
</tbody>
</table>
</div>
</td>
</tr>
</table>
<?php
$order_items_html = ob_get_contents();
ob_end_clean();
return $order_items_html;
}
// Function to convert buyer details
private function convert_buyer_details() {
if(empty($this->order_data['items'])){
return;
}
$button_background_color = json_decode(formipay_get_post_meta($this->order_data['form_id'], 'button_bg_color'), true );
// $buyer_email_field = formipay_get_post_meta($this->order_data['form_id'], 'notification_email_buyer_recipient');
$field_buyer_name = formipay_get_post_meta($this->order_data['form_id'], 'buyer_name');
$buyer_name = !empty($this->order_data['form_data'][$field_buyer_name]) ? $this->order_data['form_data'][$field_buyer_name] : '';
ob_start();
?>
<table border="0" cellpadding="10" cellspacing="0" class="table_block block-8" role="presentation" style="mso-table-lspace: 0pt; mso-table-rspace: 0pt;" width="100%">
<tr>
<td class="pad" style="padding: 0;">
<div style="border: 1px solid #cccccc; border-radius: 15px; padding: 15px;">
<table style="mso-table-lspace: 0pt; mso-table-rspace: 0pt; border-collapse: collapse; width: 100%; table-layout: fixed; direction: ltr; background-color: transparent; font-family: Arial, Helvetica, sans-serif; font-weight: 400; color: #101112; text-align: left; letter-spacing: 0px;" width="100%">
<tbody style="vertical-align: top; font-size: 16px; line-height: 120%;">
<tr>
<td style="padding: 10px; word-break: break-word; border-top: 0px solid #dddddd; border-right: 0px solid #dddddd; border-bottom: 0px solid #dddddd; border-left: 0px solid #dddddd;" width="50%"><?php echo esc_html__( 'Name', 'formipay' ); ?></td>
<td style="padding: 10px; word-break: break-word; border-top: 0px solid #dddddd; border-right: 0px solid #dddddd; border-bottom: 0px solid #dddddd; border-left: 0px solid #dddddd; text-align: right;" width="50%"><?php echo esc_html($buyer_name); ?></td>
</tr>
<?php
$customer_data = apply_filters('formipay/customer/data-mapping', ['email', 'phone'] );
foreach($customer_data as $data){
if(false !== formipay_get_post_meta($this->order_data['form_id'], 'notification_'.$data.'_buyer_recipient')) {
$field_name = formipay_get_post_meta($this->order_data['form_id'], 'notification_'.$data.'_buyer_recipient');
$field_value = !empty($order_data['form_data'][$field_name]) ? $order_data['form_data'][$field_name] : '';
if($field_value !== ''){
?>
<tr>
<td style="padding: 10px; word-break: break-word; border-top: 0px solid #dddddd; border-right: 0px solid #dddddd; border-bottom: 0px solid #dddddd; border-left: 0px solid #dddddd;" width="50%"><?php echo esc_html(ucwords($data)); ?></td>
<td style="padding: 10px; word-break: break-word; border-top: 0px solid #dddddd; border-right: 0px solid #dddddd; border-bottom: 0px solid #dddddd; border-left: 0px solid #dddddd; text-align: right;" width="50%"><?php echo esc_html($field_value); ?></td>
</tr>
<?php
}
}
}
?>
</tbody>
</table>
</div>
</td>
</tr>
</table>
<?php
$buyer_details_html = ob_get_contents();
ob_end_clean();
return $buyer_details_html;
}
private function get_action_button_depracated($recipient, $context='order', $button=[]) {
if($context == 'order' && empty($button)) {
$button = apply_filters( 'formipay/notification/order/email/action-button', [], $recipient, $this->order_data );
}
$content = '';
if(!empty($button)){
$button_background_color = json_decode(formipay_get_post_meta($this->order_data['form_id'], 'button_bg_color'), true );
$button_text_color = json_decode(formipay_get_post_meta($this->order_data['form_id'], 'button_text_color'), true );
ob_start();
if($context == 'order'){
?>
<tr class="wp-block-editor-buttonblock-v1" align="center">
<td style="background-color:#ffffff;padding-top:40px;padding-right:20px;padding-bottom:60px;padding-left:20px;width:100%" valign="top">
<table role="presentation" cellspacing="0" cellpadding="0" class="button-table">
<tbody>
<tr>
<td valign="top" class="button-CzEb4_za43eNTBt_C1QR7 button-td button-td-primary" style="cursor:pointer;border:none;border-radius:4px;background-color:<?php echo esc_html($button_background_color['regular']); ?>;font-size:16px;font-family:Open Sans, sans-serif;width:fit-content;text-decoration:none;color:<?php echo esc_html($button_text_color['regular']); ?>;overflow:hidden">
<a href="<?php echo esc_url($button['url']); ?>" style="color:<?php echo esc_html($button_text_color['regular']); ?>;display:block;padding:16px 16px 16px 16px"><?php echo esc_html($button['label']); ?></a>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
<?php
}elseif($context == 'access_link'){
?>
<a href="<?php echo esc_url($button['url']); ?>" style="cursor:pointer;border:none;border-radius:4px;background-color:<?php echo esc_html($button_background_color['regular']); ?>;font-size:16px;font-family:Open Sans, sans-serif;width:fit-content;text-decoration:none;color:<?php echo esc_html($button_text_color['regular']); ?>;display:block;padding:16px 16px 16px 16px"><?php echo esc_html($button['label']); ?></a>
<?php
}
$content = ob_get_contents();
ob_end_clean();
}
return $content;
}
private function get_action_button($recipient, $context='order', $button=[]) {
if($context == 'order' && empty($button)) {
$button = apply_filters( 'formipay/notification/order/email/action-button', [], $recipient, $this->order_data );
}
$content = '';
if(!empty($button)){
$button_background_color = json_decode(formipay_get_post_meta($this->order_data['form_id'], 'button_bg_color'), true );
$button_text_color = json_decode(formipay_get_post_meta($this->order_data['form_id'], 'button_text_color'), true );
ob_start();
if($context == 'order'){
?>
<div class="spacer_block block-9" style="height:2rem;line-height:15px;font-size:1px;"></div>
<table border="0" cellpadding="10" cellspacing="0" class="button_block block-10" role="presentation" style="mso-table-lspace: 0pt; mso-table-rspace: 0pt;" width="100%">
<tr>
<td class="pad" style="padding: 0;">
<div align="center" class="alignment">
<a href="<?php echo esc_url($button['url']); ?>" style="color:#ffffff;text-decoration:none;" target="_blank">
<!--[if mso]>
<v:roundrect
xmlns:v="urn:schemas-microsoft-com:vml"
xmlns:w="urn:schemas-microsoft-com:office:word" href="<?php echo esc_url($button['url']); ?>" style="height:52px;width:460px;v-text-anchor:middle;" arcsize="58%" fillcolor="#7747FF">
<v:stroke dashstyle="Solid" weight="0px" color="#7747FF"/>
<w:anchorlock/>
<v:textbox inset="0px,0px,0px,0px">
<center dir="false" style="color:#ffffff;font-family:sans-serif;font-size:16px">
<![endif]-->
<span class="button" style="background-color: <?php echo esc_html($button_background_color['regular']); ?>; border-bottom: 0px solid transparent; border-left: 0px solid transparent; border-radius: 30px; border-right: 0px solid transparent; border-top: 0px solid transparent; color:<?php echo esc_html($button_text_color['regular']); ?>; display: inline-block; font-family: Arial, Helvetica, sans-serif; font-size: 16px; font-weight: 400; mso-border-alt: none; padding: 10px 0; text-align: center; width: 100%; word-break: keep-all; letter-spacing: normal;">
<span style="color:<?php echo esc_html($button_text_color['regular']); ?>;word-break: break-word; line-height: 32px;"><?php echo esc_html($button['label']); ?></span>
</span>
<!--[if mso]>
</center>
</v:textbox>
</v:roundrect>
<![endif]-->
</a>
</div>
</td>
</tr>
</table>
<div class="spacer_block block-11" style="height:2rem;line-height:15px;font-size:1px;"></div>
<?php
}elseif($context == 'access_link'){
?>
<table border="0" cellpadding="10" cellspacing="0" class="heading_block block-3" role="presentation" style="mso-table-lspace: 0pt; mso-table-rspace: 0pt;" width="100%">
<tr>
<td class="pad">
<a href="<?php echo esc_url($button['url']); ?>" style="cursor:pointer;border:none;border-radius:4px;background-color:<?php echo esc_html($button_background_color['regular']); ?>;font-size:16px;font-family:Open Sans, sans-serif;width:fit-content;text-decoration:none;color:<?php echo esc_html($button_text_color['regular']); ?>;display:block;padding:16px 16px 16px 16px"><?php echo esc_html($button['label']); ?></a>
</td>
</tr>
</table>
<?php
}
$content = ob_get_contents();
ob_end_clean();
}
return $content;
}
private function get_footer_message_depracated() {
$formipay_settings = $this->formipay_settings;
if(empty($formipay_settings['notification_email_footer'])){
return;
}
$footer = sprintf('<tr>
<td align="center" style="padding: 20px;">
<p>%s</p>
</td>
</tr>', wp_kses_post($formipay_settings['notification_email_footer']) );
return $footer;
}
private function get_footer_message() {
$formipay_settings = $this->formipay_settings;
if(empty($formipay_settings['notification_email_footer'])){
return;
}
$footer = '<table border="0" cellpadding="10" cellspacing="0" class="paragraph_block block-12" role="presentation" style="mso-table-lspace: 0pt; mso-table-rspace: 0pt; word-break: break-word; margin-bottom: 2rem;" width="100%">
<tr>
<td class="pad">
<div style="color:#101112;direction:ltr;font-family:Arial, Helvetica, sans-serif;font-size:16px;font-weight:400;letter-spacing:0px;line-height:120%;text-align:left;mso-line-height-alt:19.2px;">
'.wp_kses_post($formipay_settings['notification_email_footer']).'
</div>
</td>
</tr>
</table>';
return $footer;
}
private function get_social_links() {
$formipay_settings = $this->formipay_settings;
$content = '';
if(!empty($formipay_settings['notification_email_footer_links'])){
$links = [];
foreach($formipay_settings['notification_email_footer_links'] as $link){
// phpcs:ignore PluginCheck.CodeAnalysis.ImageFunctions.NonEnqueuedImage -- This image is a plugin asset and not a WordPress attachment.
$links[] = '<a href="'.esc_url($link['link']).'" style="margin:0 10px;"><img src="' . FORMIPAY_URL . 'admin/assets/img/icons8-' . esc_html($link['type']) . '-50.png" width="24"></a>';
}
$content .= '<table border="0" cellpadding="10" cellspacing="0" class="paragraph_block block-12" role="presentation" style="mso-table-lspace: 0pt; mso-table-rspace: 0pt; word-break: break-word; margin-bottom: 2rem;" width="100%"><tr><td class="pad" style="text-align: center;">';
$content .= implode('', $links);
$content .= '</td></tr></table>';
}
return $content;
}
}

View File

@@ -0,0 +1,512 @@
<?php
namespace Formipay\Notification;
use Formipay\Traits\SingletonTrait;
// Exit if accessed directly
if ( ! defined( 'ABSPATH' ) ) exit;
class Notification {
use SingletonTrait;
protected function __construct() {
add_action( 'init', [$this, 'create_db'] );
add_filter( 'formipay/global-settings/tab:general', [$this, 'global_settings_general'], 40 );
add_filter( 'formipay/global-settings', [$this, 'add_menu_on_global_setting'], 40 );
add_filter( 'formipay/form-config', [$this, 'add_menu_on_product_setting'], 100 );
add_action( 'formipay/notification/order', [$this, 'order_trigger'] );
add_action( 'formipay/notification/access', [$this, 'access_trigger'] );
}
public function create_db() {
global $wpdb;
$charset_collate = $wpdb->get_charset_collate();
$create[] = "CREATE TABLE `{$wpdb->base_prefix}formipay_notification_log` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`user_id` int,
`customer_id` int,
`order_id` int,
`recipient_type` text,
`media` text,
`notification_data` longtext,
`status` text,
`meta_data` text,
PRIMARY KEY (`id`)
) $charset_collate;";
require_once ABSPATH . 'wp-admin/includes/upgrade.php';
dbDelta($create);
}
public function insert_notification_data($args) {
$args = wp_parse_args( $args, [
'order_id' => 0,
'recipient_type' => 'admin',
'media' => 'email',
'notification_data' => [],
'status' => 'pending',
'meta_data' => []
] );
global $wpdb;
$table = $wpdb->prefix . 'formipay_notification_log';
$insert_data = [
'order_id' => intval($args['order_id']),
'recipient_type' => sanitize_text_field($args['recipient_type']),
'media' => sanitize_text_field($args['media']),
'notification_data' => maybe_serialize($args['notification_data']),
'status' => sanitize_text_field($args['status']),
'meta_data' => maybe_serialize($args['meta_data'])
];
if($args['order_id'] > 0){
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
$wpdb->insert($table, $insert_data);
return $wpdb->insert_id;
}
return false;
}
public function get_notification_data_by_id($notification_id) {
global $wpdb;
$table = $wpdb->prefix . 'formipay_notification_log';
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
$get = $wpdb->get_row(
$wpdb->prepare(
"SELECT * FROM %i WHERE `id` = %d", $table, $notification_id
)
);
return $get;
}
public function update_notification_data($notification_id, $args) {
$recent_data = $this->get_notification_data_by_id($notification_id);
$args = wp_parse_args( $args, [
'order_id' => $recent_data->order_id,
'recipient_type' => $recent_data->recipient_type,
'media' => $recent_data->media,
'notification_data' => maybe_unserialize($recent_data->notification_data),
'status' => $recent_data->status,
'meta_data' => maybe_unserialize($recent_data->meta_data)
] );
global $wpdb;
$table_name = $wpdb->prefix . 'formipay_notification_log';
$new_args = [
'order_id' => intval($args['order_id']),
'recipient_type' => sanitize_text_field($args['recipient_type']),
'media' => sanitize_text_field($args['media']),
'notification_data' => maybe_serialize($args['notification_data']),
'status' => sanitize_text_field($args['status']),
'meta_data' => maybe_serialize($args['meta_data'])
];
$where = [ 'id' => $notification_id ];
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
$update = $wpdb->update( $table_name, $new_args, $where );
return $update;
}
public function global_settings_general($fields) {
$medias = apply_filters('formipay/notification/media', ['email'] );
$notification_fields = [
'notification_type_group' => [
'type' => 'group_title',
'label' => __( 'Notification Type', 'formipay'),
'group' => 'started',
],
];
foreach($medias as $key => $media){
$notification_fields['notification_'.$media.'_active'] = [
'type' => 'checkbox',
'label' => sprintf( __( '%s Notification', 'formipay'), ucfirst($media) ),
'value' => true
];
}
$last_notification_field = count($notification_fields) - 1;
$notification_fields[$last_notification_field]['group'] = 'ended';
$notification_fields['notification_email_sender_group_header'] = [
'type' => 'group_title',
'label' => __( 'Email Settings', 'formipay'),
'group' => 'started',
'dependency' => [
'key' => 'notification_email_active',
'value' => 'not_empty'
]
];
foreach($medias as $key => $media){
$notification_fields['notification_'.$media.'_admin_recipient'] = [
'type' => 'text',
// translators: %s is the media type name.
'label' => sprintf( __( 'Admin\'s %s', 'formipay'), ucfirst($media) ),
'dependency' => [
'key' => 'notification_email_active',
'value' => 'not_empty'
]
];
}
$notification_fields['notification_name_admin_recipient'] = [
'type' => 'text',
'label' => __( 'Admin\'s Name', 'formipay'),
'dependency' => [
'key' => 'notification_email_active',
'value' => 'not_empty'
]
];
$notification_fields['notification_email_logo'] = [
'type' => 'image',
'label' => __('Logo Image', 'formipay'),
'dependency' => [
'key' => 'notification_email_active',
'value' => 'not_empty'
]
];
$notification_fields['notification_email_footer'] = [
'type' => 'tinymce',
'label' => __( 'Email Footer', 'formipay'),
'dependency' => [
'key' => 'notification_email_active',
'value' => 'not_empty'
]
];
$notification_fields['notification_email_footer_links'] = [
'type' => 'repeater',
'label' => __( 'Icon Links', 'formipay' ),
'fields' => [
'type' => [
'type' => 'select',
'label' => __( 'Type', 'formipay' ),
'is_group_title' => true,
'options' => [
'dribbble' => 'Dribbble',
'facebook' => 'Facebook',
'facebook-messenger' => 'Messenger',
'github' => 'Github',
'instagram' => 'Instagram',
'link' => 'Link',
'linkedin' => 'Linkedin',
'pinterest' => 'Pinterest',
'telegram' => 'Telegram',
'tiktok' => 'Tiktok',
'whatsapp' => 'WhatsApp',
'wordpress' => 'WordPress',
'x' => 'X'
],
],
'link' => [
'type' => 'text',
'label' => __( 'URL', 'formipay' )
]
],
'group' => 'ended',
'dependency' => [
'key' => 'notification_email_active',
'value' => 'not_empty'
]
];
$fields = array_merge($fields, $notification_fields);
return $fields;
}
public function add_menu_on_global_setting($fields) {
$hints = formipay_editor_hints();
$statuses = formipay_order_status_list();
$medias = apply_filters('formipay/notification/media', ['email'] );
$notification_fields = [];
// access link
$notification_fields['notification_email_access_link_group'] = [
'type' => 'group_title',
'label' => __( 'Access Link', 'formipay' ),
'description' => __( 'This notification type is for responding request for access when people visit the thankyou page that contain any of your digital access (including files and URLs)', 'formipay' ),
'group' => 'started',
'submenu' => __( 'Access Link', 'formipay' ),
'dependency' => [
'key' => 'notification_email_active',
'value' => 'not_empty',
'section' => 'General'
]
];
$notification_fields['notification_email_access_link_title'] = [
'type' => 'text',
'label' => __( 'Title', 'formipay' ),
'value' => __( 'Your New Purchased Access Link', 'formipay' ),
'submenu' => __( 'Access Link', 'formipay' ),
'dependency' => [
'key' => 'notification_email_active',
'value' => 'not_empty',
'section' => 'General'
]
];
$notification_fields['notification_email_access_link_content'] = [
'type' => 'tinymce',
'label' => __( 'Content', 'formipay' ),
'hints' => [
'buyer_name' => __( 'Buyer Name', 'formipay' ),
'order_id' => __( 'Order ID', 'formipay' ),
'access_button' => __( 'Access Button', 'formipay' ),
'access_link' => __( 'Access Link', 'formipay' ),
],
'submenu' => __( 'Access Link', 'formipay' ),
'value' => '<p>Hello {{buyer_name}},</p><p><br></p><p>Anyone request to access your purchase order ID&nbsp;<span style="background-color: transparent;">{{order_id}}</span><span style="background-color: transparent;">. Here is the new access link:</span></p><p>{{access_button}}<br></p><p><br></p><p>Here is the raw link if there is issue with the button:</p><p>{{access_link}}</p><p><br></p><p>Do not give access to others to make sure your purcase safe. Please ignore this email if it was not you.</p><p><br></p><p>Best regards,</p><p>Your E-commerce Team</p>',
'group' => 'ended',
'dependency' => [
'key' => 'notification_email_active',
'value' => 'not_empty',
'section' => 'General'
]
];
foreach($statuses as $key => $status){
$status_key = str_replace('-', '_', $key);
$notification_fields['notification_email_admin_'.$status_key.'_group_header'] = [
'type' => 'group_title',
// translators: %s is the status of order.
'label' => sprintf( __( 'Email Notification Admin (%s)', 'formipay' ), $status),
'group' => 'started',
'submenu' => esc_html($status),
'dependency' => [
'key' => 'notification_email_active',
'value' => 'not_empty',
'section' => 'General'
]
];
$notification_fields['notification_email_admin_'.$status_key.'_toggle'] = [
'type' => 'checkbox',
'label' => __('Activate', 'formipay'),
'submenu' => esc_html($status),
'dependency' => [
'key' => 'notification_email_active',
'value' => 'not_empty',
'section' => 'General'
]
];
$notification_fields['notification_email_admin_'.$status_key.'_title'] = [
'type' => 'text',
'label' => __( 'Title', 'formipay' ),
'submenu' => esc_html($status),
'dependency' => [
[
'key' => 'notification_email_admin_'.$status_key.'_toggle',
'value' => 'not_empty'
],
[
'key' => 'notification_email_active',
'value' => 'not_empty',
'section' => 'General'
]
],
'dependencies' => '&&'
];
$notification_fields['notification_email_admin_'.$status_key.'_content'] = [
'type' => 'tinymce',
'label' => __( 'Content', 'formipay' ),
'hints' => [
'order_details' => __( 'Order Details', 'formipay' ),
'order_items' => __( 'Order Items', 'formipay' ),
'buyer_details' => __( 'Buyer Details', 'formipay' ),
'buyer_name' => __( 'Buyer Name', 'formipay' ),
'order_id' => __( 'Order ID', 'formipay' ),
'order_status' => __( 'Order Status', 'formipay' ),
'payment_timeout' => __( 'Payment Timeout', 'formipay' )
],
'submenu' => esc_html($status),
'dependency' => [
[
'key' => 'notification_email_admin_'.$status_key.'_toggle',
'value' => 'not_empty'
],
[
'key' => 'notification_email_active',
'value' => 'not_empty',
'section' => 'General'
]
],
'dependencies' => '&&',
'group' => 'ended',
];
$notification_fields['notification_email_buyer_'.$status_key.'_group_header'] = [
'type' => 'group_title',
// translators: %s is the status of order.
'label' => sprintf( __( 'Email Notification Buyer (%s)', 'formipay' ), $status),
'group' => 'started',
'submenu' => esc_html($status),
'description' => __( 'Email notification for buyer only available if your form is contain email field type', 'formipay'),
];
$notification_fields['notification_email_buyer_'.$status_key.'_toggle'] = [
'type' => 'checkbox',
'label' => __('Activate', 'formipay'),
'submenu' => esc_html($status),
'dependency' => [
'key' => 'notification_email_active',
'value' => 'not_empty',
'section' => 'General'
]
];
$notification_fields['notification_email_buyer_'.$status_key.'_title'] = [
'type' => 'text',
'label' => __( 'Title', 'formipay' ),
'submenu' => esc_html($status),
'dependency' => [
[
'key' => 'notification_email_buyer_'.$status_key.'_toggle',
'value' => 'not_empty'
],
[
'key' => 'notification_email_active',
'value' => 'not_empty',
'section' => 'General'
]
],
'dependencies' => '&&'
];
$notification_fields['notification_email_buyer_'.$status_key.'_content'] = [
'type' => 'tinymce',
'label' => __( 'Content', 'formipay' ),
'hints' => [
'order_details' => __( 'Order Details', 'formipay' ),
'order_items' => __( 'Order Items', 'formipay' ),
'buyer_details' => __( 'Buyer Details', 'formipay' ),
'buyer_name' => __( 'Buyer Name', 'formipay' ),
'order_id' => __( 'Order ID', 'formipay' ),
'order_status' => __( 'Order Status', 'formipay' ),
'payment_timeout' => __( 'Payment Timeout', 'formipay' )
],
'submenu' => esc_html($status),
'dependency' => [
[
'key' => 'notification_email_buyer_'.$status_key.'_toggle',
'value' => 'not_empty'
],
[
'key' => 'notification_email_active',
'value' => 'not_empty',
'section' => 'General'
]
],
'dependencies' => '&&',
'group' => 'ended',
];
$notification_fields = apply_filters('formipay/settings/notification/fields/'.$status_key, $notification_fields);
}
$fields['notification'] = [
'name' => __('Notification', 'formipay'),
'fields' => $notification_fields
];
return $fields;
}
public function add_menu_on_product_setting($fields) {
$notification_fields = [];
$hints = formipay_editor_hints();
$statuses = formipay_order_status_list();
foreach($statuses as $key => $status){
$status_key = str_replace('-', '_', $key);
$notification_fields['product_notification_email_buyer_'.$status_key.'_group_header'] = [
'type' => 'group_title',
// translators: %s is the status of order.
'label' => sprintf( __( 'Email Notification Buyer (%s)', 'formipay' ), $status),
'group' => 'started',
'description' => __( 'Email notification for buyer only available if your form is contain email field type', 'formipay'),
];
$notification_fields['product_notification_email_buyer_'.$status_key.'_toggle'] = [
'type' => 'checkbox',
'label' => __('Replace Content', 'formipay'),
];
$notification_fields['product_notification_email_buyer_'.$status_key.'_content'] = [
'type' => 'tinymce',
'label' => __( 'Email Content', 'formipay' ),
'hints' => $hints,
'dependency' => [
'key' => 'product_notification_email_buyer_'.$status_key.'_toggle',
'value' => 'not_empty'
],
'group' => 'ended',
];
$notification_fields = apply_filters('formipay/product/notification/fields/', $notification_fields, $status_key);
}
$fields['formipay_form_settings']['notification'] = [
'name' => __('Notification', 'formipay'),
'fields' => $notification_fields
];
return $fields;
}
public function order_trigger($order_data) {
$medias = apply_filters('formipay/notification/media', ['email'] );
$order_status = $order_data['status'];
if(!empty($medias)){
foreach($medias as $media){
do_action(
'formipay/notification/order/'.$media, $order_data
);
}
}
}
public function access_trigger($order_data) {
$medias = apply_filters('formipay/notification/media', ['email'] );
if(!empty($medias)){
foreach($medias as $media){
do_action(
'formipay/notification/access/'.$media, $order_data
);
}
}
}
}