diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..328b7d3 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,5 @@ +FROM wordpress:php7.2 + +WORKDIR /var/www/html/ + +COPY . ./wp-content/plugins/paystack diff --git a/admin/class-paystack-forms-admin.php b/admin/class-paystack-forms-admin.php new file mode 100644 index 0000000..0ad6995 --- /dev/null +++ b/admin/class-paystack-forms-admin.php @@ -0,0 +1,1092 @@ +plugin_name = $plugin_name; + $this->version = $version; + add_action('admin_menu', 'kkd_pff_paystack_add_settings_page'); + add_action('admin_init', 'kkd_pff_paystack_register_setting_page'); + + function kkd_pff_paystack_add_settings_page() + { + add_submenu_page('edit.php?post_type=paystack_form', 'Settings', 'Settings', 'edit_posts', basename(__FILE__), 'kkd_pff_paystack_setting_page'); + } + function kkd_pff_paystack_register_setting_page() + { + register_setting('kkd-pff-paystack-settings-group', 'mode'); + register_setting('kkd-pff-paystack-settings-group', 'tsk'); + register_setting('kkd-pff-paystack-settings-group', 'tpk'); + register_setting('kkd-pff-paystack-settings-group', 'lsk'); + register_setting('kkd-pff-paystack-settings-group', 'lpk'); + + register_setting('kkd-pff-paystack-settings-group', 'prc'); + register_setting('kkd-pff-paystack-settings-group', 'ths'); + register_setting('kkd-pff-paystack-settings-group', 'adc'); + register_setting('kkd-pff-paystack-settings-group', 'cap'); + } + function kkd_pff_paystack_txncheck($name, $txncharge) + { + if ($name == $txncharge) { + $result = "selected"; + } else { + $result = ""; + } + return $result; + } + function kkd_pff_paystack_setting_page() + { + ?> +
+

Paystack Forms Settings

+ + +

API Keys Settings

+ Get your API Keys here +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
Mode + +
Test Secret Key + +
Test Public Key
Live Secret Key
Live Public Key
+ +
+ + +

Fees Settings

+ + + + + + + + + + + + + + + + + + + + +
Percentage
Threshold
(amount above which Paystack adds the fixed amount below)
Additional Charge
(amount added to percentage fee when transaction amount is above threshold)
Cap
(maximum charge paystack can charge on your transactions)
+ + + +
+
+ _x('Paystack Forms', 'paystack_form'), + 'singular_name' => _x('Paystack Form', 'paystack_form'), + 'add_new' => _x('Add New', 'paystack_form'), + 'add_new_item' => _x('Add Paystack Form', 'paystack_form'), + 'edit_item' => _x('Edit Paystack Form', 'paystack_form'), + 'new_item' => _x('Paystack Form', 'paystack_form'), + 'view_item' => _x('View Paystack Form', 'paystack_form'), + 'all_items' => _x('All Forms', 'paystack_form'), + 'search_items' => _x('Search Paystack Forms', 'paystack_form'), + 'not_found' => _x('No Paystack Forms found', 'paystack_form'), + 'not_found_in_trash' => _x('No Paystack Forms found in Trash', 'paystack_form'), + 'parent_item_colon' => _x('Parent Paystack Form:', 'paystack_form'), + 'menu_name' => _x('Paystack Forms', 'paystack_form'), + ); + + $args = array( + 'labels' => $labels, + 'hierarchical' => true, + 'description' => 'Paystack Forms filterable by genre', + 'supports' => array('title', 'editor'), + 'public' => true, + 'show_ui' => true, + 'show_in_menu' => true, + 'menu_position' => 5, + 'menu_icon' => plugins_url('../images/logo.png', __FILE__), + 'show_in_nav_menus' => true, + 'publicly_queryable' => true, + 'exclude_from_search' => false, + 'has_archive' => false, + 'query_var' => true, + 'can_export' => true, + 'rewrite' => false, + 'comments' => false, + 'capability_type' => 'post' + ); + register_post_type('paystack_form', $args); + } + add_filter('user_can_richedit', 'kkd_pff_paystack_disable_wyswyg'); + + function kkd_pff_paystack_add_view_payments($actions, $post) + { + if (get_post_type() === 'paystack_form') { + unset($actions['view']); + unset($actions['quick edit']); + $url = add_query_arg( + array( + 'post_id' => $post->ID, + 'action' => 'submissions', + ) + ); + $actions['export'] = 'View Payments'; + } + return $actions; + } + add_filter('page_row_actions', 'kkd_pff_paystack_add_view_payments', 10, 2); + + + function kkd_pff_paystack_remove_fullscreen($qtInit) + { + $qtInit['buttons'] = 'fullscreen'; + return $qtInit; + } + function kkd_pff_paystack_disable_wyswyg($default) + { + global $post_type, $_wp_theme_features; + + + if ($post_type == 'paystack_form') { + echo ""; + add_action("admin_print_footer_scripts", "kkd_pff_paystack_shortcode_button_script"); + add_filter('user_can_richedit', '__return_false', 50); + add_action('wp_dashboard_setup', 'kkd_pff_paystack_remove_dashboard_widgets'); + remove_action('media_buttons', 'media_buttons'); + remove_meta_box('postimagediv', 'post', 'side'); + add_filter('quicktags_settings', 'kkd_pff_paystack_remove_fullscreen'); + } + + return $default; + } + function kkd_pff_paystack_remove_dashboard_widgets() + { + remove_meta_box('dashboard_right_now', 'dashboard', 'normal'); // Right Now + remove_meta_box('dashboard_recent_comments', 'dashboard', 'normal'); // Recent Comments + remove_meta_box('dashboard_incoming_links', 'dashboard', 'normal'); // Incoming Links + remove_meta_box('dashboard_plugins', 'dashboard', 'normal'); // Plugins + remove_meta_box('dashboard_quick_press', 'dashboard', 'side'); // Quick Press + remove_meta_box('dashboard_recent_drafts', 'dashboard', 'side'); // Recent Drafts + remove_meta_box('dashboard_primary', 'dashboard', 'side'); // WordPress blog + remove_meta_box('dashboard_secondary', 'dashboard', 'side'); // Other WordPress News + // use 'dashboard-network' as the second parameter to remove widgets from a network dashboard. + } + add_filter('manage_edit-paystack_form_columns', 'kkd_pff_paystack_edit_dashboard_header_columns'); + + function kkd_pff_paystack_edit_dashboard_header_columns($columns) + { + $columns = array( + 'cb' => '', + 'title' => __('Name'), + 'shortcode' => __('Shortcode'), + 'payments' => __('Payments'), + 'date' => __('Date') + ); + + return $columns; + } + add_action('manage_paystack_form_posts_custom_column', 'kkd_pff_paystack_dashboard_table_data', 10, 2); + + function kkd_pff_paystack_dashboard_table_data($column, $post_id) + { + global $post, $wpdb; + $table = $wpdb->prefix . KKD_PFF_PAYSTACK_TABLE; + + switch ($column) { + case 'shortcode': + echo ' + '; + + break; + case 'payments': + + $count_query = $wpdb->prepare("SELECT COUNT(*) FROM {$table} WHERE post_id = %d AND paid = '1'", $post_id); + $num = $wpdb->get_var($count_query); + + echo '' . $num . ''; + break; + default: + break; + } + } + add_filter('default_content', 'kkd_pff_paystack_editor_content', 10, 2); + + function kkd_pff_paystack_editor_content($content, $post) + { + switch ($post->post_type) { + case 'paystack_form': + $content = '[text name="Phone Number"]'; + break; + default: + $content = ''; + break; + } + + return $content; + } + ///// + function kkd_pff_paystack_editor_help_metabox($post) + { + do_meta_boxes(null, 'custom-metabox-holder', $post); + } + add_action('edit_form_after_title', 'kkd_pff_paystack_editor_help_metabox'); + + function kkd_pff_paystack_editor_help_metabox_details($post) + { + echo ''; ?> +
+ Email and Full Name field is added automatically, no need to include that.

+ To make an input field compulsory add required="required" to the shortcode

+ It should look like this [text name="Full Name" required="required" ]

+ + Warning: Using the file input field may cause data overload on your server. + Be sure you have enough server space before using it. You also have the ability to set file upload limits. + +
+ + +

+ + + +

+ + '; + + // Get the location data if its already been entered + $amount = get_post_meta($post->ID, '_amount', true); + $paybtn = get_post_meta($post->ID, '_paybtn', true); + $successmsg = get_post_meta($post->ID, '_successmsg', true); + $txncharge = get_post_meta($post->ID, '_txncharge', true); + $loggedin = get_post_meta($post->ID, '_loggedin', true); + $currency = get_post_meta($post->ID, '_currency', true); + $filelimit = get_post_meta($post->ID, '_filelimit', true); + $redirect = get_post_meta($post->ID, '_redirect', true); + $minimum = get_post_meta($post->ID, '_minimum', true); + $usevariableamount = get_post_meta($post->ID, '_usevariableamount', true); + $variableamount = get_post_meta($post->ID, '_variableamount', true); + $hidetitle = get_post_meta($post->ID, '_hidetitle', true); + + if ($amount == "") { + $amount = 0; + } + if ($filelimit == "") { + $filelimit = 2; + } + if ($paybtn == "") { + $paybtn = 'Pay'; + } + if ($successmsg == "") { + $successmsg = 'Thank you for paying!'; + } + if ($currency == "") { + $currency = 'NGN'; + } + if ($txncharge == "") { + $txncharge = 'merchant'; + } + if ($minimum == "") { + $minimum = 0; + } + if ($usevariableamount == "") { + $usevariableamount = 0; + } + if ($hidetitle == "") { + $hidetitle = 0; + } + if ($variableamount == "") { + $variableamount = ''; + } + // Echo out the field + + + if ($hidetitle == 1) { + echo ''; + } else { + echo ''; + } + echo "
"; + echo '

Currency:

'; + echo ''; + echo 'Ensure you are activated for the currency you are selecting. Check here for more information.'; + echo '

Amount to be paid(Set 0 for customer input):

'; + echo ''; + if ($minimum == 1) { + echo '
'; + } else { + echo '
'; + } + echo '

Variable Dropdown Amount:

'; + echo ''; + if ($usevariableamount == 1) { + echo '
'; + } else { + echo '
'; + } + echo '

Pay button Description:

'; + echo ''; + echo '

Add Extra Charge:

'; + echo ' +
This allows you include an extra charge to cushion the effect of the transaction fee. Configure'; + echo '

User logged In:

'; + echo ''; + echo '

Success Message after Payment

'; + echo ''; + echo '

File Upload Limit(MB):

'; + echo ''; + echo '

Redirect to page link after payment(keep blank to use normal success message):

'; + echo ''; + } + function kkd_pff_paystack_editor_add_email_data() + { + global $post; + + // Noncename needed to verify where the data originated + echo ''; + + // Get the location data if its already been entered + $subject = get_post_meta($post->ID, '_subject', true); + $merchant = get_post_meta($post->ID, '_merchant', true); + $heading = get_post_meta($post->ID, '_heading', true); + $message = get_post_meta($post->ID, '_message', true); + $sendreceipt = get_post_meta($post->ID, '_sendreceipt', true); + $sendinvoice = get_post_meta($post->ID, '_sendinvoice', true); + + if ($subject == "") { + $subject = 'Thank you for your payment'; + } + if ($sendreceipt == "") { + $sendreceipt = 'yes'; + } + if ($sendinvoice == "") { + $sendinvoice = 'yes'; + } + if ($heading == "") { + $heading = "We've received your payment"; + } + if ($message == "") { + $message = 'Your payment was received and we appreciate it.'; + } + // Echo out the field + echo '

Send an invoices when a payment is attempted:

'; + echo ''; + echo '

Send Email Receipt:

'; + echo ''; + echo '

Email Subject:

'; + echo ''; + echo '

Merchant Name on Receipt:

'; + echo ''; + echo '

Email Heading:

'; + echo ''; + echo '

Email Body/Message:

'; + echo ''; + } + function kkd_pff_paystack_editor_add_recur_data() + { + global $post; + + // Noncename needed to verify where the data originated + echo ''; + + // Get the location data if its already been entered + $recur = get_post_meta($post->ID, '_recur', true); + $recurplan = get_post_meta($post->ID, '_recurplan', true); + + if ($recur == "") { + $recur = 'no'; + } + if ($recurplan == "") { + $recurplan = ''; + } + // Echo out the field + echo '

Recurring Payment:

'; + echo ''; + echo '

Paystack Recur Plan code:

'; + echo ' + Plan amount must match amount on extra form description.'; + } + function kkd_pff_paystack_reset_stock() + { + } + function kkd_pff_paystack_editor_add_quantity_data() + { + global $post; + + // Noncename needed to verify where the data originated + echo ''; + + // Get the location data if its already been entered + $usequantity = get_post_meta($post->ID, '_usequantity', true); + $useinventory = get_post_meta($post->ID, '_useinventory', true); + $inventory = get_post_meta($post->ID, '_inventory', true); + $sold = get_post_meta($post->ID, '_sold', true); + $quantity = get_post_meta($post->ID, '_quantity', true); + $quantityunit = get_post_meta($post->ID, '_quantityunit', true); + $recur = get_post_meta($post->ID, '_recur', true); + + if ($usequantity == "") { + $usequantity = 'no'; + } + if ($useinventory == "") { + $useinventory = "no"; + } + if ($quantity == "") { + $quantity = '10'; + } + if ($inventory == "") { + if ($sold !== "") { + $inventory = $sold; + } else { + $inventory = '1'; + } + } + if ($sold == "") { + $sold = '0'; + } + $stock = $inventory - $sold; + if ($quantityunit == "") { + $quantityunit = 'Quantity'; + } + + // Echo out the field + echo 'Allow your users pay in multiple quantity

Quantified Payment:

'; + if ($recur != "no") { + echo ''; + } else { + echo ''; + } + if ($usequantity == "yes") { + + echo '

Max payable quantity:

'; + echo ' + Your users only get to pay in quantities if the from amount is not set to zero and recur is set to none.'; + echo '

Unit of quantity:

'; + echo ' + What is the unit of this quantity? Default is Quantity.'; + + + echo '

Inventory Payment:

'; + echo ' + + Set maximum available items in stock + '; + } + if ($useinventory == "yes" && $usequantity == "yes") { + echo '

Total Inventory

'; + echo ''; + echo '

Already sold

'; + echo ' + +
'; + } + } + + function kkd_pff_paystack_editor_add_agreement_data() + { + global $post; + + // Noncename needed to verify where the data originated + echo ''; + + // Get the location data if its already been entered + $useagreement = get_post_meta($post->ID, '_useagreement', true); + $agreementlink = get_post_meta($post->ID, '_agreementlink', true); + + if ($useagreement == "") { + $useagreement = 'no'; + } + if ($agreementlink == "") { + $agreementlink = ''; + } + // Echo out the field + echo '

Use agreement checkbox:

'; + echo ''; + echo '

Agreement Page Link:

'; + echo ''; + } + function kkd_pff_paystack_editor_add_subaccount_data() + { + global $post; + + // Noncename needed to verify where the data originated + echo ''; + + // Get the location data if its already been entered + $subaccount = get_post_meta($post->ID, '_subaccount', true); + $txnbearer = get_post_meta($post->ID, '_txnbearer', true); + $merchantamount = get_post_meta($post->ID, '_merchantamount', true); + + + if ($subaccount == "") { + $subaccount = ''; + } + if ($merchantamount == "") { + $merchantamount = ''; + } + echo '

Sub Account code:

'; + echo ''; + echo '

Transaction Charge bearer:

'; + echo ''; + echo '

Merchant Amount:

'; + echo ''; + } + function kkd_pff_paystack_editor_add_startdateplan_data() + { + global $post; + + // Noncename needed to verify where the data originated + echo '

User subscribes to plan after number of days:

'; + echo ''; + + // Get the location data if its already been entered + $days = get_post_meta($post->ID, '_startdate_days', true); + $plan = get_post_meta($post->ID, '_startdate_plan_code', true); + $enabled = get_post_meta($post->ID, '_startdate_enabled', true); + + + if ($days == "") { + $days = ''; + } + if ($plan == "") { + $plan = ''; + } + if ($enabled == "") { + $enabled = 0; + } + echo '

Number of days:

'; + echo ''; + echo '

Plan:

'; + echo ''; + if ($enabled == 1) { + echo '


'; + } else { + echo '


'; + } + } + + function kkd_pff_paystack_save_data($post_id, $post) + { + if (!wp_verify_nonce(@$_POST['eventmeta_noncename'], plugin_basename(__FILE__))) { + return $post->ID; + } + + // Is the user allowed to edit the post or page? + if (!current_user_can('edit_post', $post->ID)) { + return $post->ID; + } + $form_meta['_inventory'] = $_POST['_inventory']; + $form_meta['_useinventory'] = $_POST['_useinventory']; + $form_meta['_amount'] = $_POST['_amount']; + $form_meta['_hidetitle'] = $_POST['_hidetitle']; + $form_meta['_minimum'] = $_POST['_minimum']; + + $form_meta['_variableamount'] = $_POST['_variableamount']; + $form_meta['_usevariableamount'] = $_POST['_usevariableamount']; + + $form_meta['_paybtn'] = $_POST['_paybtn']; + $form_meta['_currency'] = $_POST['_currency']; + $form_meta['_successmsg'] = $_POST['_successmsg']; + $form_meta['_txncharge'] = $_POST['_txncharge']; + $form_meta['_loggedin'] = $_POST['_loggedin']; + $form_meta['_filelimit'] = $_POST['_filelimit']; + $form_meta['_redirect'] = $_POST['_redirect']; + /// + $form_meta['_subject'] = $_POST['_subject']; + $form_meta['_merchant'] = $_POST['_merchant']; + $form_meta['_heading'] = $_POST['_heading']; + $form_meta['_message'] = $_POST['_message']; + $form_meta['_sendreceipt'] = $_POST['_sendreceipt']; + $form_meta['_sendinvoice'] = $_POST['_sendinvoice']; + /// + $form_meta['_recur'] = $_POST['_recur']; + $form_meta['_recurplan'] = $_POST['_recurplan']; + $form_meta['_usequantity'] = $_POST['_usequantity']; + $form_meta['_quantity'] = $_POST['_quantity']; + $form_meta['_sold'] = $_POST['_sold']; + $form_meta['_quantityunit'] = $_POST['_quantityunit']; + + $form_meta['_useagreement'] = $_POST['_useagreement']; + $form_meta['_agreementlink'] = $_POST['_agreementlink']; + $form_meta['_subaccount'] = $_POST['_subaccount']; + $form_meta['_txnbearer'] = $_POST['_txnbearer']; + $form_meta['_merchantamount'] = $_POST['_merchantamount']; + // Add values of $form_meta as custom fields + + //Custom Plan with Start Date + $form_meta['_startdate_days'] = $_POST['_startdate_days']; + $form_meta['_startdate_plan_code'] = $_POST['_startdate_plan_code']; + $form_meta['_startdate_enabled'] = $_POST['_startdate_enabled']; + + foreach ($form_meta as $key => $value) { // Cycle through the $form_meta array! + if ($post->post_type == 'revision') { + return; // Don't store custom data twice + } + $value = implode(',', (array) $value); // If $value is an array, make it a CSV (unlikely) + if (get_post_meta($post->ID, $key, false)) { // If the custom field already has a value + update_post_meta($post->ID, $key, $value); + } else { // If the custom field doesn't have a value + add_post_meta($post->ID, $key, $value); + } + if (!$value) { + delete_post_meta($post->ID, $key); // Delete if blank + } + } + } + add_action('save_post', 'kkd_pff_paystack_save_data', 1, 2); + } + + public function enqueue_styles($hook) + { + if ($hook != 'toplevel_page_submissions' && $hook != 'paystack_form_page_class-paystack-forms-admin') { + return; + } + wp_enqueue_style($this->plugin_name, plugin_dir_url(__FILE__) . 'css/paystack-forms-admin.css', array(), $this->version, 'all'); + } + public function enqueue_scripts() + { + wp_enqueue_script($this->plugin_name, plugin_dir_url(__FILE__) . 'js/paystack-forms-admin.js', array('jquery'), $this->version, false); + } + + /** + * Add settings action link to the plugins page. + * + * @since 1.0.0 + */ + public function add_action_links($links) + { + $settings_link = array( + '' . __('Settings', $this->plugin_name) . '', + ); + return array_merge($settings_link, $links); + } +} + +add_action('admin_menu', 'kkd_pff_paystack_register_newpage'); +function kkd_pff_paystack_register_newpage() +{ + add_menu_page('paystack', 'paystack', 'administrator', 'submissions', 'kkd_pff_paystack_payment_submissions'); + remove_menu_page('submissions'); +} + +function kkd_pff_paystack_payment_submissions() +{ + $id = $_GET['form']; + $obj = get_post($id); + if ($obj->post_type == 'paystack_form') { + $amount = get_post_meta($id, '_amount', true); + $thankyou = get_post_meta($id, '_successmsg', true); + $paybtn = get_post_meta($id, '_paybtn', true); + $loggedin = get_post_meta($id, '_loggedin', true); + $txncharge = get_post_meta($id, '_txncharge', true); + + $exampleListTable = new Kkd_Pff_Paystack_Payments_List_Table(); + $data = $exampleListTable->prepare_items(); ?> +
+
+

post_title); ?> Payments

+

All payments made for this form

+ 0) { + ?> + +
+ + + +
+ + +

+
+
+
+
+ display(); ?> +
+ prefix . KKD_PFF_PAYSTACK_TABLE; + $data = array(); + $table = sanitize_text_field($table); + + $alldbdata = $wpdb->get_results($wpdb->prepare("SELECT * FROM {$table} WHERE post_id = %d AND paid = '1' ORDER BY `id` ASC", $post_id)); + $i = 0; + + if (count($alldbdata) > 0) { + $header = $alldbdata[0]; + $csv_output .= "#,"; + $csv_output .= "Email,"; + $csv_output .= "Amount,"; + $csv_output .= "Date Paid,"; + $csv_output .= "Reference,"; + $new = json_decode($header->metadata); + $text = ''; + if (array_key_exists("0", $new)) { + foreach ($new as $key => $item) { + $csv_output .= Kkd_pff_prep_csv_data($item->display_name) . ","; + } + } else { + if (count($new) > 0) { + foreach ($new as $key => $item) { + $csv_output .= Kkd_pff_prep_csv_data($key) . ","; + } + } + } + $csv_output .= "\n"; + + foreach ($alldbdata as $key => $dbdata) { + $newkey = $key + 1; + if ($dbdata->txn_code_2 != "") { + $txn_code = $dbdata->txn_code_2; + } else { + $txn_code = $dbdata->txn_code; + } + $csv_output .= Kkd_pff_prep_csv_data($newkey) . ","; + $csv_output .= Kkd_pff_prep_csv_data($dbdata->email) . ","; + $csv_output .= Kkd_pff_prep_csv_data($currency . ' ' . $dbdata->amount) . ","; + $csv_output .= Kkd_pff_prep_csv_data(substr($dbdata->paid_at, 0, 10)) . ","; + $csv_output .= Kkd_pff_prep_csv_data($txn_code) . ","; + $new = json_decode($dbdata->metadata); + $text = ''; + if (array_key_exists("0", $new)) { + foreach ($new as $key => $item) { + $csv_output .= Kkd_pff_prep_csv_data($item->value) . ","; + } + } else { + if (count($new) > 0) { + foreach ($new as $key => $item) { + $csv_output .= Kkd_pff_prep_csv_data($item) . ","; + } + } + } + $csv_output .= "\n"; + } + + + $filename = $obj->post_title . "_payments_" . date("Y-m-d_H-i", time()); + header("Content-type: application/vnd.ms-excel"); + header("Content-disposition: csv" . date("Y-m-d") . ".csv"); + header("Content-disposition: filename=" . $filename . ".csv"); + print $csv_output; + exit; + } + + + // Handle request then generate response using echo or leaving PHP and using HTML +} + +class Kkd_Pff_Paystack_Wp_List_Table +{ + public function __construct() + { + add_action('admin_menu', array($this, 'add_menu_example_list_table_page')); + } + public function add_menu_example_list_table_page() + { + add_menu_page('', '', 'manage_options', 'example-list-table.php', array($this, 'list_table_page')); + } + public function list_table_page() + { + $exampleListTable = new Example_List_Table(); + $exampleListTable->prepare_items($data); ?> +
+
+ display(); ?> +
+ $item) { + if ($item->type == 'text') { + $text .= '' . $item->display_name . ": " . $item->value . "
"; + } else { + $text .= '' . $item->display_name . ": link
"; + } + } + } else { + $text = ''; + if (count($new) > 0) { + foreach ($new as $key => $item) { + $text .= '' . $key . ": " . $item . "
"; + } + } + } + // + return $text; +} + +class Kkd_Pff_Paystack_Payments_List_Table extends WP_List_Table +{ + public function prepare_items() + { + $post_id = $_GET['form']; + $currency = get_post_meta($post_id, '_currency', true); + + global $wpdb; + + $table = $wpdb->prefix . KKD_PFF_PAYSTACK_TABLE; + $data = array(); + $alldbdata = $wpdb->get_results($wpdb->prepare("SELECT * FROM {$table} WHERE post_id = %d AND paid = '1'", $post_id)); + foreach ($alldbdata as $key => $dbdata) { + $newkey = $key + 1; + if ($dbdata->txn_code_2 != "") { + $txn_code = $dbdata->txn_code_2; + } else { + $txn_code = $dbdata->txn_code; + } + $data[] = array( + 'id' => $newkey, + 'email' => '' . $dbdata->email . '', + 'amount' => $currency . '' . number_format($dbdata->amount) . '', + 'txn_code' => $txn_code, + 'metadata' => format_data($dbdata->metadata), + 'date' => $dbdata->created_at + ); + } + + $columns = $this->get_columns(); + $hidden = $this->get_hidden_columns(); + $sortable = $this->get_sortable_columns(); + usort($data, array(&$this, 'sort_data')); + $perPage = 20; + $currentPage = $this->get_pagenum(); + $totalItems = count($data); + $this->set_pagination_args( + array( + 'total_items' => $totalItems, + 'per_page' => $perPage + ) + ); + $data = array_slice($data, (($currentPage - 1) * $perPage), $perPage); + $this->_column_headers = array($columns, $hidden, $sortable); + $this->items = $data; + + $rows = count($alldbdata); + return $rows; + } + + public function get_columns() + { + $columns = array( + 'id' => '#', + 'email' => 'Email', + 'amount' => 'Amount', + 'txn_code' => 'Txn Code', + 'metadata' => 'Data', + 'date' => 'Date' + ); + return $columns; + } + /** + * Define which columns are hidden + * + * @return Array + */ + public function get_hidden_columns() + { + return array(); + } + public function get_sortable_columns() + { + return array('email' => array('email', false), 'date' => array('date', false), 'amount' => array('amount', false)); + } + /** + * Get the table data + * + * @return Array + */ + private function table_data($data) + { + return $data; + } + /** + * Define what data to show on each column of the table + * + * @param Array $item Data + * @param String $column_name - Current column name + * + * @return Mixed + */ + public function column_default($item, $column_name) + { + switch ($column_name) { + case 'id': + case 'email': + case 'amount': + case 'txn_code': + case 'metadata': + case 'date': + return $item[$column_name]; + default: + return print_r($item, true); + } + } + + /** + * Allows you to sort the data by the variables set in the $_GET + * + * @return Mixed + */ + private function sort_data($a, $b) + { + $orderby = 'date'; + $order = 'desc'; + if (!empty($_GET['orderby'])) { + $orderby = $_GET['orderby']; + } + if (!empty($_GET['order'])) { + $order = $_GET['order']; + } + $result = strcmp($a[$orderby], $b[$orderby]); + if ($order === 'asc') { + return $result; + } + return -$result; + } +} diff --git a/admin/css/paystack-forms-admin.css b/admin/css/paystack-forms-admin.css new file mode 100644 index 0000000..e79a17e --- /dev/null +++ b/admin/css/paystack-forms-admin.css @@ -0,0 +1,413 @@ +/** + * All of the CSS for your admin-specific functionality should be + * included in this file. + */ + +#titlediv .inside p.description { + margin: 8px 2px 0; +} + +#titlediv .inside p.description label { + cursor: pointer; +} + +span.shortcode { + display: block; + margin: 2px 0; +} + +span.shortcode.old { + background: #777; + color: #fff; +} + +span.shortcode > input { + background: inherit; + color: inherit; + font-size: 12px; + border: none; + box-shadow: none; + padding: 4px 8px; + margin: 0; +} + +#submitpost input.copy { + margin-bottom: 10px; +} + +#submitpost input.delete { + padding: 0; + margin: 0; + border: none; + cursor: pointer; + background: inherit; + color: #a00; +} + +#submitpost input.delete:hover { + color: #f00; +} + +#submitpost input.delete:focus { + outline: thin dotted; +} + +.postbox-container .postbox h3 { + border-bottom: 1px solid transparent; +} + +.keyboard-interaction { + visibility: hidden; + color: #23282d; +} + +#misc-publishing-actions .misc-pub-section::before { + content: "\f488"; + -moz-osx-font-smoothing: grayscale; + display: inline-block; + font: 20px/1 dashicons; + left: -1px; + padding: 0 2px 0 0; + position: relative; + text-decoration: none !important; + top: 0; + vertical-align: top; + color: #82878c; +} + +#misc-publishing-actions .misc-pub-section.warning::before { + content: "\f534"; +} + +#misc-publishing-actions .misc-pub-section.warning a.external { + font-style: italic; +} + +div.config-error, span.config-error, ul.config-error { + color: #d00; + font-style: normal; + font-size: 13px; +} + +ul.config-error { + margin: 0; +} + +ul.config-error li { + padding: 0 4px; + margin: 0; +} + +ul.config-error li a.external { + font-style: italic; +} + +[data-config-field][aria-invalid="true"] { + border-color: #d00; +} + +/* + * Tabs + */ +#contact-form-editor-tabs { + border-bottom: 1px solid #aaa; + padding: 9px 15px 0 10px; + margin: 0; +} + +#contact-form-editor-tabs li { + display: inline-block; + list-style: none; + border: 1px solid #ccc; + border-bottom: 1px solid #aaa; + padding: 0; + margin: 0 4px -1px; + background-color: #e4e4e4; +} + +#contact-form-editor-tabs li:hover { + background-color: #fff; +} + +#contact-form-editor-tabs li.ui-tabs-active, +#contact-form-editor-tabs li.ui-tabs-active:hover { + border-top: 1px solid #aaa; + border-right: 1px solid #aaa; + border-left: 1px solid #aaa; + border-bottom: 1px solid #f5f5f5; + background-color: #f5f5f5; +} + +#contact-form-editor-tabs li a { + padding: 6px 10px; + font-size: 14px; + font-weight: normal; + line-height: 30px; + color: #333; + text-decoration: none; +} + +#contact-form-editor-tabs li.ui-tabs-active a { + color: #000; + font-size: 14px; + font-weight: bold; +} + +#contact-form-editor-tabs li a:hover { + color: #000; +} + +#contact-form-editor .contact-form-editor-panel h2 { + font-size: 18px; + font-weight: 400; + line-height: 24px; + margin: 8px 0; + padding: 0; +} + +#contact-form-editor .contact-form-editor-panel { + background-color: #f5f5f5; + border: 1px solid #aaa; + border-top: none; + padding: 16px; +} + +#contact-form-editor .form-table th { + width: 100px; +} + +#contact-form-editor .contact-form-editor-panel fieldset legend { + line-height: 1.5; + margin: .6em 0 .4em; +} + +/* + * Form Panel + */ +#tag-generator-list a.button { + font-size: 12px; + height: 26px; + line-height: 24px; + margin: 2px; + padding: 0 8px 1px; +} + +.tag-generator-panel { + position: relative; + height: 495px; +} + +.tag-generator-panel .control-box { + padding: 0; + margin: 0; + height: 380px; + overflow: auto; +} + +.tag-generator-panel .control-box > fieldset legend { + border: 1px solid #dfdfdf; + border-left: 4px solid #00a0d2; + background: #f7fcfe; + padding: 4px 12px; + margin: 4px 0; + line-height: 1.4em; + width: 95%; +} + +.tag-generator-panel table { + width: 100%; +} + +.tag-generator-panel table.form-table th { + width: 120px; + padding: 4px 10px 4px 0; + font-size: 13px; +} + +.tag-generator-panel table.form-table td { + padding: 4px 10px; + font-size: 13px; +} + +.tag-generator-panel .control-box input.oneline { + width: 200px; +} + +.tag-generator-panel .control-box textarea.values { + width: 200px; + height: 6em; +} + +.tag-generator-panel .control-box input[type="number"], +.tag-generator-panel .control-box input[type="date"] { + width: 88px; +} + +.tag-generator-panel .control-box table caption { + text-align: left; + font-size: 110%; + font-weight: bold; + color: #777; + margin: 10px 0 5px; +} + +.tag-generator-panel .control-box table.form-table td label { + line-height: 1.1em; +} + +.tag-generator-panel .control-box table.form-table td label .description { + line-height: 1.4em; +} + +.tag-generator-panel .insert-box { + position: absolute; + left: -15px; + right: -15px; + bottom: -15px; + width: 100%; + height: 84px; + margin: 0; + padding: 8px 16px; + background-color: #fcfcfc; + border-top: 1px solid #dfdfdf; + overflow: auto; +} + +.tag-generator-panel .insert-box input.tag { + width: 480px; + float: left; + background-color: transparent; + box-shadow: none; +} + +.tag-generator-panel .insert-box .submitbox { + padding: 2px 4px; +} + +.tag-generator-panel .insert-box .submitbox input[type="button"] { + float: right; +} + +.tag-generator-panel .insert-box .description label { + cursor: text; +} + +/* + * Mail Panel + */ +.contact-form-editor-box-mail span.mailtag { + display: inline-block; + margin: 0 0 0 4px; + padding: 1px 2px; + cursor: pointer; + color: #000; +} + +.contact-form-editor-box-mail span.mailtag.used { + color: #666; +} + +/* + * Messages Panel + */ +#messages-panel p.description { + margin: 5px 0 10px; +} + +/* + * List Table + */ +.fixed .column-title { + width: 38%; +} + +.fixed .column-shortcode { + width: 38%; +} + +/* + * Welcome Panel + */ +.welcome-panel h3 { + font-size: 16px; + font-weight: 600; + line-height: 2.1em; + margin: 1.33em 0 0; +} + +.welcome-panel p.message { + line-height: 1.4em; + margin-right: 25px; +} + +.welcome-panel li { + margin-bottom: 12px; +} + +.welcome-panel-close { + z-index: 2; +} + +/* + * Integration + */ +.card { + background: #fff none repeat scroll 0 0; + border: 1px solid #e5e5e5; + border-left: 4px solid #e5e5e5; + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.04); + margin-top: 20px; + max-width: 520px; + min-width: 255px; + padding: 0.7em 2em 1em; + position: relative; +} + +.card.active { + border-color: #00a0d2; +} + +.card img.icon { + float: left; + margin: 8px 8px 8px -8px; +} + +.card h2.title { + float: left; + max-width: 240px; + font-size: 1.3em; + font-weight: 600; +} + +.card .infobox { + float: right; + font-size: 13px; + color: #666; + margin: 2px 0 5px; + line-height: 1.5; + max-width: 240px; +} + +.card .inside .form-table th { + padding: 15px 10px 15px 0; + width: 160px; +} + +.card .inside .form-table td { + padding: 10px 10px; +} + + +.paystack_setting_page input{ + width: 50%; +} +#custom-metabox-holder-sortables{ + margin-top:30px; +} + +.wp-list-table .column-id { width: 5%; } +.wp-list-table .column-email { width: 20%; } +.wp-list-table .column-metadata { width: 35%; } +.wp-list-table .column-amount { width: 10%; } +.wp-list-table .column-txn_code { width: 15%; } +.wp-list-table .column-date { width: 10%; } diff --git a/admin/index.php b/admin/index.php new file mode 100644 index 0000000..e71af0e --- /dev/null +++ b/admin/index.php @@ -0,0 +1 @@ + input { - background: inherit; - color: inherit; - font-size: 12px; - border: none; - box-shadow: none; - padding: 4px 8px; - margin: 0; -} - -#submitpost input.copy { - margin-bottom: 10px; -} -#submitpost input.delete { - padding: 0; - margin: 0; - border: none; - cursor: pointer; - background: inherit; - color: #a00; -} -#submitpost input.delete:hover { - color: #f00; -} -#submitpost input.delete:focus { - outline: thin dotted; -} - -.postbox-container .postbox h3 { - border-bottom: 1px solid transparent; -} - -.keyboard-interaction { - visibility: hidden; - color: #23282d; -} - -#misc-publishing-actions .misc-pub-section::before { - content: "\f488"; - -moz-osx-font-smoothing: grayscale; - display: inline-block; - font: 20px/1 dashicons; - left: -1px; - padding: 0 2px 0 0; - position: relative; - text-decoration: none !important; - top: 0; - vertical-align: top; - color: #82878c; -} -#misc-publishing-actions .misc-pub-section.warning::before { - content: "\f534"; -} -#misc-publishing-actions .misc-pub-section.warning a.external { - font-style: italic; -} - -.config-error { - color: #d00; - font-style: normal; - font-size: 13px; -} -.config-error ul, -.config-error span, -.config-error div { - margin: 0; -} -.config-error ul li, -.config-error span li, -.config-error div li { - padding: 0 4px; - margin: 0; -} -.config-error ul li a.external, -.config-error span li a.external, -.config-error div li a.external { - font-style: italic; -} - -[data-config-field][aria-invalid=true] { - border-color: #d00; -} - -/* - * Tabs - */ -#contact-form-editor-tabs { - border-bottom: 1px solid #aaa; - padding: 9px 15px 0 10px; - margin: 0; -} -#contact-form-editor-tabs li { - display: inline-block; - list-style: none; - border: 1px solid #ccc; - border-bottom: 1px solid #aaa; - padding: 0; - margin: 0 4px -1px; - background-color: #e4e4e4; -} -#contact-form-editor-tabs li:hover { - background-color: #fff; -} -#contact-form-editor-tabs li.ui-tabs-active, #contact-form-editor-tabs li.ui-tabs-active:hover { - border-top: 1px solid #aaa; - border-right: 1px solid #aaa; - border-left: 1px solid #aaa; - border-bottom: 1px solid #f5f5f5; - background-color: #f5f5f5; -} -#contact-form-editor-tabs li a { - padding: 6px 10px; - font-size: 14px; - font-weight: normal; - line-height: 30px; - color: #333; - text-decoration: none; -} -#contact-form-editor-tabs li a:hover { - color: #000; -} -#contact-form-editor-tabs li.ui-tabs-active a { - color: #000; - font-size: 14px; - font-weight: bold; -} - -#contact-form-editor .contact-form-editor-panel { - background-color: #f5f5f5; - border: 1px solid #aaa; - border-top: none; - padding: 16px; -} -#contact-form-editor .contact-form-editor-panel h2 { - font-size: 18px; - font-weight: 400; - line-height: 24px; - margin: 8px 0; - padding: 0; -} -#contact-form-editor .contact-form-editor-panel fieldset legend { - line-height: 1.5; - margin: 0.6em 0 0.4em; -} -#contact-form-editor .form-table th { - width: 100px; -} - -/* - * Form Panel - */ -#tag-generator-list a.button { - font-size: 12px; - height: 26px; - line-height: 24px; - margin: 2px; - padding: 0 8px 1px; -} - -.tag-generator-panel { - position: relative; - height: 495px; -} -.tag-generator-panel .control-box { - padding: 0; - margin: 0; - height: 380px; - overflow: auto; -} -.tag-generator-panel .control-box > fieldset legend { - border: 1px solid #dfdfdf; - border-left: 4px solid #00a0d2; - background: #f7fcfe; - padding: 4px 12px; - margin: 4px 0; - line-height: 1.4em; - width: 95%; -} -.tag-generator-panel .control-box input.oneline { - width: 200px; -} -.tag-generator-panel .control-box textarea.values { - width: 200px; - height: 6em; -} -.tag-generator-panel .control-box input[type=number], -.tag-generator-panel .control-box input[type=date] { - width: 88px; -} -.tag-generator-panel .control-box table { - width: 100%; -} -.tag-generator-panel .control-box table .form-table th { - width: 120px; - padding: 4px 10px 4px 0; - font-size: 13px; -} -.tag-generator-panel .control-box table .form-table td { - padding: 4px 10px; - font-size: 13px; -} -.tag-generator-panel .control-box table .form-table td label { - line-height: 1.1em; -} -.tag-generator-panel .control-box table .form-table td label .description { - line-height: 1.4em; -} -.tag-generator-panel .control-box table caption { - text-align: left; - font-size: 110%; - font-weight: bold; - color: #777; - margin: 10px 0 5px; -} -.tag-generator-panel .insert-box { - position: absolute; - left: -15px; - right: -15px; - bottom: -15px; - width: 100%; - height: 84px; - margin: 0; - padding: 8px 16px; - background-color: #fcfcfc; - border-top: 1px solid #dfdfdf; - overflow: auto; -} -.tag-generator-panel .insert-box input.tag { - width: 480px; - float: left; - background-color: transparent; - box-shadow: none; -} -.tag-generator-panel .insert-box .submitbox { - padding: 2px 4px; -} -.tag-generator-panel .insert-box .submitbox input[type=button] { - float: right; -} -.tag-generator-panel .insert-box .description label { - cursor: text; -} - -/* - * Mail Panel - */ -.contact-form-editor-box-mail span.mailtag { - display: inline-block; - margin: 0 0 0 4px; - padding: 1px 2px; - cursor: pointer; - color: #000; -} -.contact-form-editor-box-mail span.mailtag.used { - color: #666; -} - -/* - * Messages Panel - */ -#messages-panel p.description { - margin: 5px 0 10px; -} - -/* - * List Table - */ -.fixed .column-title { - width: 38%; -} -.fixed .column-shortcode { - width: 38%; -} - -/* - * Welcome Panel - */ -.welcome-panel h3 { - font-size: 16px; - font-weight: 600; - line-height: 2.1em; - margin: 1.33em 0 0; -} -.welcome-panel p.message { - line-height: 1.4em; - margin-right: 25px; -} -.welcome-panel li { - margin-bottom: 12px; -} -.welcome-panel-close { - z-index: 2; -} - -/* - * Integration - */ -.card { - background: #fff none repeat scroll 0 0; - border: 1px solid #e5e5e5; - border-left: 4px solid #e5e5e5; - box-shadow: 0 1px 1px rgba(0, 0, 0, 0.04); - margin-top: 20px; - max-width: 520px; - min-width: 255px; - padding: 0.7em 2em 1em; - position: relative; -} -.card.active { - border-color: #00a0d2; -} -.card img.icon { - float: left; - margin: 8px 8px 8px -8px; -} -.card h2.title { - float: left; - max-width: 240px; - font-size: 1.3em; - font-weight: 600; -} -.card .infobox { - float: right; - font-size: 13px; - color: #666; - margin: 2px 0 5px; - line-height: 1.5; - max-width: 240px; -} -.card .inside .form-table th { - padding: 15px 10px 15px 0; - width: 160px; -} -.card .inside .form-table td { - padding: 10px 10px; -} - -.paystack_setting_page input { - width: 50%; -} - -#custom-metabox-holder-sortables { - margin-top: 30px; -} - -.wp-list-table .column-id { - width: 5%; -} -.wp-list-table .column-email { - width: 20%; -} -.wp-list-table .column-metadata { - width: 35%; -} -.wp-list-table .column-amount { - width: 10%; -} -.wp-list-table .column-txn_code { - width: 15%; -} -.wp-list-table .column-date { - width: 10%; -} -/*# sourceMappingURL=paystack-admin.css.map */ \ No newline at end of file diff --git a/assets/css/paystack-admin.css.map b/assets/css/paystack-admin.css.map deleted file mode 100644 index b60c189..0000000 --- a/assets/css/paystack-admin.css.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["paystack-admin.scss","paystack-admin.css"],"names":[],"mappings":"AAEE;EACC,iBAAA;ACDH;ADGG;EACC,eAAA;ACDJ;;ADOA;EACC,cAAA;EACA,aAAA;ACJD;ADMC;EACC,gBAAA;EACA,WAAA;ACJF;ADOC;EACC,mBAAA;EACA,cAAA;EACA,eAAA;EACA,YAAA;EACA,gBAAA;EACA,gBAAA;EACA,SAAA;ACLF;;ADUC;EACC,mBAAA;ACPF;ADUC;EACC,UAAA;EACA,SAAA;EACA,YAAA;EACA,eAAA;EACA,mBAAA;EACA,WAAA;ACRF;ADUE;EACC,WAAA;ACRH;ADWE;EACC,oBAAA;ACTH;;ADcA;EACC,oCAAA;ACXD;;ADcA;EACC,kBAAA;EACA,cAAA;ACXD;;ADgBE;EACC,gBAAA;EACA,kCAAA;EACA,qBAAA;EACA,sBAAA;EACA,UAAA;EACA,kBAAA;EACA,kBAAA;EACA,gCAAA;EACA,MAAA;EACA,mBAAA;EACA,cAAA;ACbH;ADgBE;EACC,gBAAA;ACdH;ADiBE;EACC,kBAAA;ACfH;;ADoBA;EACC,WAAA;EACA,kBAAA;EACA,eAAA;ACjBD;ADmBC;;;EAGC,SAAA;ACjBF;ADmBE;;;EACC,cAAA;EACA,SAAA;ACfH;ADiBG;;;EACC,kBAAA;ACbJ;;ADmBA;EACC,kBAAA;AChBD;;ADmBA;;EAAA;AAGC;EACG,6BAAA;EACA,wBAAA;EACA,SAAA;AChBJ;ADkBI;EACI,qBAAA;EACA,gBAAA;EACA,sBAAA;EACA,6BAAA;EACA,UAAA;EACA,kBAAA;EACA,yBAAA;AChBR;ADkBQ;EACI,sBAAA;AChBZ;ADmBQ;EAEI,0BAAA;EACA,4BAAA;EACA,2BAAA;EACA,gCAAA;EACA,yBAAA;AClBZ;ADqBQ;EACI,iBAAA;EACA,eAAA;EACA,mBAAA;EACA,iBAAA;EACA,WAAA;EACA,qBAAA;ACnBZ;ADqBY;EACI,WAAA;ACnBhB;ADuBQ;EACI,WAAA;EACA,eAAA;EACA,iBAAA;ACrBZ;;AD2BI;EACI,yBAAA;EACA,sBAAA;EACA,gBAAA;EACA,aAAA;ACxBR;AD0BQ;EACI,eAAA;EACA,gBAAA;EACA,iBAAA;EACA,aAAA;EACA,UAAA;ACxBZ;AD2BQ;EACI,gBAAA;EACA,qBAAA;ACzBZ;AD6BI;EACI,YAAA;AC3BR;;AD+BA;;EAAA;AAII;EACI,eAAA;EACA,YAAA;EACA,iBAAA;EACA,WAAA;EACA,kBAAA;AC7BR;;ADiCA;EACI,kBAAA;EACA,aAAA;AC9BJ;ADgCI;EACI,UAAA;EACA,SAAA;EACA,aAAA;EACA,cAAA;AC9BR;ADgCQ;EACI,yBAAA;EACA,8BAAA;EACA,mBAAA;EACA,iBAAA;EACA,aAAA;EACA,kBAAA;EACA,UAAA;AC9BZ;ADiCQ;EACI,YAAA;AC/BZ;ADkCQ;EACI,YAAA;EACA,WAAA;AChCZ;ADmCQ;;EAEI,WAAA;ACjCZ;ADoCQ;EACI,WAAA;AClCZ;ADqCgB;EACI,YAAA;EACA,uBAAA;EACA,eAAA;ACnCpB;ADsCgB;EACI,iBAAA;EACA,eAAA;ACpCpB;ADsCoB;EACI,kBAAA;ACpCxB;ADsCwB;EACI,kBAAA;ACpC5B;AD0CY;EACI,gBAAA;EACA,eAAA;EACA,iBAAA;EACA,WAAA;EACA,kBAAA;ACxChB;AD6CI;EACI,kBAAA;EACA,WAAA;EACA,YAAA;EACA,aAAA;EACA,WAAA;EACA,YAAA;EACA,SAAA;EACA,iBAAA;EACA,yBAAA;EACA,6BAAA;EACA,cAAA;AC3CR;AD6CQ;EACI,YAAA;EACA,WAAA;EACA,6BAAA;EACA,gBAAA;AC3CZ;AD8CQ;EACI,gBAAA;AC5CZ;AD8CY;EACI,YAAA;AC5ChB;ADgDQ;EACI,YAAA;AC9CZ;;ADmDA;;EAAA;AAII;EACI,qBAAA;EACA,iBAAA;EACA,gBAAA;EACA,eAAA;EACA,WAAA;ACjDR;ADmDQ;EACI,WAAA;ACjDZ;;ADsDA;;EAAA;AAII;EACI,kBAAA;ACpDR;;ADwDA;;EAAA;AAII;EACI,UAAA;ACtDR;ADyDI;EACI,UAAA;ACvDR;;AD2DA;;EAAA;AAII;EACI,eAAA;EACA,gBAAA;EACA,kBAAA;EACA,kBAAA;ACzDR;AD4DI;EACI,kBAAA;EACA,kBAAA;AC1DR;AD6DI;EACI,mBAAA;AC3DR;AD8DI;EACI,UAAA;AC5DR;;ADgEA;;EAAA;AAGA;EACI,uCAAA;EACA,yBAAA;EACA,8BAAA;EACA,yCAAA;EACA,gBAAA;EACA,gBAAA;EACA,gBAAA;EACA,sBAAA;EACA,kBAAA;AC7DJ;AD+DI;EACI,qBAAA;AC7DR;ADgEI;EACI,WAAA;EACA,wBAAA;AC9DR;ADiEI;EACI,WAAA;EACA,gBAAA;EACA,gBAAA;EACA,gBAAA;AC/DR;ADkEI;EACI,YAAA;EACA,eAAA;EACA,WAAA;EACA,iBAAA;EACA,gBAAA;EACA,gBAAA;AChER;ADqEY;EACI,yBAAA;EACA,YAAA;ACnEhB;ADsEY;EACI,kBAAA;ACpEhB;;AD2EI;EACI,UAAA;ACxER;;AD4EA;EACI,gBAAA;ACzEJ;;AD6EI;EACI,SAAA;AC1ER;AD6EI;EACI,UAAA;AC3ER;AD8EI;EACI,UAAA;AC5ER;AD+EI;EACI,UAAA;AC7ER;ADgFI;EACI,UAAA;AC9ER;ADiFI;EACI,UAAA;AC/ER","file":"paystack-admin.css"} \ No newline at end of file diff --git a/assets/css/paystack-admin.scss b/assets/css/paystack-admin.scss deleted file mode 100644 index 990ecf8..0000000 --- a/assets/css/paystack-admin.scss +++ /dev/null @@ -1,459 +0,0 @@ -#titlediv { - .inside { - p.description { - margin: 8px 2px 0; - - label { - cursor: pointer; - } - } - } -} - -span.shortcode { - display: block; - margin: 2px 0; - - &.old { - background: #777; - color: #fff; - } - - > input { - background: inherit; - color: inherit; - font-size: 12px; - border: none; - box-shadow: none; - padding: 4px 8px; - margin: 0; - } -} - -#submitpost { - input.copy { - margin-bottom: 10px; - } - - input.delete { - padding: 0; - margin: 0; - border: none; - cursor: pointer; - background: inherit; - color: #a00; - - &:hover { - color: #f00; - } - - &:focus { - outline: thin dotted; - } - } -} - -.postbox-container .postbox h3 { - border-bottom: 1px solid transparent; -} - -.keyboard-interaction { - visibility: hidden; - color: #23282d; -} - -#misc-publishing-actions { - .misc-pub-section { - &::before { - content: "\f488"; - -moz-osx-font-smoothing: grayscale; - display: inline-block; - font: 20px/1 dashicons; - left: -1px; - padding: 0 2px 0 0; - position: relative; - text-decoration: none !important; - top: 0; - vertical-align: top; - color: #82878c; - } - - &.warning::before { - content: "\f534"; - } - - &.warning a.external { - font-style: italic; - } - } -} - -.config-error { - color: #d00; - font-style: normal; - font-size: 13px; - - ul, - span, - div { - margin: 0; - - li { - padding: 0 4px; - margin: 0; - - a.external { - font-style: italic; - } - } - } -} - -[data-config-field][aria-invalid="true"] { - border-color: #d00; -} - -/* - * Tabs - */ - #contact-form-editor-tabs { - border-bottom: 1px solid #aaa; - padding: 9px 15px 0 10px; - margin: 0; - - li { - display: inline-block; - list-style: none; - border: 1px solid #ccc; - border-bottom: 1px solid #aaa; - padding: 0; - margin: 0 4px -1px; - background-color: #e4e4e4; - - &:hover { - background-color: #fff; - } - - &.ui-tabs-active, - &.ui-tabs-active:hover { - border-top: 1px solid #aaa; - border-right: 1px solid #aaa; - border-left: 1px solid #aaa; - border-bottom: 1px solid #f5f5f5; - background-color: #f5f5f5; - } - - a { - padding: 6px 10px; - font-size: 14px; - font-weight: normal; - line-height: 30px; - color: #333; - text-decoration: none; - - &:hover { - color: #000; - } - } - - &.ui-tabs-active a { - color: #000; - font-size: 14px; - font-weight: bold; - } - } -} - -#contact-form-editor { - .contact-form-editor-panel { - background-color: #f5f5f5; - border: 1px solid #aaa; - border-top: none; - padding: 16px; - - h2 { - font-size: 18px; - font-weight: 400; - line-height: 24px; - margin: 8px 0; - padding: 0; - } - - fieldset legend { - line-height: 1.5; - margin: .6em 0 .4em; - } - } - - .form-table th { - width: 100px; - } -} - -/* - * Form Panel - */ - #tag-generator-list { - a.button { - font-size: 12px; - height: 26px; - line-height: 24px; - margin: 2px; - padding: 0 8px 1px; - } -} - -.tag-generator-panel { - position: relative; - height: 495px; - - .control-box { - padding: 0; - margin: 0; - height: 380px; - overflow: auto; - - > fieldset legend { - border: 1px solid #dfdfdf; - border-left: 4px solid #00a0d2; - background: #f7fcfe; - padding: 4px 12px; - margin: 4px 0; - line-height: 1.4em; - width: 95%; - } - - input.oneline { - width: 200px; - } - - textarea.values { - width: 200px; - height: 6em; - } - - input[type="number"], - input[type="date"] { - width: 88px; - } - - table { - width: 100%; - - .form-table { - th { - width: 120px; - padding: 4px 10px 4px 0; - font-size: 13px; - } - - td { - padding: 4px 10px; - font-size: 13px; - - label { - line-height: 1.1em; - - .description { - line-height: 1.4em; - } - } - } - } - - caption { - text-align: left; - font-size: 110%; - font-weight: bold; - color: #777; - margin: 10px 0 5px; - } - } - } - - .insert-box { - position: absolute; - left: -15px; - right: -15px; - bottom: -15px; - width: 100%; - height: 84px; - margin: 0; - padding: 8px 16px; - background-color: #fcfcfc; - border-top: 1px solid #dfdfdf; - overflow: auto; - - input.tag { - width: 480px; - float: left; - background-color: transparent; - box-shadow: none; - } - - .submitbox { - padding: 2px 4px; - - input[type="button"] { - float: right; - } - } - - .description label { - cursor: text; - } - } -} - -/* - * Mail Panel - */ - .contact-form-editor-box-mail { - span.mailtag { - display: inline-block; - margin: 0 0 0 4px; - padding: 1px 2px; - cursor: pointer; - color: #000; - - &.used { - color: #666; - } - } -} - -/* - * Messages Panel - */ -#messages-panel { - p.description { - margin: 5px 0 10px; - } -} - -/* - * List Table - */ -.fixed { - .column-title { - width: 38%; - } - - .column-shortcode { - width: 38%; - } -} - -/* - * Welcome Panel - */ -.welcome-panel { - h3 { - font-size: 16px; - font-weight: 600; - line-height: 2.1em; - margin: 1.33em 0 0; - } - - p.message { - line-height: 1.4em; - margin-right: 25px; - } - - li { - margin-bottom: 12px; - } - - &-close { - z-index: 2; - } -} - -/* - * Integration - */ -.card { - background: #fff none repeat scroll 0 0; - border: 1px solid #e5e5e5; - border-left: 4px solid #e5e5e5; - box-shadow: 0 1px 1px rgba(0, 0, 0, 0.04); - margin-top: 20px; - max-width: 520px; - min-width: 255px; - padding: 0.7em 2em 1em; - position: relative; - - &.active { - border-color: #00a0d2; - } - - img.icon { - float: left; - margin: 8px 8px 8px -8px; - } - - h2.title { - float: left; - max-width: 240px; - font-size: 1.3em; - font-weight: 600; - } - - .infobox { - float: right; - font-size: 13px; - color: #666; - margin: 2px 0 5px; - line-height: 1.5; - max-width: 240px; - } - - .inside { - .form-table { - th { - padding: 15px 10px 15px 0; - width: 160px; - } - - td { - padding: 10px 10px; - } - } - } -} - -.paystack_setting_page { - input { - width: 50%; - } -} - -#custom-metabox-holder-sortables { - margin-top: 30px; -} - -.wp-list-table { - .column-id { - width: 5%; - } - - .column-email { - width: 20%; - } - - .column-metadata { - width: 35%; - } - - .column-amount { - width: 10%; - } - - .column-txn_code { - width: 15%; - } - - .column-date { - width: 10%; - } -} \ No newline at end of file diff --git a/banner-772x250.png b/banner-772x250.png new file mode 100644 index 0000000..242c2f5 Binary files /dev/null and b/banner-772x250.png differ diff --git a/icon-256x256.png b/icon-256x256.png new file mode 100644 index 0000000..5fb6f77 Binary files /dev/null and b/icon-256x256.png differ diff --git a/icon.png b/icon.png new file mode 100644 index 0000000..8b40dab Binary files /dev/null and b/icon.png differ diff --git a/assets/images/cardlogos.png b/images/cardlogos.png similarity index 100% rename from assets/images/cardlogos.png rename to images/cardlogos.png diff --git a/assets/images/logo.png b/images/logo.png similarity index 100% rename from assets/images/logo.png rename to images/logo.png diff --git a/assets/images/logos@2x.png b/images/logos@2x.png similarity index 100% rename from assets/images/logos@2x.png rename to images/logos@2x.png diff --git a/includes/class-paystack-forms-activator.php b/includes/class-paystack-forms-activator.php new file mode 100644 index 0000000..4c3fb02 --- /dev/null +++ b/includes/class-paystack-forms-activator.php @@ -0,0 +1,88 @@ +prefix . KKD_PFF_PAYSTACK_TABLE; + $table_name = sanitize_text_field($table_name); + $charset_collate = $wpdb->get_charset_collate(); + + $sql = "CREATE TABLE IF NOT EXISTS `" . $table_name . "` ( + id int(11) NOT NULL AUTO_INCREMENT, + post_id int(11) NOT NULL, + user_id int(11) NOT NULL, + email varchar(255) DEFAULT '' NOT NULL, + metadata text, + paid int(1) NOT NULL DEFAULT '0', + plan varchar(255) DEFAULT '' NOT NULL, + txn_code varchar(255) DEFAULT '' NOT NULL, + txn_code_2 varchar(255) DEFAULT '' NOT NULL, + amount varchar(255) DEFAULT '' NOT NULL, + ip varchar(255) NOT NULL, + deleted_at varchar(255) DEFAULT '' NULL, + created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + paid_at timestamp, + modified timestamp DEFAULT '0000-00-00 00:00:00' NOT NULL, + UNIQUE KEY id (id),PRIMARY KEY (id) + ) $charset_collate;"; + + include_once ABSPATH . 'wp-admin/includes/upgrade.php'; + dbDelta($sql); + + if (version_compare($version, '2.0') < 0) { + $sql = "CREATE TABLE IF NOT EXISTS `" . $table_name . "` ( + id int(11) NOT NULL AUTO_INCREMENT, + post_id int(11) NOT NULL, + user_id int(11) NOT NULL, + email varchar(255) DEFAULT '' NOT NULL, + metadata text, + paid int(1) NOT NULL DEFAULT '0', + plan varchar(255) DEFAULT '' NOT NULL, + txn_code varchar(255) DEFAULT '' NOT NULL, + txn_code_2 varchar(255) DEFAULT '' NOT NULL, + amount varchar(255) DEFAULT '' NOT NULL, + paid_at timestamp, + ip varchar(255) NOT NULL, + deleted_at varchar(255) DEFAULT '' NULL, + created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + modified timestamp DEFAULT '0000-00-00 00:00:00' NOT NULL, + UNIQUE KEY id (id),PRIMARY KEY (id) + ) $charset_collate;"; + + dbDelta($sql); + + update_option('kkd_db_version', '2.0'); + } + + + $query = $wpdb->prepare( + "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = %s AND column_name = 'plan'", + $table_name + ); + + $row = $wpdb->get_results($query); + if (empty($row)) { + $wpdb->query("ALTER TABLE `" . $table_name . "` ADD `plan` VARCHAR(255) NOT NULL AFTER `paid`;"); + } + + $row1 = $wpdb->get_results( + "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS + WHERE table_name = '" . $table_name . "' AND column_name = 'txn_code_2'" + ); + if (empty($row1)) { + $wpdb->query("ALTER TABLE `" . $table_name . "` ADD `txn_code_2` VARCHAR(255) DEFAULT '' NULL AFTER `txn_code`;"); + } + + $row1 = $wpdb->get_results( + "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS + WHERE table_name = '" . $table_name . "' AND column_name = 'paid_at'" + ); + if (empty($row1)) { + $wpdb->query("ALTER TABLE `" . $table_name . "` ADD `paid_at` timestamp AFTER `created_at`;"); + } + } +} diff --git a/includes/class-paystack-forms-deactivator.php b/includes/class-paystack-forms-deactivator.php new file mode 100644 index 0000000..a720328 --- /dev/null +++ b/includes/class-paystack-forms-deactivator.php @@ -0,0 +1,19 @@ +actions = array(); + $this->filters = array(); + + } + + /** + * Add a new action to the collection to be registered with WordPress. + * + * @since 1.0.0 + * @param string $hook The name of the WordPress action that is being registered. + * @param object $component A reference to the instance of the object on which the action is defined. + * @param string $callback The name of the function definition on the $component. + * @param int $priority Optional. he priority at which the function should be fired. Default is 10. + * @param int $accepted_args Optional. The number of arguments that should be passed to the $callback. Default is 1. + */ + public function add_action( $hook, $component, $callback, $priority = 10, $accepted_args = 1 ) + { + $this->actions = $this->add($this->actions, $hook, $component, $callback, $priority, $accepted_args); + } + + /** + * Add a new filter to the collection to be registered with WordPress. + * + * @param string $hook The name of the WordPress filter that is being registered. + * @param object $component A reference to the instance of the object on which the filter is defined. + * @param string $callback The name of the function definition on the $component. + * @param int $priority Optional. he priority at which the function should be fired. Default is 10. + * @param int $accepted_args Optional. The number of arguments that should be passed to the $callback. Default is 1 + * + * @return null + * + * @since 1.0.0 + */ + public function add_filter( $hook, $component, $callback, $priority = 10, $accepted_args = 1 ) + { + $this->filters = $this->add($this->filters, $hook, $component, $callback, $priority, $accepted_args); + } + + /** + * A utility function that is used to register the actions and hooks into a single + * collection. + * + * @since 1.0.0 + * @access private + * @param array $hooks The collection of hooks that is being registered (that is, actions or filters). + * @param string $hook The name of the WordPress filter that is being registered. + * @param object $component A reference to the instance of the object on which the filter is defined. + * @param string $callback The name of the function definition on the $component. + * @param int $priority The priority at which the function should be fired. + * @param int $accepted_args The number of arguments that should be passed to the $callback. + * @return array The collection of actions and filters registered with WordPress. + */ + private function add( $hooks, $hook, $component, $callback, $priority, $accepted_args ) + { + + $hooks[] = array( + 'hook' => $hook, + 'component' => $component, + 'callback' => $callback, + 'priority' => $priority, + 'accepted_args' => $accepted_args + ); + + return $hooks; + + } + + /** + * Register the filters and actions with WordPress. + * + * @since 1.0.0 + */ + public function run() + { + + foreach ( $this->filters as $hook ) { + add_filter($hook['hook'], array( $hook['component'], $hook['callback'] ), $hook['priority'], $hook['accepted_args']); + } + + foreach ( $this->actions as $hook ) { + add_action($hook['hook'], array( $hook['component'], $hook['callback'] ), $hook['priority'], $hook['accepted_args']); + } + + } + +} diff --git a/includes/class-paystack-forms.php b/includes/class-paystack-forms.php new file mode 100644 index 0000000..938553b --- /dev/null +++ b/includes/class-paystack-forms.php @@ -0,0 +1,261 @@ +plugin_name = 'pff-paystack'; + $this->version = '2.0.0'; + + $this->load_dependencies(); + $this->set_locale(); + $this->define_admin_hooks(); + $this->define_public_hooks(); + add_action('init', array( &$this, 'setup_tinymce_plugin' )); + + + } + /** + * Check if the current user can edit Posts or Pages, and is using the Visual Editor + * If so, add some filters so we can register our plugin + */ + function setup_tinymce_plugin() + { + + // Check if the logged in WordPress User can edit Posts or Pages + // If not, don't register our TinyMCE plugin + if (! current_user_can('edit_posts') && ! current_user_can('edit_pages') ) { + return; + } + + // Check if the logged in WordPress User has the Visual Editor enabled + // If not, don't register our TinyMCE plugin + if (get_user_option('rich_editing') !== 'true' ) { + return; + } + + // Setup some filters + add_filter('mce_external_plugins', array( &$this, 'add_tinymce_plugin' )); + add_filter('mce_buttons', array( &$this, 'add_tinymce_toolbar_button' )); + + } + + /** + * Adds a TinyMCE plugin compatible JS file to the TinyMCE / Visual Editor instance + * + * @param array $plugin_array Array of registered TinyMCE Plugins + * @return array Modified array of registered TinyMCE Plugins + */ + function add_tinymce_plugin( $plugin_array ) + { + + $plugin_array['custom_class'] = plugin_dir_url(__FILE__) . 'tinymce-custom-class.js'; + return $plugin_array; + + } + + /** + * Adds a button to the TinyMCE / Visual Editor which the user can click + * to insert a custom CSS class. + * + * @param array $buttons Array of registered TinyMCE Buttons + * @return array Modified array of registered TinyMCE Buttons + */ + function add_tinymce_toolbar_button( $buttons ) + { + + array_push($buttons, 'custom_class'); + return $buttons; + + } + + /** + * Load the required dependencies for this plugin. + * + * Include the following files that make up the plugin: + * + * - Paystack_Forms_Loader. Orchestrates the hooks of the plugin. + * - Paystack_Forms_i18n. Defines internationalization functionality. + * - Paystack_Forms_Admin. Defines all hooks for the admin area. + * - Paystack_Forms_Public. Defines all hooks for the public side of the site. + * + * Create an instance of the loader which will be used to register the hooks + * with WordPress. + * + * @since 1.0.0 + * @access private + */ + private function load_dependencies() + { + + /** + * The class responsible for orchestrating the actions and filters of the + * core plugin. + */ + include_once plugin_dir_path(dirname(__FILE__)) . 'includes/class-paystack-forms-loader.php'; + + /** + * The class responsible for defining internationalization functionality + * of the plugin. + */ + include_once plugin_dir_path(dirname(__FILE__)) . 'includes/class-paystack-forms-i18n.php'; + + /** + * The class responsible for defining all actions that occur in the admin area. + */ + include_once plugin_dir_path(dirname(__FILE__)) . 'admin/class-paystack-forms-admin.php'; + + /** + * The class responsible for defining all actions that occur in the public-facing + * side of the site. + */ + include_once plugin_dir_path(dirname(__FILE__)) . 'public/class-paystack-forms-public.php'; + // require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/paystack-webhook.php'; + + $this->loader = new Kkd_Pff_Paystack_Loader(); + + } + + /** + * Define the locale for this plugin for internationalization. + * + * Uses the Paystack_Forms_i18n class in order to set the domain and to register the hook + * with WordPress. + * + * @since 1.0.0 + * @access private + */ + private function set_locale() + { + + $plugin_i18n = new Kkd_Pff_Paystack_i18n(); + + $this->loader->add_action('plugins_loaded', $plugin_i18n, 'load_plugin_textdomain'); + + } + + /** + * Register all of the hooks related to the admin area functionality + * of the plugin. + * + * @since 1.0.0 + * @access private + */ + private function define_admin_hooks() + { + + $plugin_admin = new Kkd_Pff_Paystack_Admin($this->get_plugin_name(), $this->get_version()); + + $this->loader->add_action('admin_enqueue_scripts', $plugin_admin, 'enqueue_styles'); + $this->loader->add_action('admin_enqueue_scripts', $plugin_admin, 'enqueue_scripts'); + + // Add Settings link to the plugin + $this->loader->add_filter( + 'plugin_action_links_' . KKD_PFF_PLUGIN_BASENAME, + $plugin_admin, + 'add_action_links' + ); + } + + /** + * Register all of the hooks related to the public-facing functionality + * of the plugin. + * + * @since 1.0.0 + * @access private + */ + private function define_public_hooks() + { + + $plugin_public = new Kkd_Pff_Paystack_Public($this->get_plugin_name(), $this->get_version()); + + $this->loader->add_action('wp_enqueue_scripts', $plugin_public, 'enqueue_styles'); + $this->loader->add_action('wp_enqueue_scripts', $plugin_public, 'enqueue_scripts'); + + } + + /** + * Run the loader to execute all of the hooks with WordPress. + * + * @since 1.0.0 + */ + public function run() + { + $this->loader->run(); + } + + /** + * The name of the plugin used to uniquely identify it within the context of + * WordPress and to define internationalization functionality. + * + * @since 1.0.0 + * @return string The name of the plugin. + */ + public function get_plugin_name() + { + return $this->plugin_name; + } + + /** + * The reference to the class that orchestrates the hooks with the plugin. + * + * @since 1.0.0 + * @return Paystack_Forms_Loader Orchestrates the hooks of the plugin. + */ + public function get_loader() + { + return $this->loader; + } + + /** + * Retrieve the version number of the plugin. + * + * @since 1.0.0 + * @return string The version number of the plugin. + */ + public function get_version() + { + return $this->version; + } + +} diff --git a/includes/classes/class-activation.php b/includes/classes/class-activation.php deleted file mode 100644 index d0c5d4a..0000000 --- a/includes/classes/class-activation.php +++ /dev/null @@ -1,141 +0,0 @@ -prefix . PFF_PAYSTACK_TABLE; - $table_name = sanitize_text_field( $table_name ); - - // Include the DB Functions. - include_once ABSPATH . 'wp-admin/includes/upgrade.php'; - - Activation::create_tables( $table_name ); - Activation::maybe_upgrade( $table_name ); - update_option( 'kkd_db_version', '2.0' ); - } - - /** - * Install Paystack DB Table - */ - public static function create_tables( $table_name ) { - global $wpdb; - $query = "CREATE TABLE IF NOT EXISTS `{$table_name}` ( - id int(11) NOT NULL AUTO_INCREMENT, - post_id int(11) NOT NULL, - user_id int(11) NOT NULL, - email varchar(255) DEFAULT '' NOT NULL, - metadata text, - paid int(1) NOT NULL DEFAULT '0', - plan varchar(255) DEFAULT '' NOT NULL, - txn_code varchar(255) DEFAULT '' NOT NULL, - txn_code_2 varchar(255) DEFAULT '' NOT NULL, - amount varchar(255) DEFAULT '' NOT NULL, - ip varchar(255) NOT NULL, - deleted_at varchar(255) DEFAULT '' NULL, - created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - paid_at timestamp, - modified timestamp DEFAULT '0000-00-00 00:00:00' NOT NULL, - UNIQUE KEY id (id),PRIMARY KEY (id) - ) {$wpdb->get_charset_collate()};"; - dbDelta( $query ); - } - - /** - * Install Paystack DB Table - * - * This function supresses the following WPCS warnings because we dont want caching involved. - */ - public static function maybe_upgrade( $table_name ) { - global $wpdb; - - // Get the current version number, defaults to 1.0 - $version = get_option( 'kkd_db_version', '1.0' ); - - if ( version_compare( $version, '2.0' ) < 0 ) { - // Check if the plan column is there? - // phpcs:ignore WordPress.DB.DirectDatabaseQuery - $row = $wpdb->get_results( - $wpdb->prepare( - "SELECT COLUMN_NAME - FROM INFORMATION_SCHEMA.COLUMNS - WHERE table_name = %s - AND column_name = 'plan'", - $table_name - ) - ); - // Add in the plan column if not. - if ( empty( $row ) ) { - // phpcs:ignore WordPress.DB.DirectDatabaseQuery - $wpdb->query( - $wpdb->prepare( - // phpcs:ignore WordPress.DB.DirectDatabaseQuery - "ALTER TABLE %i ADD `plan` VARCHAR(255) NOT NULL AFTER `paid`;", - $table_name - ) - ); - } - - // Add in the txn_code_2 column. - // phpcs:ignore WordPress.DB.DirectDatabaseQuery - $row1 = $wpdb->get_results( - $wpdb->prepare( - "SELECT COLUMN_NAME - FROM INFORMATION_SCHEMA.COLUMNS - WHERE table_name = %s - AND column_name = 'txn_code_2'", - $table_name - ) - ); - if ( empty( $row1 ) ) { - // phpcs:ignore WordPress.DB.DirectDatabaseQuery - $wpdb->query( - $wpdb->prepare( - // phpcs:ignore WordPress.DB.DirectDatabaseQuery - "ALTER TABLE %i ADD `txn_code_2` VARCHAR(255) DEFAULT '' NULL AFTER `txn_code`;", - $table_name - ) - ); - } - - // Add in the paid_at column. - // phpcs:ignore WordPress.DB.DirectDatabaseQuery - $row2 = $wpdb->get_results( - $wpdb->prepare( - "SELECT COLUMN_NAME - FROM INFORMATION_SCHEMA.COLUMNS - WHERE table_name = %s - AND column_name = 'paid_at'", - $table_name - ) - ); - if ( empty( $row2 ) ) { - // phpcs:ignore WordPress.DB.DirectDatabaseQuery - $wpdb->query( - $wpdb->prepare( - // phpcs:ignore WordPress.DB.DirectDatabaseQuery - "ALTER TABLE %i ADD `paid_at` timestamp AFTER `created_at`;", - $table_name - ) - ); - } - } - } -} diff --git a/includes/classes/class-api.php b/includes/classes/class-api.php deleted file mode 100644 index 1d60c0a..0000000 --- a/includes/classes/class-api.php +++ /dev/null @@ -1,165 +0,0 @@ -public = esc_attr( get_option( 'tpk' ) ); - $this->secret = esc_attr( get_option( 'tsk' ) ); - } else { - $this->public = esc_attr( get_option( 'lpk' ) ); - $this->secret = esc_attr( get_option( 'lsk' ) ); - } - } - - /** - * Sets the module variable. - * - * @param string $module - * @return string - */ - protected function set_module( $module = '' ) { - $this->module = $module . '/'; - } - - /** - * Sets the additional URl arguments. - * - * @param string $module - * @return string - */ - protected function set_url_args( $args = '' ) { - $this->url_args = $args; - } - - /** - * Gets the headers for the current request. - * - * @return array - */ - protected function get_headers(){ - return array( - 'Authorization' => 'Bearer ' . $this->secret - ); - } - - /** - * Gets the headers for the current request. - * - * @return string - */ - protected function get_url(){ - return $this->url . $this->module . $this->url_args; - } - - /** - * Gets the arguments for the current request. - * - * @return array - */ - protected function get_args(){ - return array( - 'headers' => $this->get_headers(), - 'timeout' => 60 - ); - } - - /** - * Sends a GET request and checks to see is is_wp_error(). - * - * @return boolean|object - */ - public function get_request() { - $response = false; - $return = wp_remote_get( $this->get_url(), $this->get_args() ); - if ( ! is_wp_error( $return ) && 200 === wp_remote_retrieve_response_code( $return ) ) { - $response = json_decode( wp_remote_retrieve_body( $return ) ); - } - return $response; - } - - /** - * Sends a POST request and checks to see is is_wp_error(). - * - * @return boolean|object - */ - public function post_request( $body = [] ) { - $response = false; - $args = array( - 'body' => $body, - 'headers' => $this->get_headers(), - 'timeout' => 60, - ); - $return = wp_remote_post( $this->get_url(), $args ); - if ( ! empty( $body ) && ! is_wp_error( $return ) && 200 === wp_remote_retrieve_response_code( $return ) ) { - $response = json_decode( wp_remote_retrieve_body( $return ) ); - } - return $response; - } - - /** - * Determines if all the settings have been entered. - * - * @return boolean - */ - public function api_ready() { - $ready = false; - if ( '' !== $this->secret ) { - $ready = true; - } - return $ready; - } -} \ No newline at end of file diff --git a/includes/classes/class-confirm-payment.php b/includes/classes/class-confirm-payment.php deleted file mode 100644 index c94ab8e..0000000 --- a/includes/classes/class-confirm-payment.php +++ /dev/null @@ -1,332 +0,0 @@ -payment_meta = $payment; - $this->meta = $this->helpers->parse_meta_values( get_post( $this->payment_meta->post_id ) ); - $this->amount = $this->payment_meta->amount; - $this->oamount = $this->meta['amount']; - $this->form_id = $this->payment_meta->post_id; - - if ( 'customer' === $this->meta['txncharge'] ) { - $this->oamount = $this->helpers->process_transaction_fees( $this->oamount ); - } - } - - /** - * Confirm Payment Functionality. - */ - public function confirm_payment() { - - if ( ! isset( $_POST['nonce'] ) || false === wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce'] ) ), 'pff-paystack-confirm' ) ) { - $response = array( - 'error' => true, - 'error_message' => __( 'Nonce verification is required.', 'pff-paystack' ), - ); - - exit( wp_json_encode( $response ) ); - } - - // This is a false positive, we are using isset as WPCS suggest in the PCP plugin. - // phpcs:ignore WordPress.Security.ValidatedSanitizedInput - if ( ! isset( $_POST['code'] ) || '' === trim( wp_unslash( $_POST['code'] ) ) ) { - $response = array( - 'error' => true, - 'error_message' => __( 'Did you make a payment?', 'pff-paystack' ), - ); - - exit( wp_json_encode( $response ) ); - } - - // If this is a retry payment then set the colum accordingly. - if ( isset( $_POST['retry'] ) ) { - $this->txn_column = 'txn_code_2'; - } - - $this->helpers = new Helpers(); - $code = sanitize_text_field( wp_unslash( $_POST['code'] ) ); - $record = $this->helpers->get_db_record( $code, $this->txn_column ); - - if ( false !== $record ) { - - $this->setup_data( $record ); - - // Verify our transaction with the Paystack API. - $transaction = pff_paystack()->classes['transaction-verify']->verify_transaction( $code ); - - if ( ! empty( $transaction ) && isset( $transaction['data'] ) ) { - $transaction['data'] = json_decode( $transaction['data'] ); - if ( 'success' === $transaction['data']->status ) { - $this->update_sold_inventory(); - $response = $this->update_payment_dates( $transaction['data'] ); - } - } else { - $response = [ - 'message' => __( 'Failed to connect to Paystack.', 'pff-paystack' ), - 'result' => 'failed', - ]; - } - - } else { - $response = [ - 'message' => __( 'Payment Verification Failed', 'pff-paystack' ), - 'result' => 'failed', - ]; - } - - - // Create plan and send reciept. - if ( 'success' === $response['result'] ) { - - // Create a plan that the user will be subscribed to. - - /*$pstk_logger = new kkd_pff_paystack_plugin_tracker( 'pff-paystack', Kkd_Pff_Paystack_Public::fetchPublicKey() ); - $pstk_logger->log_transaction_success( $code );*/ - - $this->maybe_create_subscription(); - - - $sendreceipt = $this->meta['sendreceipt']; - if ( 'yes' === $sendreceipt ) { - $decoded = json_decode( $this->payment_meta->metadata ); - $fullname = $decoded[1]->value; - - /** - * Allow 3rd Party Plugins to hook into the email sending. - * - * 10: Email_Receipt::send_receipt(); - * 11: Email_Receipt_Owner::send_receipt_owner(); - */ - do_action( 'pff_paystack_send_receipt', - $this->payment_meta->post_id, - $this->payment_meta->currency, - $this->payment_meta->amount_paid, - $fullname, - $this->payment_meta->email, - $this->payment_meta->reference, - $this->payment_meta->metadata - ); - } - } - - if ( 'success' === $response['result'] && '' !== $this->meta['redirect'] ) { - $response['result'] = 'success2'; - $response['link'] = $this->meta['redirect']; - } - - echo wp_json_encode( $response ); - die(); - } - - /** - * Update the sold invetory with the amount of payments made. - * - * @return void - */ - protected function update_sold_inventory() { - $usequantity = $this->meta['usequantity']; - $sold = (int) $this->meta['sold']; - - if ( 'yes' === $usequantity ) { - $quantity = 1; - // Nonce is checked above in the parent function confirm_payment(). - // phpcs:ignore WordPress.Security.NonceVerification - if ( isset( $_POST['quantity'] ) ) { - // phpcs:ignore WordPress.Security.NonceVerification - $quantity = (int) sanitize_text_field( wp_unslash( $_POST['quantity'] ) ); - } - $sold = $this->meta['sold']; - - if ( '' === $sold ) { - $sold = '0'; - } - $sold += $quantity; - } else { - $sold++; - } - - if ( $this->meta['sold'] ) { - update_post_meta( $this->form_id, '_sold', $sold ); - } else { - add_post_meta( $this->form_id, '_sold', $sold, true ); - } - } - - /** - * Updates the paid Date for the current record. - * - * @param object $data - * @return array - */ - protected function update_payment_dates( $data ) { - global $wpdb; - $table = $wpdb->prefix . PFF_PAYSTACK_TABLE; - $return = [ - 'message' => __( 'DB not updated.', 'pff-paystack' ), - 'result' => 'failed', - ]; - - $amount_paid = $data->amount / 100; - $paystack_ref = $data->reference; - $paid_at = $data->transaction_date; - if ( 'optional' === $this->meta['recur'] || 'plan' === $this->meta['recur'] ) { - // phpcs:ignore WordPress.DB.DirectDatabaseQuery - $wpdb->update( - $table, - array( - 'paid' => 1, - 'amount' => $amount_paid, - 'paid_at' => $paid_at, - ), - array( $this->txn_column => $paystack_ref ) - ); - $return = [ - 'message' => $this->meta['successmsg'], - 'result' => 'success', - ]; - } else { - // If this the price paid was free, or if it was a variable amount. - if ( 0 === (int) $this->oamount || 1 === $this->meta['usevariableamount'] ) { - // phpcs:ignore WordPress.DB.DirectDatabaseQuery - $wpdb->update( - $table, - array( - 'paid' => 1, - 'amount' => $amount_paid, - 'paid_at' => $paid_at, - ), - array( $this->txn_column => $paystack_ref ) - ); - $return = [ - 'message' => $this->meta['successmsg'], - 'result' => 'success', - ]; - } else { - if ( $this->oamount !== $amount_paid ) { - $return = [ - // translators: %1$s: currency, %2$s: formatted amount required - 'message' => sprintf( __( 'Invalid amount Paid. Amount required is %1$s%2$s', 'pff-paystack' ), $this->meta['currency'], number_format( $this->oamount ) ), - 'result' => 'failed', - ]; - } else { - // phpcs:ignore WordPress.DB.DirectDatabaseQuery - $wpdb->update( - $table, - array( - 'paid' => 1, - 'paid_at' => $paid_at, - ), - array( $this->txn_column => $paystack_ref ) - ); - $return = [ - 'message' => $this->meta['successmsg'], - 'result' => 'success', - ]; - } - } - } - return $return; - } - - protected function maybe_create_subscription() { - // Create a "subscription" and attach it to the current plan code. - if ( 1 == $this->meta['startdate_enabled'] && ! empty( $this->meta['startdate_days'] ) && ! empty( $this->meta['startdate_plan_code'] ) ) { - $start_date = gmdate( 'c', strtotime( '+' . $this->meta['startdate_days'] . ' days' ) ); - $body = array( - 'start_date' => $start_date, - 'plan' => $this->meta['startdate_plan_code'], - 'customer' => $this->payment_meta->email, - ); - - $created_sub = pff_paystack()->classes['request-subscription']->create_subscription( $body ); - if ( false !== $created_sub ) { - // Nothing defined for this. - } - } - } -} \ No newline at end of file diff --git a/includes/classes/class-email-invoice.php b/includes/classes/class-email-invoice.php deleted file mode 100644 index 60f80b2..0000000 --- a/includes/classes/class-email-invoice.php +++ /dev/null @@ -1,236 +0,0 @@ -slug = 'invoice'; - $this->form_id = $form_id; - $this->amount = $amount; - $this->currency = $currency; - $this->code = $code; - $this->name = $name; - $this->email = stripslashes( $email ); - $this->referer_url = $referer_url; - - $this->subject = sprintf( - // Translators: %1$s is the currency code, %2$s is the formatted amount - __( 'Payment Invoice for %1$s %2$s', 'text-domain' ), - $currency, - number_format( $amount ) - ); - $this->reply_to = get_option( 'admin_email' ); - $this->reply_name = get_option( 'blogname' ); - $this->send(); - } - - public function get_html_body() { - ?> - -
-
- - - - - - -
-
-
- - - - - - -
-
-
-
-
- - - - - - -
-
-
- - - - - - -
-

- #code ); ?>

-
-
-
-
- - - - - - -
-
-
- - - - - - -
- -
name ); ?>
-

email ); ?>

-
-
-
- - - - - - -
-

currency ) . ' ' . number_format( $this->amount ); ?>

-
-
-
-
- - - - - - -
-
-
- - - - - - -
-

- -

- - - - - - -
- - - - - -
-

- - - -

-
-
-
-
- - - - - - - -
-
- - slug = 'receipt-owner'; - $this->amount = $amount; - $this->currency = $currency; - $this->code = $code; - $this->name = $name; - $this->email = stripslashes( $email ); - $this->metadata = $metadata; - - // Custom Values - $this->subject = __( 'You just received a payment' , 'pff-paystack' ); - $this->heading = get_post_meta( $form_id, '_heading', true ); - $this->sitemessage = get_post_meta( $form_id, '_message', true ); - - $this->reply_to = get_option( 'admin_email' ); - $this->reply_name = get_option( 'blogname' ); - $this->send(); - } - - public function get_html_body() { - ?> - -
- -
- - - - - - -
-
- - - - - - -
-
-
- - - - - - -
-

 

-
-
-
-
-
- - - - - - -
-
-
- - - - - - -
- - - - - - - - - - - - -
 
 
- -
-

- : currency ) . ' ' . number_format( $this->amount ); ?>
- : email ); ?>
- metadata ); - if ( array_key_exists( "0", $new ) ) { - foreach ( $new as $key => $item ) { - if ( 'text' === $item->type ) { - echo esc_html( $item->display_name ) . ' :' . esc_html( $item->value ) . '
'; - } else { - echo esc_html( $item->display_name ) . ' : ' . esc_html__( 'link', 'pff-paystack' ) . '
'; - } - } - } else { - if ( count( $new ) > 0 ) { - foreach ( $new as $key => $item ) { - echo esc_html( $key ) . ' :' . esc_html( $item ) . '
'; - } - } - } - ?> - : code ); ?>
-

-
-
-
-
- - - - - - -
- -
- -
- - - - - - -
-
- currency . ' ' . number_format( $this->amount ) ); ?> .
-
-
- -
-
- - - - - - - -
-
- - slug = 'receipt'; - $this->amount = $amount; - $this->currency = $currency; - $this->code = $code; - $this->name = $name; - $this->email = stripslashes( $email ); - $this->metadata = $metadata; - - // Custom Values - $this->subject = get_post_meta( $form_id, '_subject', true ); - $this->merchant = get_post_meta( $form_id, '_merchant', true ); - $this->heading = get_post_meta( $form_id, '_heading', true ); - $this->sitemessage = get_post_meta( $form_id, '_message', true ); - - $this->reply_to = get_option( 'admin_email' ); - $this->reply_name = get_option( 'blogname' ); - $this->send(); - } - - public function get_html_body() { - ?> - -
- -
- - - - - - -
- -
- - - - - - - -
- -
- -
- - - - - - -
-

 

-
- heading ); ?> -
-

- name . ' ', ' ', true ) ) - ); - ?> -

-

- sitemessage ); ?> -

-

 

-
-
- -
- -
- - - - - - - -
- -
- -
- - - - - - -
- - - - - - - - - - - - -
 
 
- -
-

- currency ), - esc_html( number_format_i18n( $this->amount ) ) - ); - ?>
- email ) - ); - ?>
- metadata ); - if ( array_key_exists( '0', $new ) ) { - foreach ( $new as $key => $item ) { - if ( 'text' === $item->type ) { - echo sprintf( - /* translators: %1$s: Display name, %2$s: Value */ - '%1$s : %2$s
', - esc_html( $item->display_name ), - esc_html( $item->value ) - ); - } else { - echo sprintf( - /* translators: %s: Display name */ - '%1$s : link
', - esc_html( $item->display_name ), - esc_url( $item->value ) - ); - } - } - } else { - if ( count( (array) $new ) > 0 ) { - foreach ( $new as $key => $item ) { - echo sprintf( - /* translators: %1$s: Key, %2$s: Item */ - '%1$s : %2$s
', - esc_html( $key ), - esc_html( $item ) - ); - } - } - } - printf( - /* translators: %s: Transaction code */ - esc_html__( 'Transaction code: %s', 'pff-paystack' ), - esc_html( $this->code ) - ); - ?>
-

-
-
-
- -
- - - - - - - -
- -
- -
- - - - - - -
- -
- currency . ' ' . number_format_i18n( $this->amount ) ) - ); - ?> - - - . -
-
-
- -
-
- - - - - - - - - -
-
- - get_html_header(); - $this->get_html_body(); - $this->get_html_footer(); - $message = ob_get_contents(); - ob_end_clean(); - return $message; - } - - public function get_html_header() { - ?> - - - - - - - - - - - - - - - - - - - - - reply_to}", - "From: {$this->reply_name} <{$this->reply_to}>" - ); - } - - public function send() { - wp_mail( $this->email, $this->subject, $this->get_email_body(), $this->get_headers() ); - } -} \ No newline at end of file diff --git a/includes/classes/class-field-shortcodes.php b/includes/classes/class-field-shortcodes.php deleted file mode 100644 index e0a09a1..0000000 --- a/includes/classes/class-field-shortcodes.php +++ /dev/null @@ -1,309 +0,0 @@ - __( 'Title', 'pff-paystack' ), - 'required' => '0', - ), - $atts, - 'text' - ); - - $name = sanitize_text_field( $atts['name'] ); - $required = $atts['required'] === 'required' ? 'required' : ''; - $id = uniqid( 'text-' ); - - $code = '
- -
-
'; - - return $code; - } - /** - * Generates the "textarea" field. - * - * @param array $atts - * @return string - */ - public function textarea_field( $atts ) { - $atts = shortcode_atts( - array( - 'name' => __( 'Title', 'pff-paystack' ), - 'required' => '0', - ), - $atts, - 'textarea' - ); - - $name = sanitize_text_field( $atts['name'] ); - $required = $atts['required'] === 'required' ? 'required' : ''; - - $id = uniqid( 'textarea-' ); - - $code = '
'; - $code .= ''; - $code .= '
'; - $code .= '
'; - - return $code; - } - /** - * Generates the "checkbot" input field. - * - * @param array $atts - * @return string - */ - public function checkbox_field( $atts ) { - $atts = shortcode_atts( - array( - 'name' => __( 'Title', 'pff-paystack' ), - 'options' => '', - 'required' => '0', - ), - $atts, - 'checkbox' - ); - - $name = sanitize_text_field( $atts['name'] ); - $options = array_map( 'sanitize_text_field', explode( ',', $atts['options'] ) ); - $required = $atts['required'] === 'required' ? 'required' : ''; - - $code = '
'; - $code .= ''; - $code .= '
'; - - foreach ( $options as $option ) { - $id = uniqid( 'checkbox-' ); - $code .= ''; - } - - $code .= '
'; - - return $code; - } - /** - * Generates the general "input" input field. - * - * @param array $atts - * @return string - */ - public function input_field( $atts ) { - $atts = shortcode_atts( - array( - 'name' => __( 'Title', 'pff-paystack' ), - 'required' => '0', - ), - $atts, - 'input' - ); - - $name = sanitize_text_field( $atts['name'] ); - $required = $atts['required'] === 'required' ? 'required' : ''; - $fileInputId = uniqid( 'file-input-' ); - $textInputId = uniqid( 'text-input-' ); - - $code = '
'; - $code .= ''; - $code .= '
'; - $code .= '
'; - $code .= __( 'Browse', 'pff-paystack' ); - $code .= ''; - $code .= '
'; - $code .= ''; - $code .= '
'; - - return $code; - } - /** - * Generates the "datepicker" input field. - * - * @param array $atts - * @return string - */ - public function datepicker_field( $atts ) { - $atts = shortcode_atts( - array( - 'name' => __( 'Title', 'pff-paystack' ), - 'required' => '0', - ), - $atts, - 'datepicker' - ); - - $name = sanitize_text_field( $atts['name'] ); - $required = $atts['required'] === 'required' ? 'required' : ''; - $id = uniqid( 'datepicker-' ); - - $code = '
'; - $code .= ''; - $code .= '
'; - $code .= '
'; - - return $code; - } - /** - * Generates the "dropdown" select field. - * - * @param array $atts - * @return string - */ - public function select_field( $atts ) { - $atts = shortcode_atts( - array( - 'name' => __( 'Title', 'pff-paystack' ), - 'options' => '', - 'required' => '0', - ), - $atts, - 'select' - ); - - $name = sanitize_text_field( $atts['name'] ); - $options = array_map( 'sanitize_text_field', explode( ',', $atts['options'] ) ); - $required = $atts['required'] === 'required' ? 'required' : ''; - $id = uniqid( 'select-' ); - - $code = '
'; - $code .= ''; - $code .= '
'; - $code .= '
'; - - return $code; - } - /** - * Generates the "radio" input field. - * - * @param array $atts - * @return string - */ - public function radio_field( $atts ) { - $atts = shortcode_atts( - array( - 'name' => __( 'Title', 'pff-paystack' ), - 'options' => '', - 'required' => '0', - ), - $atts, - 'radio' - ); - - $name = sanitize_text_field( $atts['name'] ); - $options = array_map( 'sanitize_text_field', explode( ',', $atts['options'] ) ); - $required = $atts['required'] === 'required' ? 'required' : ''; - - $code = '
'; - $code .= ''; - $code .= '
'; - - foreach ( $options as $index => $option ) { - $id = uniqid( 'radio-' ); - $isChecked = $index == 0 ? 'checked' : ''; - $code .= ''; - } - - $code .= '
'; - - return $code; - } -} diff --git a/includes/classes/class-form-shortcode.php b/includes/classes/class-form-shortcode.php deleted file mode 100644 index 24a780d..0000000 --- a/includes/classes/class-form-shortcode.php +++ /dev/null @@ -1,563 +0,0 @@ - 0 - ); - $atts = shortcode_atts( - $defaults, - $atts, - 'paystack_form' - ); - $id = intval( $atts['id'] ); // Ensure $id is an integer - $this->helpers = Helpers::get_instance(); - - // First lets check for a public key. - $public_key = $this->helpers->get_public_key(); - if ( ! $public_key ) { - $settings_link = esc_url( get_admin_url( null, 'edit.php?post_type=paystack_form&page=settings' ) ); - return sprintf( - '
%s %s
', - esc_html__( 'You must set your Paystack API keys first', 'pff-paystack' ), - esc_url( $settings_link ), - esc_html__( 'settings', 'pff-paystack' ) - ); // Return early to avoid further processing - } - - // Store our items in an array and not an object. - $html = []; - - if ( $id > 0 ) { - $obj = get_post( $id ); - if ( null !== $obj && 'paystack_form' === get_post_type( $obj ) ) { - - $this->form = $obj; - $this->set_user_details(); - $this->set_meta_data( $obj ); - - // First lets see if this is for a retry payment. - $code = $this->get_code(); - if ( '' !== $code ) { - $html = $this->get_retry_form( $code ); - return implode( '', $html ); - } - - // Check if the form should be displayed based on user login status - $show_form = $this->should_show_form(); - - if ( $show_form ) { - // Form title - if ( $this->meta['hidetitle'] != 1 ) { - $html[] = "

" . esc_html( $obj->post_title ) . "

"; - } - - // Start form output - $html[] = '
-
'; - - // Hidden Fields - $html[] = $this->get_hidden_fields(); - // User fields - $html[] = $this->get_fullname_field(); - $html[] = $this->get_email_field(); - - // Amount selection with consideration for variable amounts, minimum payments, and recurring plans - $html[] = $this->get_amount_field(); - - $html[] = $this->get_quantity_field(); - - // Recurring payment options - $html[] = $this->get_recurring_field(); - $html[] = $this->get_recurring_plan_fields(); - - $html[] = do_shortcode( $obj->post_content ); - - $html[] = $this->get_agreement_field(); - - $html[] = $this->get_form_footer(); - - $html[] = '
'; - } else { - $html[] = '
' . __( 'You must be logged in to make a payment.', 'pff-paystack' ) . '
'; - } - } else { - $html[] = '
' . __( 'Invalid Paystack form ID or the form does not exist.', 'pff-paystack' ) . '
'; - } - } else { - $html[] = '
' . __( 'No Paystack form ID provided.', 'pff-paystack' ) . '
'; - } - - $html = implode( '', $html ); - - return $html; - } - - /** - * Get the code from the url query vars if it exists. - * - * @return void - */ - public function get_code() { - // We ignore this as we are not performing any update action with the data - // phpcs:ignore WordPress.Security.NonceVerification - $code = isset( $_GET['code'] ) ? sanitize_text_field( wp_unslash( $_GET['code'] ) ) : ''; - return $code; - } - - /** - * Set the user deteails based on the logged in wp_user - * - * @return void - */ - public function set_user_details() { - // Ensure the current user is populated - $this->user['logged_in'] = false; - $this->user['id'] = 0; - $this->user['fullname'] = ''; - $this->user['email'] = ''; - - if ( is_user_logged_in() ) { - $current_user = wp_get_current_user(); - $user['logged_in'] = true; - $this->user['id'] = $current_user->ID; - $this->user['email'] = $current_user->user_email; - $this->user['fname'] = sanitize_text_field( $current_user->user_firstname ); - $this->user['lname'] = sanitize_text_field( $current_user->user_lastname ); - $this->user['fullname'] = $this->user['fname'] || $this->user['lname'] ? trim( $this->user['fname'] . ' ' . $this->user['lname'] ) : ''; - } - } - - /** - * Set the user deteails based on the logged in wp_user - * - * @return void - */ - public function set_meta_data( $obj ) { - $this->meta = $this->helpers->parse_meta_values( $obj ); - if ( 1 === $this->meta['usevariableamount'] ) { - $this->meta['paymentoptions'] = explode( ',', $this->meta['variableamount'] ); - - $this->meta['paymentoptions'] = array_map( 'sanitize_text_field', $this->meta['paymentoptions'] ); - } - - $this->meta['planerrorcode'] = __( 'Input Correct Recurring Plan Code', 'pff-paystack' ); - - if ( 'plan' === $this->meta['recur'] ) { - if ( '' === $this->meta['recurplan'] ) { - $this->show_btn = false; - } else { - $this->plan = pff_paystack()->classes['request-plan']->fetch_plan( $this->meta['recurplan'] ); - if ( false !== $this->plan && isset( $this->plan->data->amount ) ) { - $this->has_plan = true; - $this->meta['planamount'] = $this->plan->data->amount / 100; - } else { - $this->show_btn = false; - } - } - } - } - - /** - * If we should show the form or not. - * - * @return boolean - */ - public function should_show_form() { - $show_form = false; - if ( 'no' === $this->meta['loggedin'] || ( 'yes' === $this->meta['loggedin'] && true === $this->user['logged_in'] ) ) { - $show_form = true; - } - return $show_form; - } - - /** - * Return the Hidden fields needed. - * @return string - */ - public function get_hidden_fields() { - // Hidden inputs - $html = ' - - - - ' . - wp_nonce_field( 'pff-paystack-invoice', 'pf-nonce', true, false ); - ; - return $html; - } - - /** - * Return the Fullname field. - * - * @return string - */ - public function get_fullname_field() { - $html = '
- -
- -
-
'; - return $html; - } - - /** - * Return the Email field. - * - * @return string - */ - public function get_email_field() { - $html = '
- -
- meta['loggedin'] == 'yes' ? 'readonly' : '' ) . ' required> -
-
'; - return $html; - } - - /** - * Get the amount field - * @return string - */ - public function get_amount_field() { - $html = []; - $html[] = '
- -
'; - - // If the amount is set. - if ( 0 === $this->meta['usevariableamount'] ) { - - if ($this->meta['minimum'] == 1) { - $html[] = ' Minimum payable amount ' . esc_html($this->meta['currency']) . ' ' . esc_html(number_format($this->meta['amount'])) . ''; - } - - if ($this->meta['recur'] == 'plan') { - if ( $this->show_btn ) { - $html[] = ''; - } else { - $html[] = '
- -
'; - } - } elseif ( $this->meta['recur'] == 'optional' ) { - $html[] = ''; - } else { - $html[] = 'meta['amount'] ) . '" id="pf-amount" ' . ( 0 !== $this->meta['amount'] && 1 !== $this->meta['minimum'] ? 'readonly' : '' ) . ' required />'; - } - - } else { - - if ( '' === $this->meta['variableamount'] || 0 === $this->meta['variableamount'] || ! is_array( $this->meta['paymentoptions'] ) ) { - $html[] = __( 'Form Error, set variable amount string', 'pff-paystack' ); - } else if ( count( $this->meta['paymentoptions'] ) > 0 ) { - $html[] = '
- - -
'; - } - } - - // Transaction charge notice - if ( 'merchant' !== $this->meta['txncharge'] && 'plan' !== $this->meta['recur'] ) { - $html[] = 'Transaction Charge: , Total:'; - } - - $html[] = '
'; - - return implode( '', $html ); - } - - /** - * Get the agreement checkbox and link. - * - * @return string - */ - public function get_agreement_field() { - $html = ''; - if ( 'yes' === $this->meta['useagreement'] ) { - $html = '
- -

'; - } - return $html; - } - - /** - * Get the form footer including the logos and the action buttons. - * - * @return string - */ - public function get_form_footer() { - $html = []; - - // Form submission controls - $html[] = '
- * are compulsory -
- cardlogos - '; - if ($this->show_btn) { - $html[] = ''; - } - $html[] = '
'; - return implode( '', $html ); - } - - /** - * Gets the quantity selector if it is set. - * @return string - */ - public function get_quantity_field() { - $html = []; - // Quantity selection - if ( 'no' === $this->meta['recur'] && 'yes' === $this->meta['usequantity'] && ( 1 === $this->meta['usevariableamount'] || 0 !== $this->meta['amount'] ) ) { - $html[] = '
- -
- -
'; - } - return implode( '', $html ); - } - - /** - * Gets the recurring field. - * @return string - */ - public function get_recurring_field() { - $html = []; - - if ( $this->meta['recur'] == 'optional' ) { - - $intervals = [ - 'no' => 'None', - 'daily' =>'Daily', - 'weekly' => 'Weekly', - 'monthly' => 'Monthly', - 'biannually' => 'Biannually', - 'annually' => 'Annually', - ]; - - $html[] = '
-
- -
-
'; - } - return implode( '', $html ); - } - - /** - * Gets the recurring plan fields. - * - * @return string - */ - public function get_recurring_plan_fields() { - $html = []; - // Plan details for recurring payments - if ( $this->meta['recur'] == 'plan' && $this->has_plan && $this->show_btn ) { - $html[] = ''; - $html[] = '
- -
'; - } - - return implode( '', $html ); - } - - /** - * Gets the retry form. - * - * @param string $code - * @return array - */ - public function get_retry_form( $code = '' ) { - $html = []; - $record = $this->helpers->get_db_record( $code ); - if ( false !== $record ) { - $html[] = '
'; - $html[] = '
'; - $html[] = '
'; - $html[] = '
'; - $html[] = '
'; - - $html[] = ''; - $html[] = ''; - $html[] = wp_nonce_field( 'pff-paystack-retry', 'pf-nonce', true, false ); - - $html[] = '
'; - - - $html[] = '
- ' . __( 'Payment Invoice', 'pff-paystack' ) . ' -
'; - - $html[] = '
'; - - $html[] = '
- - ' . esc_html( $record->email ) . ' -
'; - - $html[] = '
- - ' . esc_html( $this->meta['currency'] . number_format( $record->amount ) ) . ' -
'; - - - $html[] = $this->helpers->format_meta_as_display_fields( $record->metadata ); - - $html[] = '
- - ' . esc_html( $record->created_at ) . ' -
'; - - if ( 1 === intval( $record->paid ) ) { - $html[] = '
- - ' . __( 'Successful', 'pff-paystack' ) . ' -
'; - } - - $html[] = '
'; - $html[] = '
'; - - $html[] = ''; - $html[] = '
'; - $html[] = '
'; - $html[] = '
'; - $html[] = '
'; - $html[] = '
'; - - } else { - $html[] = esc_html__( 'Invoice code invalid', 'pff-paystack' ); - } - - return $html; - } - - -} \ No newline at end of file diff --git a/includes/classes/class-form-submit.php b/includes/classes/class-form-submit.php deleted file mode 100644 index a1e1e23..0000000 --- a/includes/classes/class-form-submit.php +++ /dev/null @@ -1,484 +0,0 @@ -response['result'] = 'failed'; - $this->response['message'] = __( 'Nonce verification is required.', 'pff-paystack' ); - return false; - } - - if ( ! isset( $_POST['pf-id'] ) || '' == trim( sanitize_text_field( wp_unslash( $_POST['pf-id'] ) ) ) ) { - $this->response['result'] = 'failed'; - $this->response['message'] = __( 'A form ID is required', 'pff-paystack' ); - return false; - } else { - $this->form_id = sanitize_text_field( wp_unslash( $_POST['pf-id'] ) ); - } - - if ( ! isset( $_POST['pf-pemail'] ) || '' == trim( sanitize_text_field( wp_unslash( $_POST['pf-pemail'] ) ) ) ) { - $this->response['result'] = 'failed'; - $this->response['message'] = __( 'Email is required', 'pff-paystack' ); - return false; - } - return true; - } - - /** - * Undocumented function - * - * @return void - */ - protected function setup_data() { - $this->helpers = new Helpers(); - $this->meta = $this->helpers->parse_meta_values( get_post( $this->form_id ) ); - $this->form_data = filter_input_array( INPUT_POST ); - - $this->metadata = $this->form_data; - unset( - $this->metadata['action'], - $this->metadata['pf-recur'], - $this->metadata['pf-id'], - $this->metadata['pf-pemail'], - $this->metadata['pf-amount'], - $this->metadata['pf-user_id'], - $this->metadata['pf-interval'] - ); - $this->untouched = $this->helpers->format_meta_as_custom_fields( $this->metadata ); - - // Make sure we always have 1 quantity being purchased. - if ( ! isset( $this->form_data['pf-quantity'] ) ) { - $this->form_data['pf-quantity'] = 1; - } - - if ( isset( $_SERVER['HTTP_REFERER'] ) ) { - // Get the referer URL - $this->referer_url = sanitize_url( wp_unslash( $_SERVER['HTTP_REFERER'] ) ); - } - } - - /** - * This will adjust the amount being paid according to the variable payment and amounts. - * - * @param integer $amount - * @return integer - */ - public function process_amount( $amount = 0 ) { - $original_amount = $amount; - - if ( 'no' === $this->meta['recur'] && 1 !== $this->meta['usevariableamount'] ) { - if ( 0 !== (int) floatval( $this->meta['amount'] ) ) { - $amount = floatval( $this->meta['amount'] ); - } else { - $amount = $this->form_data['pf-amount']; - } - $amount = (int) str_replace( ' ', '', floatval( $amount ) ); - } - - if ( 1 === $this->meta['minimum'] && 0 !== floatval( $this->meta['amount'] ) ) { - if ( $original_amount < floatval( $this->meta['amount'] ) ) { - $amount = floatval( $this->meta['amount'] ); - } else { - $amount = $original_amount; - } - } - - if ( 1 === $this->meta['usevariableamount'] ) { - $payment_options = explode( ',', $this->meta['variableamount'] ); - if ( count( $payment_options ) > 0 ) { - foreach ( $payment_options as $key => $payment_option ) { - list( $a, $b ) = explode( ':', $payment_option ); - if ( $this->form_data['pf-vname'] == $a ) { - $amount = $b; - } - } - } - } - - return $amount; - } - - /** - * This will adjust the amount if the quantity fields are being used. - * - * @param integer $amount - * @return integer - */ - public function process_amount_quantity( $amount = 0 ) { - if ( $this->meta['use_quantity'] === 'yes' && ! ( 'optional' === $this->meta['recur'] || 'plan' === $this->meta['recur'] ) ) { - $quantity = $this->form_data['pf-quantity']; - $unit_amt = (int) str_replace( ' ', '', $amount ); - $amount = $quantity * $unit_amt; - } - return $amount; - } - - /** - * This function uploads the images with media_handle_upload and adds them to the metadata array. - * - * @return void - */ - public function process_images() { - $max_file_size = $this->meta['filelimit'] * 1024 * 1024; - - // Our nonce is checked in the Form_Submit::valid_submission() function - // phpcs:ignore WordPress.Security.NonceVerification - if ( ! empty( $_FILES ) ) { - // phpcs:ignore WordPress.Security.NonceVerification - foreach ( $_FILES as $key_name => $value ) { - if ( $value['size'] > 0 ) { - if ( $value['size'] > $max_file_size ) { - $response['result'] = 'failed'; - // translators: %s: maximum upload file size in MB - $response['message'] = sprintf( __( 'Max upload size is %sMB', 'pff-paystack' ), $this->meta['filelimit'] ); - exit( wp_json_encode( $response ) ); - } else { - $attachment_id = media_handle_upload( $key_name, $this->form_id ); - $url = wp_get_attachment_url( $attachment_id ); - $this->fixed_metadata[] = array( - 'display_name' => ucwords( str_replace( '_', ' ', $key_name ) ), - 'variable_name' => $key_name, - 'type' => 'link', - 'value' => $url, - ); - } - } else { - $this->fixed_metadata[] = array( - 'display_name' => ucwords( str_replace( '_', ' ', $key_name ) ), - 'variable_name' => $key_name, - 'type' => 'text', - 'value' => __( 'No file Uploaded', 'pff-paystack' ), - ); - } - } - } - } - - public function submit_action() { - if ( ! $this->valid_submission() ) { - // Exit here, for not processing further because of the error - exit( wp_json_encode( $this->response ) ); - } - - /** - * Setup our data to be processed. - */ - $this->setup_data(); - - /** - * Hookable location. Allows other plugins use a fresh submission before it is saved to the database. - * add_action( 'pff_paystack_before_save', 'function_to_use_posted_values' ); - * - */ - do_action( 'pff_paystack_before_save', $this ); - - /** - * @deprecated 3.4.2 - */ - do_action( 'kkd_pff_paystack_before_save' ); - - global $wpdb; - $code = $this->generate_code(); - $table = $wpdb->prefix . PFF_PAYSTACK_TABLE; - - $this->fixed_metadata = []; - - $amount = (int) str_replace( ' ', '', $this->form_data['pf-amount'] ); - $amount = $this->process_amount( $amount ); - - // Store the single unit price. - $this->fixed_metadata[] = array( - 'display_name' => __( 'Unit Price', 'pff-paystack' ), - 'variable_name' => 'Unit_Price', - 'type' => 'text', - 'value' => $this->meta['currency'] . number_format( $amount ), - ); - - if ( 'customer' === $this->meta['txncharge'] ) { - $amount = $this->helpers->process_transaction_fees( $amount ); - } - - /** - * This function will exit early if one of the images is too large to be uploaded. - */ - $this->process_images(); - $this->process_recurring_plans( $amount ); - $this->fixed_metadata = json_decode( wp_json_encode( $this->fixed_metadata, JSON_NUMERIC_CHECK ), true ); - $this->fixed_metadata = array_merge( $this->untouched, $this->fixed_metadata ); - - $insert = array( - 'post_id' => $this->form_data['pf-id'], - 'email' => $this->form_data['pf-pemail'], - 'user_id' => $this->form_data['pf-user_id'], - 'amount' => $amount, - 'plan' => $this->meta['plancode'], - 'ip' => $this->helpers->get_the_user_ip(), - 'txn_code' => $code, - 'metadata' => wp_json_encode( $this->fixed_metadata ), - ); - - // phpcs:ignore WordPress.DB.DirectDatabaseQuery - $exist = $wpdb->get_results( - $wpdb->prepare( - "SELECT * - FROM %i - WHERE post_id = %s - AND email = %s - AND user_id = %s - AND amount = %s - AND plan = %s - AND ip = %s - AND paid = '0' - AND metadata = %s", - $table, - $insert['post_id'], - $insert['email'], - $insert['user_id'], - $insert['amount'], - $insert['plan'], - $insert['ip'], - $insert['metadata'] - ) - ); - - if ( count( $exist ) > 0 ) { - // phpcs:ignore WordPress.DB.DirectDatabaseQuery - $wpdb->update( - $table, - array( - 'txn_code' => $code, - 'plan' => $insert['plan'], - ), - array( - 'id' => $exist[0]->id, - ) - ); - } else { - // phpcs:ignore WordPress.DB.DirectDatabaseQuery - $wpdb->insert( - $table, - $insert - ); - } - - /** - * Allow 3rd party plugins to send off an invoice as well - * - * 11: Email_Invoice::send_invoice(); - */ - if ( 'yes' === $this->meta['sendinvoice'] ) { - do_action( 'pff_paystack_send_invoice', $this->form_id, $this->meta['currency'], $insert['amount'], $this->form_data['pf-fname'], $insert['email'], $code, $this->referer_url ); - } - - $transaction_charge = (int) $this->meta['merchantamount']; - $transaction_charge = $transaction_charge * 100; - - if ( '' == $this->meta['subaccount'] || ! isset( $this->meta['subaccount'] ) ) { - $subaccount = null; - $txn_bearer = null; - $transaction_charge = null; - } - if ( '' == $transaction_charge || 0 == $transaction_charge || null == $transaction_charge ) { - $transaction_charge = null; - } - - $amount = floatval( $insert['amount'] ) * 100; - - $response = array( - 'result' => 'success', - 'code' => $insert['txn_code'], - 'plan' => $insert['plan'], - 'quantity' => $this->form_data['pf-quantity'], - 'email' => $insert['email'], - 'name' => $this->form_data['pf-fname'], - 'total' => round( $amount ), - 'currency' => $this->meta['currency'], - 'custom_fields' => $this->fixed_metadata, - 'subaccount' => $subaccount, - 'txnbearer' => $txn_bearer, - 'transaction_charge' => $transaction_charge, - ); - - // We create 2 nonces here - // 1 incase the payment fails, and the user needs to try again. - // 2 if the payment is successful and the confirmation ajax needs to run. - $response['invoiceNonce'] = wp_create_nonce( 'pff-paystack-invoice' ); - $response['confirmNonce'] = wp_create_nonce( 'pff-paystack-confirm' ); - - echo wp_json_encode( $response ); - die(); - } - - /** - * This function looks for a recurring plan set by the customer, a recurring plan code set by the owner. - */ - public function process_recurring_plans( $amount ) { - $plan_code = 'none'; - $has_interval = false; - - if ( 'no' !== $this->meta['recur'] ) { - - // is the user setting the interval? - if ( 'optional' === $this->meta['recur'] ) { - $interval = $this->form_data['pf-interval']; - - // Only create a subscription plan if they choose an interval. - if ( 'no' !== $interval ) { - $unit_amount = $amount * 100; - $possible_plan = pff_paystack()->classes['request-plan']->list_plans( '?amount=' . $unit_amount . '&interval=' . $interval ); - - // If we have found a plan, then use that code, otherwise create a new one. - if ( false !== $possible_plan && isset( $possible_plan->plan_code ) ) { - $plan_code = $possible_plan->plan_code; - $has_interval = $possible_plan->interval; - } else { - // Create Plan. - $body = array( - 'name' => get_the_title( $this->form_id ) . ' [' . $this->meta['currency'] . number_format( $amount ) . '] - ' . $interval, - 'amount' => $unit_amount, - 'interval' => $interval, - ); - $created_plan = pff_paystack()->classes['request-plan']->create_plan( $body ); - if ( false !== $created_plan && isset( $created_plan->plan_code ) ) { - $plan_code = $created_plan->data->plan_code; - $has_interval = $created_plan->data->interval; - } - } - } - } else { - // Use Plan Code. - $plan_code = sanitize_text_field( wp_unslash( $this->form_data['pf-plancode'] ) ); - unset( $this->metadata['pf-plancode'] ); - } - } - - if ( 'none' !== $plan_code ) { - $this->meta['plancode'] = $plan_code; - $this->fixed_metadata[] = array( - 'display_name' => __( 'Plan', 'pff-paystack' ), - 'variable_name' => 'Plan', - 'type' => 'text', - 'value' => $plan_code, - ); - - if ( false !== $has_interval ) { - $this->fixed_metadata[] = array( - 'display_name' => __( 'Plan Interval', 'pff-paystack' ), - 'variable_name' => 'Plan Interval', - 'type' => 'text', - 'value' => $has_interval, - ); - } - - } else if ( ! isset( $this->meta['plancode'] ) ) { - $this->meta['plancode'] = ''; - } - } - - /** - * Generate a unique Paystack code that does not yet exist in the database. - * - * @return string Generated unique code. - */ - public function generate_code() { - do { - $code = $this->helpers->generate_new_code(); - $check = $this->helpers->check_code( $code ); - } while ( $check ); - - return $code; - } -} \ No newline at end of file diff --git a/includes/classes/class-forms-list.php b/includes/classes/class-forms-list.php deleted file mode 100644 index 0111a2f..0000000 --- a/includes/classes/class-forms-list.php +++ /dev/null @@ -1,75 +0,0 @@ -ID ) . '" >' . __( 'View Payments', 'payment_forms' ) . ''; - } - return $actions; - } - - /** - * Registers our column names. - * - * @param array $columns - * @return array - */ - public function register_columns( $columns ) { - $columns = array( - 'cb' => '', - 'title' => __( 'Name', 'pff-paystack' ), - 'shortcode' => __( 'Shortcode', 'pff-paystack' ), - 'payments' => __( 'Payments', 'pff-paystack' ), - 'date' => __( 'Date', 'pff-paystack' ) - ); - return $columns; - } - - public function column_data( $column, $post_id ) { - $helpers = Helpers::get_instance(); - switch ( $column ) { - case 'shortcode': - echo wp_kses_post( '[pff-paystack id="' . $post_id . '"]"' ); - break; - case 'payments': - $num = $helpers->get_payments_count( $post_id ); - echo wp_kses_post( '' . $num . '' ); - break; - default: - break; - } - } -} diff --git a/includes/classes/class-forms-update.php b/includes/classes/class-forms-update.php deleted file mode 100644 index f421220..0000000 --- a/includes/classes/class-forms-update.php +++ /dev/null @@ -1,612 +0,0 @@ -set_vars(); - add_action( 'admin_head', [ $this, 'setup_actions' ] ); - add_filter( 'admin_head', [ $this, 'disable_wyswyg' ], 10, 1 ); - - // Default Content. - add_filter('default_content', [ $this, 'default_content' ], 10, 2); - - // Define the meta boxes. - add_action( 'edit_form_after_title', [ $this, 'metabox_action' ] ); - add_action( 'add_meta_boxes', [ $this, 'register_meta_boxes' ] ); - - // Save the Meta boxes - add_action( 'save_post', [ $this, 'save_post_meta' ], 1, 2 ); - } - - /** - * Sets useable variables like the fields. - * - * @return void - */ - public function set_vars() { - $this->helpers = Helpers::get_instance(); - $this->defaults = $this->helpers->get_meta_defaults(); - $this->allowed_html = $this->helpers->get_allowed_html(); - } - - /** - * Add the phone number as the default content when a form is created. - * - * @param string $content - * @param WP_Post $post - * @return string - */ - public function default_content( $content, $post ) { - switch ( $post->post_type ) { - case 'paystack_form': - $content = '[text name="' . __( 'Phone Number', 'pff-paystack' ) . '"]'; - break; - default: - $content = ''; - break; - } - return $content; - } - - /** - * Run some actions on admin_head - * - * @return void - */ - public function setup_actions() { - add_filter( 'user_can_richedit', '__return_false', 50 ); - add_filter( 'quicktags_settings', [ $this, 'remove_fullscreen' ], 10, 1 ); - - remove_action( 'media_buttons', 'media_buttons' ); - remove_meta_box( 'postimagediv', 'post', 'side' ); - - add_action( 'admin_print_footer_scripts', [ $this, 'shortcode_buttons_script' ] ); - } - - /** - * Outputs CSS to hide the WYSIWYG - * - * @param string $default - * @return string - */ - public function disable_wyswyg( $default ) { - if ( 'paystack_form' === get_post_type() ) { - ?> - - - - parse_meta_values( $post ); - do_meta_boxes( 'paystack_form', 'pff', $post ); - } - - /** - * Registers our custom metaboxes. - * - * @return void - */ - public function register_meta_boxes() { - // Register the information boxes. - if ( isset( $_GET['action'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended - add_meta_box( 'pff_paystack_editor_details_box', __( 'Paste shortcode on preferred page', 'paystack_form' ), [ $this, 'shortcode_details' ], 'paystack_form', 'pff' ); - } - add_meta_box( 'pff_paystack_editor_help_box', __( 'Help Section', 'pff-paystack' ), [ $this, 'help_details' ], 'paystack_form', 'pff' ); - - // Add in our "normal" meta boxes - add_meta_box( 'form_data', __( 'Extra Form Description', 'pff-paystack' ), [ $this, 'form_data' ], 'paystack_form', 'normal', 'default' ); - add_meta_box( 'email_data', __( 'Email Receipt Settings', 'pff-paystack' ), [ $this, 'email_data' ], 'paystack_form', 'normal', 'default' ); - - // Add in our "side" meta boxes - add_meta_box( 'recuring_data', __( 'Recurring Payment', 'pff-paystack' ), [ $this, 'recur_data' ], 'paystack_form', 'side', 'default' ); - add_meta_box( 'quantity_data', __( 'Quantity Payment', 'pff-paystack' ), [ $this, 'quantity_data' ], 'paystack_form', 'side', 'default' ); - add_meta_box( 'agreement_data', __( 'Agreement checkbox', 'pff-paystack' ), [ $this, 'agreement_data' ], 'paystack_form', 'side', 'default' ); - add_meta_box( 'subaccount_data', __( 'Sub Account', 'pff-paystack' ), [ $this, 'subaccount_data' ], 'paystack_form', 'side', 'default' ); - add_meta_box( 'plan_data', __( '*Special: Subscribe to plan after time', 'pff-paystack' ), [ $this, 'plan_data' ], 'paystack_form', 'side', 'default' ); - - } - - /** - * Output the shortcode details - * - * @param WP_Post $post - * @return void - */ - public function shortcode_details( $post ) { - ?> -

- - - - -

- -
-
- To make an input field compulsory add required="required" to the shortcode

- It should look like this [text name="Full Name" required="required" ]

' ) ) ; ?> - - Warning: Using the file input field may cause data overload on your server. - Be sure you have enough server space before using it. You also have the ability to set file upload limits.' ) ) ; ?> -
- meta = $this->helpers->parse_meta_values( $post ); - } - - /** - * Outputs the Extra Form Description Meta Box. - * - * @return void - */ - public function form_data() { - $html = []; - - // We shall output 1 Nonce Field for all of our metaboxes. - $html[] = wp_nonce_field( 'pff-paystack-save-form', 'pff_paystack_save', true, false ); - - if ($this->meta['hidetitle'] == 1) { - $html[] = ''; - } else { - $html[] = ''; - } - $html[] = '
'; - $html[] = '

Currency:

'; - $html[] = ''; - - $html[] = '' . __('Ensure you are activated for the currency you are selecting. Check here for more information.', 'pff-paystack') . ''; - $html[] = '

' . __('Amount to be paid(Set 0 for customer input):', 'pff-paystack') . '

'; - $html[] = ''; - if ($this->meta['minimum'] == 1) { - $html[] = '
'; - } else { - $html[] = '
'; - } - $html[] = '

' . __('Variable Dropdown Amount:', 'pff-paystack') . '

'; - $html[] = ''; - $html[] = '
'; - - - $html[] = '

' . __('Pay button Description:', 'pff-paystack') . '

'; - $html[] = ''; - $html[] = '

' . __('Add Extra Charge:', 'pff-paystack') . '

'; - $html[] = ' -
' . __('This allows you include an extra charge to cushion the effect of the transaction fee. ' . __('Configure', 'pff-paystack') . ''; - $html[] = '

' . __('User logged In:', 'pff-paystack') . '

'; - $html[] = ''; - $html[] = '

' . __('Success Message after Payment', 'pff-paystack') . '

'; - $html[] = ''; - $html[] = '

' . __('File Upload Limit(MB):', 'pff-paystack') . '

'; - $html[] = ''; - $html[] = '

' . __('Redirect to page link after payment(keep blank to use normal success message):', 'pff-paystack') . '

'; - $html[] = ''; - - // To output the concatenated $html array content - echo wp_kses( implode( '', $html ), $this->allowed_html ); - } - - /** - * Checks to see if the curren value is selected. - * - * @param string $value - * @param string $compare - * @return string - */ - public function is_option_selected( $value, $compare, $selected = 'selected' ) { - if ( $value == $compare ) { - $result = $selected; - } else { - $result = ""; - } - return $result; - } - - /** - * Output the recurring data meta box. - * - * @return void - */ - public function recur_data(){ - $html = []; - $html[] = '

' . __('Recurring Payment:', 'pff-paystack') . '

'; - $html[] = ''; - $html[] = '

' . __('Paystack Recur Plan code:', 'pff-paystack') . '

'; - $html[] = ' - ' . __('Plan amount must match amount on extra form description.', 'pff-paystack') . ''; - - // Output the accumulated HTML - echo wp_kses( implode( '', $html ), $this->allowed_html ); - } - - /** - * Add the email metabox - * - * @return void - */ - public function email_data() { - $html = []; - // Echo out the field - $html[] = '

' . __('Send an invoice when a payment is attempted:', 'pff-paystack') . '

'; - $html[] = ''; - $html[] = '

' . __('Send Email Receipt:', 'pff-paystack') . '

'; - $html[] = ''; - $html[] = '

' . __('Email Subject:', 'pff-paystack') . '

'; - $html[] = ''; - $html[] = '

' . __('Merchant Name on Receipt:', 'pff-paystack') . '

'; - $html[] = ''; - $html[] = '

' . __('Email Heading:', 'pff-paystack') . '

'; - $html[] = ''; - $html[] = '

' . __('Email Body/Message:', 'pff-paystack') . '

'; - $html[] = ''; - - echo wp_kses( implode( '', $html ), $this->allowed_html ); - } - - /** - * Add the quantity metabox - * - * @return void - */ - public function quantity_data() { - $html = []; - - // Echo out the field - $html[] = '' . __('Allow your users pay in multiple quantity', 'pff-paystack') . ' -

' . __('Quantified Payment:', 'pff-paystack') . '

'; - - if ($this->meta['recur'] != "no") { - $html[] = ''; - } else { - $html[] = ''; - } - - if ($this->meta['usequantity'] == "yes") { - - $html[] = '

' . __('Max payable quantity:', 'pff-paystack') . '

'; - $html[] = '' . __('Your users only get to pay in quantities if the from amount is not set to zero and recur is set to none.', 'pff-paystack') . ''; - $html[] = '

' . __('Unit of quantity:', 'pff-paystack') . '

'; - $html[] = '' . __('What is the unit of this quantity? Default is Quantity.', 'pff-paystack') . ''; - - $html[] = '

' . __('Inventory Payment:', 'pff-paystack') . '

'; - $html[] = ' - ' . __('Set maximum available items in stock', 'pff-paystack') . ''; - } - - if ($this->meta['useinventory'] == "yes" && $this->meta['usequantity'] == "yes") { - $html[] = '

' . __('Total Inventory', 'pff-paystack') . '

'; - $html[] = ''; - $html[] = '

' . __('Already sold', 'pff-paystack') . '

'; - $html[] = ' - -
'; - } - - echo wp_kses( implode( '', $html ), $this->allowed_html ); - } - - /** - * Add the agreement metabox - * - * @return void - */ - public function agreement_data() { - $html = []; - - // Add components to the $html array - $html[] = '

' . __( 'Use agreement checkbox:', 'pff-paystack' ) . '

'; - $html[] = ''; - $html[] = '

' . __( 'Agreement Page Link:', 'pff-paystack' ) . '

'; - $html[] = ''; - echo wp_kses( implode( '', $html ), $this->allowed_html ); - } - - /** - * Output the Subaccount metabox. - * - * @return void - */ - public function subaccount_data() { - $html = []; - // Add components to the $html array - $html[] = '

' . __( 'Sub Account code:', 'pff-paystack' ) . '

'; - $html[] = ''; - $html[] = '

' . __( 'Transaction Charge bearer:', 'pff-paystack' ) . '

'; - $html[] = ''; - $html[] = '

' . __( 'Merchant Amount:', 'pff-paystack' ) . '

'; - $html[] = ''; - echo wp_kses( implode( '', $html ), $this->allowed_html ); - } - - /** - * Output the Plan metabox - * - * @return void - */ - public function plan_data() { - $html = []; - $html[] = '

' . __( 'User subscribes to plan after number of days:', 'pff-paystack' ) . '

'; - $html[] = '

' . __( 'Number of days:', 'pff-paystack' ) . '

'; - $html[] = ''; - $html[] = '

' . __( 'Plan:', 'pff-paystack' ) . '

'; - $html[] = ''; - - if ($this->meta['startdate_enabled'] == 1) { - $html[] = '


'; - } else { - $html[] = '


'; - } - echo wp_kses( implode( '', $html ), $this->allowed_html ); - } - - /** - * Saves the post meta field stored in the $defaults variable. - * - * @param int|string $post_id - * @param WP_Post $post - * @return void - */ - public function save_post_meta( $form_id, $post ) { - - if ( ! isset( $_POST['pff_paystack_save'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['pff_paystack_save'] ) ), 'pff-paystack-save-form' ) ) { - return $form_id; - } - - // Is the user allowed to edit the post or page? - if ( ! current_user_can('edit_post', $form_id ) ) { - return $form_id; - } - - // Cycle through our fields and save the information. - foreach ( $this->defaults as $key => $default ) { - if ( $post->post_type == 'revision' ) { - return; // Don't store custom data twice - } - - if ( isset( $_POST[ '_' . $key ] ) ) { - $value = sanitize_text_field( wp_unslash( $_POST[ '_' . $key ] ) ); - } else { - $value = $default; - } - - $value = implode( ',', (array) $value ); // If $value is an array, make it a CSV (unlikely) - if ( get_post_meta( $form_id, '_' . $key, false ) ) { // If the custom field already has a value - update_post_meta( $form_id, '_' . $key, $value ); - } else { // If the custom field doesn't have a value - add_post_meta( $form_id, '_' . $key, $value ); - } - if ( ! $value ) { - delete_post_meta( $form_id, '_' . $key ); // Delete if blank - } - } - } -} diff --git a/includes/classes/class-helpers.php b/includes/classes/class-helpers.php deleted file mode 100644 index 4d29c13..0000000 --- a/includes/classes/class-helpers.php +++ /dev/null @@ -1,822 +0,0 @@ -defaults = [ - 'amount' => 0, - 'paybtn' => __( 'Pay', 'pff-paystack' ), - 'successmsg' => __( 'Thank you for paying!', 'pff-paystack' ), - 'txncharge' => 'merchant', - 'loggedin' => '', - 'currency' => 'NGN', - 'filelimit' => 2, - 'redirect' => '', - 'minimum' => 0, - 'usevariableamount' => 0, - 'variableamount' => 'Please configure your options:0,None:0', - 'hidetitle' => 0, - 'loggedin' => 'no', - 'recur' => 'no', - 'recurplan' => '', - 'subject' => __( 'Thank you for your payment', 'pff-paystack' ), - 'merchant' => '', - 'heading' => __( 'We\'ve received your payment', 'pff-paystack' ), - 'message' => __( 'Your payment was received and we appreciate it.', 'pff-paystack' ), - 'sendreceipt' => 'yes', - 'sendinvoice' => 'yes', - 'usequantity' => 'no', - 'useinventory' => 'no', - 'inventory' => '0', - 'sold' => '0', - 'quantity' => '10', - 'quantityunit' => __( 'Quantity', 'pff-paystack' ), - 'useagreement' => 'no', - 'agreementlink' => '', - 'subaccount' => '', - 'txnbearer' => 'account', - 'merchantamount' => '', - 'startdate_days' => '', - 'startdate_plan_code' => '', - 'startdate_enabled' => 0, - ]; - - $this->allowed_html = array( - 'small' => array( - 'href' => true, - 'target' => true - ), - 'a' => array( - 'href' => true, - 'target' => true - ), - 'p' => array(), - 'input' => array( - 'type' => true, - 'name' => true, - 'value' => true, - 'class' => true, - 'checked' => true - ), - 'br' => array(), - 'label' => array( - 'for' => true - ), - 'code' => array(), - 'select' => array( - 'class' => true, - 'name' => true, - 'id' => true, - 'style' => true - ), - 'option' => array( - 'value' => true, - 'selected' => true - ), - 'textarea' => array( - 'rows' => true, - 'name' => true, - 'class' => true - ) - ); - } - - /** - * Return an instance of this class. - * - * @return object \paystack\payment_forms\Payment_Forms - */ - public static function get_instance() { - // If the single instance hasn't been set, set it now. - if ( null == self::$instance ) { - self::$instance = new self(); - } - - return self::$instance; - } - - // GETTERS - - /** - * Returns the fee settings save or the default values. - * - * @return array - */ - public function get_fees() { - $ret = []; - $ret['prc'] = intval( floatval( esc_attr( get_option( 'prc', PFF_PAYSTACK_PERCENTAGE ) ) ) * 100 ) / 10000; - $ret['ths'] = intval( floatval( esc_attr( get_option( 'ths', PFF_PAYSTACK_CROSSOVER_TOTAL ) ) ) * 100 ); - $ret['adc'] = intval( floatval( esc_attr( get_option( 'adc', PFF_PAYSTACK_ADDITIONAL_CHARGE ) ) ) * 100 ); - $ret['cap'] = intval( floatval( esc_attr( get_option( 'cap', PFF_PAYSTACK_LOCAL_CAP ) ) ) * 100 ); - return $ret; - } - - /** - * Gets the public key from the settings. - * - * @return string - */ - public function get_public_key() { - $mode = esc_attr( get_option( 'mode' ) ); - if ( 'test' === $mode ) { - $key = esc_attr( get_option( 'tpk', '' ) ); - } else { - $key = esc_attr( get_option( 'lpk', '' ) ); - } - return $key; - } - - /** - * Fetch an array of the payments by the form ID. - * - * @param integer $form_id - * @param array $args - * @return array - */ - public function get_payments_by_id( $form_id = 0, $args = array() ) { - global $wpdb; - $results = array(); - if ( 0 === $form_id ) { - return $results; - } - - $defaults = array( - 'paid' => '1', - 'order' => 'desc', - 'orderby' => 'created_at', - ); - $args = wp_parse_args( $args, $defaults ); - $table = $wpdb->prefix . PFF_PAYSTACK_TABLE; - $order = strtoupper( $args['order'] ); - - // phpcs:ignore WordPress.DB.DirectDatabaseQuery - $results = $wpdb->get_results( - $wpdb->prepare( - "SELECT * - FROM %i - WHERE post_id = %d - AND paid = %s - ORDER BY %i $order", // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared - $table, - $form_id, - $args['paid'], - $args['orderby'], - ) - ); - return $results; - } - - /** - * Gets the payments count for the current form. - * - * @param int|string $form_id - * @return int - */ - public function get_payments_count( $form_id ) { - global $wpdb; - $table = $wpdb->prefix . PFF_PAYSTACK_TABLE; - $num = wp_cache_get( 'form_payments_' . $form_id, 'pff_paystack' ); - if ( false === $num ) { - // phpcs:ignore WordPress.DB.DirectDatabaseQuery - $num = $wpdb->get_var( - $wpdb->prepare( - "SELECT COUNT(*) - FROM %i - WHERE post_id = %d - AND paid = '1'", - $table, - $form_id - ) - ); - wp_cache_set( 'form_payments_' . $form_id, $num, 'pff_paystack', 60*5 ); - } - return $num; - } - - /** - * Returns an array | string of the countries - * - * @param boolean $implode - * @return array|string - */ - public function get_countries( $implode = false ) { - $countries = [ - __( "Afghanistan", 'pff-paystack' ), - __( "Albania", 'pff-paystack' ), - __( "Algeria", 'pff-paystack' ), - __( "American Samoa", 'pff-paystack' ), - __( "Andorra", 'pff-paystack' ), - __( "Angola", 'pff-paystack' ), - __( "Anguilla", 'pff-paystack' ), - __( "Antarctica", 'pff-paystack' ), - __( "Antigua and Barbuda", 'pff-paystack' ), - __( "Argentina", 'pff-paystack' ), - __( "Armenia", 'pff-paystack' ), - __( "Aruba", 'pff-paystack' ), - __( "Australia", 'pff-paystack' ), - __( "Austria", 'pff-paystack' ), - __( "Azerbaijan", 'pff-paystack' ), - __( "Bahamas", 'pff-paystack' ), - __( "Bahrain", 'pff-paystack' ), - __( "Bangladesh", 'pff-paystack' ), - __( "Barbados", 'pff-paystack' ), - __( "Belarus", 'pff-paystack' ), - __( "Belgium", 'pff-paystack' ), - __( "Belize", 'pff-paystack' ), - __( "Benin", 'pff-paystack' ), - __( "Bermuda", 'pff-paystack' ), - __( "Bhutan", 'pff-paystack' ), - __( "Bolivia", 'pff-paystack' ), - __( "Bosnia and Herzegovina", 'pff-paystack' ), - __( "Botswana", 'pff-paystack' ), - __( "Bouvet Island", 'pff-paystack' ), - __( "Brazil", 'pff-paystack' ), - __( "British Indian Ocean Territory", 'pff-paystack' ), - __( "Brunei Darussalam", 'pff-paystack' ), - __( "Bulgaria", 'pff-paystack' ), - __( "Burkina Faso", 'pff-paystack' ), - __( "Burundi", 'pff-paystack' ), - __( "Cambodia", 'pff-paystack' ), - __( "Cameroon", 'pff-paystack' ), - __( "Canada", 'pff-paystack' ), - __( "Cape Verde", 'pff-paystack' ), - __( "Cayman Islands", 'pff-paystack' ), - __( "Central African Republic", 'pff-paystack' ), - __( "Chad", 'pff-paystack' ), - __( "Chile", 'pff-paystack' ), - __( "China", 'pff-paystack' ), - __( "Christmas Island", 'pff-paystack' ), - __( "Cocos (Keeling) Islands", 'pff-paystack' ), - __( "Colombia", 'pff-paystack' ), - __( "Comoros", 'pff-paystack' ), - __( "Congo", 'pff-paystack' ), - __( "Congo, The Democratic Republic of The", 'pff-paystack' ), - __( "Cook Islands", 'pff-paystack' ), - __( "Costa Rica", 'pff-paystack' ), - __( "Cote D'ivoire", 'pff-paystack' ), - __( "Croatia", 'pff-paystack' ), - __( "Cuba", 'pff-paystack' ), - __( "Cyprus", 'pff-paystack' ), - __( "Czech Republic", 'pff-paystack' ), - __( "Denmark", 'pff-paystack' ), - __( "Djibouti", 'pff-paystack' ), - __( "Dominica", 'pff-paystack' ), - __( "Dominican Republic", 'pff-paystack' ), - __( "Ecuador", 'pff-paystack' ), - __( "Egypt", 'pff-paystack' ), - __( "El Salvador", 'pff-paystack' ), - __( "Equatorial Guinea", 'pff-paystack' ), - __( "Eritrea", 'pff-paystack' ), - __( "Estonia", 'pff-paystack' ), - __( "Ethiopia", 'pff-paystack' ), - __( "Falkland Islands (Malvinas)", 'pff-paystack' ), - __( "Faroe Islands", 'pff-paystack' ), - __( "Fiji", 'pff-paystack' ), - __( "Finland", 'pff-paystack' ), - __( "France", 'pff-paystack' ), - __( "French Guiana", 'pff-paystack' ), - __( "French Polynesia", 'pff-paystack' ), - __( "French Southern Territories", 'pff-paystack' ), - __( "Gabon", 'pff-paystack' ), - __( "Gambia", 'pff-paystack' ), - __( "Georgia", 'pff-paystack' ), - __( "Germany", 'pff-paystack' ), - __( "Ghana", 'pff-paystack' ), - __( "Gibraltar", 'pff-paystack' ), - __( "Greece", 'pff-paystack' ), - __( "Greenland", 'pff-paystack' ), - __( "Grenada", 'pff-paystack' ), - __( "Guadeloupe", 'pff-paystack' ), - __( "Guam", 'pff-paystack' ), - __( "Guatemala", 'pff-paystack' ), - __( "Guinea", 'pff-paystack' ), - __( "Guinea-bissau", 'pff-paystack' ), - __( "Guyana", 'pff-paystack' ), - __( "Haiti", 'pff-paystack' ), - __( "Heard Island and Mcdonald Islands", 'pff-paystack' ), - __( "Holy See (Vatican City State)", 'pff-paystack' ), - __( "Honduras", 'pff-paystack' ), - __( "Hong Kong", 'pff-paystack' ), - __( "Hungary", 'pff-paystack' ), - __( "Iceland", 'pff-paystack' ), - __( "India", 'pff-paystack' ), - __( "Indonesia", 'pff-paystack' ), - __( "Iran, Islamic Republic of", 'pff-paystack' ), - __( "Iraq", 'pff-paystack' ), - __( "Ireland", 'pff-paystack' ), - __( "Israel", 'pff-paystack' ), - __( "Italy", 'pff-paystack' ), - __( "Jamaica", 'pff-paystack' ), - __( "Japan", 'pff-paystack' ), - __( "Jordan", 'pff-paystack' ), - __( "Kazakhstan", 'pff-paystack' ), - __( "Kenya", 'pff-paystack' ), - __( "Kiribati", 'pff-paystack' ), - __( "Korea, Democratic People's Republic of", 'pff-paystack' ), - __( "Korea, Republic of", 'pff-paystack' ), - __( "Kuwait", 'pff-paystack' ), - __( "Kyrgyzstan", 'pff-paystack' ), - __( "Lao People's Democratic Republic", 'pff-paystack' ), - __( "Latvia", 'pff-paystack' ), - __( "Lebanon", 'pff-paystack' ), - __( "Lesotho", 'pff-paystack' ), - __( "Liberia", 'pff-paystack' ), - __( "Libyan Arab Jamahiriya", 'pff-paystack' ), - __( "Liechtenstein", 'pff-paystack' ), - __( "Lithuania", 'pff-paystack' ), - __( "Luxembourg", 'pff-paystack' ), - __( "Macao", 'pff-paystack' ), - __( "Macedonia, The Former Yugoslav Republic of", 'pff-paystack' ), - __( "Madagascar", 'pff-paystack' ), - __( "Malawi", 'pff-paystack' ), - __( "Malaysia", 'pff-paystack' ), - __( "Maldives", 'pff-paystack' ), - __( "Mali", 'pff-paystack' ), - __( "Malta", 'pff-paystack' ), - __( "Marshall Islands", 'pff-paystack' ), - __( "Martinique", 'pff-paystack' ), - __( "Mauritania", 'pff-paystack' ), - __( "Mauritius", 'pff-paystack' ), - __( "Mayotte", 'pff-paystack' ), - __( "Mexico", 'pff-paystack' ), - __( "Micronesia, Federated States of", 'pff-paystack' ), - __( "Moldova, Republic of", 'pff-paystack' ), - __( "Monaco", 'pff-paystack' ), - __( "Mongolia", 'pff-paystack' ), - __( "Montserrat", 'pff-paystack' ), - __( "Morocco", 'pff-paystack' ), - __( "Mozambique", 'pff-paystack' ), - __( "Myanmar", 'pff-paystack' ), - __( "Namibia", 'pff-paystack' ), - __( "Nauru", 'pff-paystack' ), - __( "Nepal", 'pff-paystack' ), - __( "Netherlands", 'pff-paystack' ), - __( "Netherlands Antilles", 'pff-paystack' ), - __( "New Caledonia", 'pff-paystack' ), - __( "New Zealand", 'pff-paystack' ), - __( "Nicaragua", 'pff-paystack' ), - __( "Niger", 'pff-paystack' ), - __( "Nigeria", 'pff-paystack' ), - __( "Niue", 'pff-paystack' ), - __( "Norfolk Island", 'pff-paystack' ), - __( "Northern Mariana Islands", 'pff-paystack' ), - __( "Norway", 'pff-paystack' ), - __( "Oman", 'pff-paystack' ), - __( "Pakistan", 'pff-paystack' ), - __( "Palau", 'pff-paystack' ), - __( "Palestinian Territory, Occupied", 'pff-paystack' ), - __( "Panama", 'pff-paystack' ), - __( "Papua New Guinea", 'pff-paystack' ), - __( "Paraguay", 'pff-paystack' ), - __( "Peru", 'pff-paystack' ), - __( "Philippines", 'pff-paystack' ), - __( "Pitcairn", 'pff-paystack' ), - __( "Poland", 'pff-paystack' ), - __( "Portugal", 'pff-paystack' ), - __( "Puerto Rico", 'pff-paystack' ), - __( "Qatar", 'pff-paystack' ), - __( "Reunion", 'pff-paystack' ), - __( "Romania", 'pff-paystack' ), - __( "Russian Federation", 'pff-paystack' ), - __( "Rwanda", 'pff-paystack' ), - __( "Saint Helena", 'pff-paystack' ), - __( "Saint Kitts and Nevis", 'pff-paystack' ), - __( "Saint Lucia", 'pff-paystack' ), - __( "Saint Pierre and Miquelon", 'pff-paystack' ), - __( "Saint Vincent and The Grenadines", 'pff-paystack' ), - __( "Samoa", 'pff-paystack' ), - __( "San Marino", 'pff-paystack' ), - __( "Sao Tome and Principe", 'pff-paystack' ), - __( "Saudi Arabia", 'pff-paystack' ), - __( "Senegal", 'pff-paystack' ), - __( "Serbia and Montenegro", 'pff-paystack' ), - __( "Seychelles", 'pff-paystack' ), - __( "Sierra Leone", 'pff-paystack' ), - __( "Singapore", 'pff-paystack' ), - __( "Slovakia", 'pff-paystack' ), - __( "Slovenia", 'pff-paystack' ), - __( "Solomon Islands", 'pff-paystack' ), - __( "Somalia", 'pff-paystack' ), - __( "South Africa", 'pff-paystack' ), - __( "South Georgia and The South Sandwich Islands", 'pff-paystack' ), - __( "Spain", 'pff-paystack' ), - __( "Sri Lanka", 'pff-paystack' ), - __( "Sudan", 'pff-paystack' ), - __( "Suriname", 'pff-paystack' ), - __( "Svalbard and Jan Mayen", 'pff-paystack' ), - __( "Swaziland", 'pff-paystack' ), - __( "Sweden", 'pff-paystack' ), - __( "Switzerland", 'pff-paystack' ), - __( "Syrian Arab Republic", 'pff-paystack' ), - __( "Taiwan, Province of China", 'pff-paystack' ), - __( "Tajikistan", 'pff-paystack' ), - __( "Tanzania, United Republic of", 'pff-paystack' ), - __( "Thailand", 'pff-paystack' ), - __( "Timor-leste", 'pff-paystack' ), - __( "Togo", 'pff-paystack' ), - __( "Tokelau", 'pff-paystack' ), - __( "Tonga", 'pff-paystack' ), - __( "Trinidad and Tobago", 'pff-paystack' ), - __( "Tunisia", 'pff-paystack' ), - __( "Turkey", 'pff-paystack' ), - __( "Turkmenistan", 'pff-paystack' ), - __( "Turks and Caicos Islands", 'pff-paystack' ), - __( "Tuvalu", 'pff-paystack' ), - __( "Uganda", 'pff-paystack' ), - __( "Ukraine", 'pff-paystack' ), - __( "United Arab Emirates", 'pff-paystack' ), - __( "United Kingdom", 'pff-paystack' ), - __( "United States", 'pff-paystack' ), - __( "United States Minor Outlying Islands", 'pff-paystack' ), - __( "Uruguay", 'pff-paystack' ), - __( "Uzbekistan", 'pff-paystack' ), - __( "Vanuatu", 'pff-paystack' ), - __( "Venezuela", 'pff-paystack' ), - __( "Viet Nam", 'pff-paystack' ), - __( "Virgin Islands; British", 'pff-paystack' ), - __( "Virgin Islands; U.S.", 'pff-paystack' ), - __( "Wallis and Futuna", 'pff-paystack' ), - __( "Western Sahara", 'pff-paystack' ), - __( "Yemen", 'pff-paystack' ), - __( "Zambia", 'pff-paystack' ), - __( "Zimbabwe", 'pff-paystack' ), - ]; - if ( $implode ) { - $countries = implode( ',', $countries ); - } - return $countries; - } - - /** - * Returns the states available. - * - * @param boolean $implode - * @return array|string - */ - public function get_states( $implode = false ) { - $states = [ - __( 'Abia', 'pff-paystack' ), - __( 'Adamawa', 'pff-paystack' ), - __( 'Akwa Ibom', 'pff-paystack' ), - __( 'Anambra', 'pff-paystack' ), - __( 'Bauchi', 'pff-paystack' ), - __( 'Bayelsa', 'pff-paystack' ), - __( 'Benue', 'pff-paystack' ), - __( 'Borno', 'pff-paystack' ), - __( 'Cross River', 'pff-paystack' ), - __( 'Delta', 'pff-paystack' ), - __( 'Ebonyi', 'pff-paystack' ), - __( 'Edo', 'pff-paystack' ), - __( 'Ekiti', 'pff-paystack' ), - __( 'Enugu', 'pff-paystack' ), - __( 'FCT', 'pff-paystack' ), - __( 'Gombe', 'pff-paystack' ), - __( 'Imo', 'pff-paystack' ), - __( 'Jigawa', 'pff-paystack' ), - __( 'Kaduna', 'pff-paystack' ), - __( 'Kano', 'pff-paystack' ), - __( 'Katsina', 'pff-paystack' ), - __( 'Kebbi', 'pff-paystack' ), - __( 'Kogi', 'pff-paystack' ), - __( 'Kwara', 'pff-paystack' ), - __( 'Lagos', 'pff-paystack' ), - __( 'Nasarawa', 'pff-paystack' ), - __( 'Niger', 'pff-paystack' ), - __( 'Ogun', 'pff-paystack' ), - __( 'Ondo', 'pff-paystack' ), - __( 'Osun', 'pff-paystack' ), - __( 'Oyo', 'pff-paystack' ), - __( 'Plateau', 'pff-paystack' ), - __( 'Rivers', 'pff-paystack' ), - __( 'Sokoto', 'pff-paystack' ), - __( 'Taraba', 'pff-paystack' ), - __( 'Yobe', 'pff-paystack' ), - __( 'Zamfara', 'pff-paystack' ), - ]; - if ( $implode ) { - $states = implode( ',', $states ); - } - return $states; - } - - /** - * Returns the meta fields and their default values. - * - * @return array - */ - public function get_meta_defaults() { - return $this->defaults; - } - - /** - * Returns the allowed HTML for wp_kses() - * - * @return array - */ - public function get_allowed_html() { - return $this->allowed_html; - } - - /** - * Retrieve the user's IP address. - * - * @return string User's IP address. - */ - public function get_the_user_ip() { - $ip = ''; - - if ( ! empty( $_SERVER['HTTP_CLIENT_IP'] ) ) { - $ip = sanitize_text_field( wp_unslash( $_SERVER['HTTP_CLIENT_IP'] ) ); - } elseif ( ! empty( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) { - $ip = sanitize_text_field( wp_unslash( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ); - } elseif ( ! empty( $_SERVER['REMOTE_ADDR'] ) ) { - $ip = sanitize_text_field( wp_unslash( $_SERVER['REMOTE_ADDR'] ) ); - } - - return $ip; - } - - - /** - * Get the DB records by the transaction code supplied. - * - * @param string $code - * @return object - */ - public function get_db_record( $code, $column = 'txn_code' ) { - global $wpdb; - $return = false; - $table = $wpdb->prefix . PFF_PAYSTACK_TABLE; - // phpcs:ignore WordPress.DB.DirectDatabaseQuery - $record = $wpdb->get_results( - $wpdb->prepare( - "SELECT * - FROM %i - WHERE %i = %s" - , - $table, - $column, - $code - ), 'OBJECT' ); - - if ( ! empty( $record ) && isset( $record[0] ) ) { - $return = $record[0]; - } - return $return; - } - - // FUNCTIONS - - /** - * Gets the current forms meta fields values and set the defaults if needed. - * - * @param WP_Post $post - * @return array - */ - public function parse_meta_values( $post ) { - $new_values = []; - foreach ( $this->defaults as $key => $default ) { - $value = get_post_meta( $post->ID, '_' . $key, true ); - if ( false !== $value && ! empty( $value ) ) { - $new_values[ $key ] = $value; - } - } - - $meta = wp_parse_args( $new_values, $this->defaults ); - if ( '' === $meta['inventory'] || '0' === $meta['inventory'] ) { - if ( '' !== $meta['sold'] ) { - $meta['inventory'] = $meta['sold']; - } else { - $meta['inventory'] = '1'; - } - } - - // Strip any text from the variable amount field. - if ( isset( $meta['usevariableamount'] ) && is_string( $meta['usevariableamount'] ) ) { - $meta['usevariableamount'] = (int) $meta['usevariableamount']; - } - - $meta['minimum'] = floatval( $meta['minimum'] ); - //$meta['txncharge'] = floatval( $meta['txncharge'] ); - return $meta; - } - - /** - * Take an array of the submitted form values and formats it for a paystack request. - * - * @param array $metadata - * @return void - */ - public function format_meta_as_custom_fields( $metadata ) { - $fields = array(); - - foreach ( $metadata as $key => $value ) { - if ( is_array( $value ) ) { - $value = implode( ', ', $value ); - } - - switch ( $key ) { - case 'pf-fname': - $fields[] = array( - 'display_name' => __( 'Full Name', 'pff-paystack' ), - 'variable_name' => 'Full_Name', - 'type' => 'text', - 'value' => $value, - ); - break; - - case 'pf-plancode': - $fields[] = array( - 'display_name' => __( 'Plan', 'pff-paystack' ), - 'variable_name' => 'Plan', - 'type' => 'text', - 'value' => $value, - ); - break; - - case 'pf-vname': - $fields[] = array( - 'display_name' => __( 'Payment Option', 'pff-paystack' ), - 'variable_name' => 'Payment Option', - 'type' => 'text', - 'value' => $value, - ); - break; - - case 'pf-interval': - $fields[] = array( - 'display_name' => __( 'Plan Interval', 'pff-paystack' ), - 'variable_name' => 'Plan Interval', - 'type' => 'text', - 'value' => $value, - ); - break; - - case 'pf-quantity': - $fields[] = array( - 'display_name' => __( 'Quantity', 'pff-paystack' ), - 'variable_name' => 'Quantity', - 'type' => 'text', - 'value' => $value, - ); - break; - - default: - $display_name = ucwords( str_replace( array( '_', '-', 'pf' ), ' ', $key ) ); - $fields[] = array( - 'display_name' => $display_name, - 'variable_name' => $key, - 'type' => 'text', - 'value' => (string) $value, - ); - break; - } - } - return $fields; - } - - /** - * Formats the metadata for output on the retry form page. - * - * @param string $data - * @return string - */ - public function format_meta_as_display_fields( $data ) { - $new = json_decode( $data ); - $text = ''; - - if ( is_array( $new ) && array_key_exists( 0, $new ) ) { - foreach ( $new as $item ) { - if ( 'text' === $item->type ) { - $text .= sprintf( - '
- - %s -
', - esc_html( $item->display_name ), - esc_html( $item->value ) - ); - } else { - $text .= sprintf( - '
- - %s -
', - esc_html( $item->display_name ), - esc_url( $item->value ), - __( 'link', 'pff-paystack' ) - ); - } - } - } elseif ( is_object( $new ) ) { - if ( count( get_object_vars( $new ) ) > 0 ) { - foreach ( $new as $key => $item ) { - $text .= sprintf( - '
- - %s -
', - esc_html( $key ), - esc_html( $item ) - ); - } - } - } - return $text; - } - - /** - * Generate a new Paystack code. - * - * @param int $length Length of the code to generate. Default 10. - * @return string Generated code. - */ - public function generate_new_code( $length = 10 ) { - $characters = '06EFGHI9KL' . time() . 'MNOPJRSUVW01YZ923234' . time() . 'ABCD5678QXT'; - $characters_length = strlen( $characters ); - $random_string = ''; - - for ( $i = 0; $i < $length; $i++ ) { - $random_string .= $characters[ wp_rand( 0, $characters_length - 1 ) ]; - } - - return time() . '_' . $random_string; - } - - /** - * Check if the given code exists in the database. - * - * @param string $code The code to check. - * @global wpdb $wpdb WordPress database abstraction object. - * @return bool True if the code exists, false otherwise. - */ - public function check_code( $code ) { - global $wpdb; - $table = $wpdb->prefix . PFF_PAYSTACK_TABLE; - // phpcs:ignore WordPress.DB.DirectDatabaseQuery - $o_exist = $wpdb->get_results( - $wpdb->prepare( - "SELECT * FROM %i WHERE txn_code = %s", - $table, - $code - ) - ); - return ( count( $o_exist ) > 0 ); - } - - - /** - * Takes the amount and processes the "transactional" fees. - * - * @param integer $amount - * @return integer - */ - public function process_transaction_fees( $amount ) { - $fees = $this->get_fees(); - $pc = new Transaction_Fee( - $fees['prc'], - $fees['adc'], - $fees['ths'], - $fees['cap'] - ); - return $pc->add_for_ngn( $amount ); - } -} \ No newline at end of file diff --git a/includes/classes/class-payments-list-table.php b/includes/classes/class-payments-list-table.php deleted file mode 100644 index 5fef516..0000000 --- a/includes/classes/class-payments-list-table.php +++ /dev/null @@ -1,206 +0,0 @@ -form_id = sanitize_text_field( wp_unslash( $_GET['form'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended - $helpers = Helpers::get_instance(); - $data = array(); - $row_data = $helpers->get_payments_by_id( $this->form_id, $this->get_args() ); - $data = $this->format_row_data( $row_data ); - $columns = $this->get_columns(); - $hidden = $this->get_hidden_columns(); - $sortable = $this->get_sortable_columns(); - $per_page = 20; - $current_page = $this->get_pagenum(); - $total_items = count( $data ); - - $this->set_pagination_args( - array( - 'total_items' => $total_items, - 'per_page' => $per_page - ) - ); - $data = array_slice( $data, ( ( $current_page - 1 ) * $per_page ), $per_page ); - $this->_column_headers = array( $columns, $hidden, $sortable ); - $this->items = $data; - - $rows = count( $row_data ); - return $rows; - } - - /** - * Returns the headers and keys for our column headers - * - * @return array - */ - public function get_columns() { - $columns = array( - 'id' => '#', - 'email' => __( 'Email', 'pff-paystack' ), - 'amount' => __( 'Amount', 'pff-paystack' ), - 'txn_code' => __( 'Txn Code', 'pff-paystack' ), - 'metadata' => __( 'Data', 'pff-paystack' ), - 'date' => __( 'Date', 'pff-paystack' ), - ); - return $columns; - } - - /** - * Returns an array of the hidden columns - * - * @return array - */ - public function get_hidden_columns() { - return array(); - } - - /** - * Set which of our columns are sortable. - * - * @return void - */ - public function get_sortable_columns() { - return array( - 'email' => array( - 'email', - false - ), - 'date' => array( - 'created_at', - false - ), - 'amount' => array( - 'amount', - false - ) - ); - } - - /** - * Get the table data - * - * @return Array - */ - private function table_data( $data ) { - return $data; - } - - /** - * Define what data to show on each column of the table - * - * @param Array $item Data - * @param String $column_name - Current column name - * - * @return Mixed - */ - public function column_default( $item, $column_name ) { - switch ( $column_name ) { - case 'id': - case 'email': - case 'amount': - case 'txn_code': - case 'metadata': - case 'date': - return $item[ $column_name ]; - - default: - return print_r( $item, true ); - } - } - - /** - * Allows you to sort the data by the variables set in the $_GET - * - * @return int - */ - private function get_args() { - $args = array( - 'orderby' => 'created_at', - 'order' => 'desc', - ); - // phpcs:ignore WordPress.Security.NonceVerification.Recommended - if ( ! empty( $_GET['orderby'] ) ) { - $args['orderby'] = sanitize_text_field( wp_unslash( $_GET['orderby'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended - } - // phpcs:ignore WordPress.Security.NonceVerification.Recommended - if ( ! empty( $_GET['order'] ) ) { - $args['order'] = sanitize_text_field( wp_unslash( $_GET['order'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended - if ( 'date' === $args['order'] ) { - $args['order'] = 'created_at'; - } - } - return $args; - } - - /** - * Format each row into a readable HTML string. - * - * @param array $data - * @return array - */ - public function format_row_data( $alldata ) { - $currency = get_post_meta( $this->form_id, '_currency', true ); - $new_data = []; - foreach ( $alldata as $key => $row ) { - $new_key = $key + 1; - if ( $row->txn_code_2 != "" ) { - $txn_code = $row->txn_code_2; - } else { - $txn_code = $row->txn_code; - } - $new_data[] = array( - 'id' => $new_key, - 'email' => '' . $row->email . '', - 'amount' => $currency . '' . number_format( $row->amount ) . '', - 'txn_code' => $txn_code, - 'metadata' => $this->format_metadata( $row->metadata ), - 'date' => $row->created_at - ); - } - return $new_data; - } - - /** - * Format the Meta Data for output in each table row. - * - * @param string $data - * @return string - */ - public function format_metadata( $data ) { - $new = json_decode( $data ); - $text = ''; - - // Determine both for backwards compatability - if ( array_key_exists( "0", $new ) ) { - foreach ( $new as $key => $item ) { - if ( $item->type == 'text' ) { - $text .= '' . $item->display_name . ": " . $item->value . "
"; - } else { - $text .= '' . $item->display_name . ": link
"; - } - } - } else { - $text = ''; - if ( count( $new ) > 0 ) { - foreach ( $new as $key => $item ) { - $text .= '' . $key . ": " . $item . "
"; - } - } - } - return $text; - } -} \ No newline at end of file diff --git a/includes/classes/class-paystack-forms.php b/includes/classes/class-paystack-forms.php deleted file mode 100644 index 1ce1d59..0000000 --- a/includes/classes/class-paystack-forms.php +++ /dev/null @@ -1,141 +0,0 @@ - object. - * - * @var array - */ - public $classes = array(); - - /** - * Helpers functions for the custom payments. - * - * @var \paystack\payment_forms\Helpers - */ - public $helpers; - - /** - * Initialize the plugin by setting localization, filters, and - * administration functions. - * - * @access private - */ - private function __construct() { - $this->set_variables(); - $this->include_classes(); - $this->init_hooks(); - } - - /** - * Return an instance of this class. - * - * @return object \paystack\payment_forms\Payment_Forms - */ - public static function get_instance() { - // If the single instance hasn't been set, set it now. - if ( null == self::$instance ) { - self::$instance = new self(); - } - - return self::$instance; - } - - /** - * Sets our plugin variables. - * - * @return void - */ - private function set_variables() { - $this->classes = array( - 'activation' => '', - 'setup' => 'Setup', - 'helpers' => '', - 'settings' => 'Settings', - 'forms-list' => 'Forms_List', - 'submissions' => 'Submissions', - 'forms-update' => 'Forms_Update', - 'tinymce-plugin' => 'TinyMCE_Plugin', - 'form-shortcode' => 'Form_Shortcode', - 'field-shortcodes' => 'Field_Shortcodes', - 'api' => '', - 'request-plan' => 'Request_Plan', - 'request-subscription' => 'Request_Subscription', - 'transaction-verify' => 'Transaction_Verify', - 'form-submit' => 'Form_Submit', - 'transaction-fee' => '', - 'confirm-payment' => 'Confirm_Payment', - 'email' => '', - 'email-invoice' => 'Email_Invoice', - 'email-receipt' => 'Email_Receipt', - 'email-receipt-owner' => 'Email_Receipt_Owner', - 'retry-submit' => 'Retry_Submit', - ); - } - - /** - * Includes our class files - * - * @return void - */ - private function include_classes() { - foreach ( $this->classes as $key => $name ) { - include_once PFF_PAYSTACK_PLUGIN_PATH . '/includes/classes/class-' . $key . '.php'; - if ( '' !== $name ) { - $this->classes[ $key ] = new ( $this->namespace . $name ); - } - } - } - - /** - * Hook into actions and filters. - * - * @since 2.3 - */ - private function init_hooks() { - register_activation_hook( PFF_PAYSTACK_MAIN_FILE, array( '\paystack\payment_forms\activation', 'install' ) ); - } -} \ No newline at end of file diff --git a/includes/classes/class-request-plan.php b/includes/classes/class-request-plan.php deleted file mode 100644 index 0e2ce01..0000000 --- a/includes/classes/class-request-plan.php +++ /dev/null @@ -1,101 +0,0 @@ -set_module( 'plan' ); - } - - /** - * Send a request to Paystack and get the Plan Object. - * - * @return boolean|object - */ - public function fetch_plan( $code = '' ) { - $plan = false; - if ( '' === $code || ! $this->api_ready() ) { - return false; - } - $this->set_url_args( $code ); - $response = $this->get_request(); - if ( $this->is_plan_valid( $response ) ) { - $plan = $response; - } - return $plan; - } - - /** - * Reviews the plan parameters to see if the plan is active. - * - * @param object $plan - * @return boolean - */ - public function is_plan_valid( $plan ) { - if ( null === $plan ) { - return false; - } - if ( ! isset( $plan->status ) || false === $plan->status ) { - return false; - } - if ( ! isset( $plan->data->is_archived ) || true === $plan->data->is_archived ) { - return false; - } - if ( ! isset( $plan->data->is_deleted ) || true === $plan->data->is_deleted ) { - return false; - } - return true; - } - - /** - * Send a request to the Paystack "List plans" request, and return the first found one. - * - * @return boolean|object - */ - public function list_plans( $url_args = '' ) { - $plan = false; - if ( '' === $url_args || ! $this->api_ready() ) { - return false; - } - $this->set_url_args( $url_args ); - $response = $this->get_request(); - if ( isset( $response->meta->total ) && $response->meta->total >= 1 && isset( $response->data[0] ) ) { - $plan = $response->data[0]; - } - return $plan; - } - - /** - * Create a plan for the customer with their amount and interval. - * - * @return boolean|object - */ - public function create_plan( $body = [] ) { - $plan = false; - if ( empty( $body ) || ! $this->api_ready() ) { - return false; - } - $response = $this->post_request( $body ); - if ( isset( $response->plan_code ) ) { - $plan = $response; - } - return $plan; - } -} \ No newline at end of file diff --git a/includes/classes/class-request-subscription.php b/includes/classes/class-request-subscription.php deleted file mode 100644 index dda35ab..0000000 --- a/includes/classes/class-request-subscription.php +++ /dev/null @@ -1,43 +0,0 @@ -set_module( 'subscription' ); - } - - /** - * Create a plan for the customer with their amount and interval. - * - * @return boolean|object - */ - public function create_subscription( $body = [] ) { - $sub = false; - if ( empty( $body ) || ! $this->api_ready() ) { - return false; - } - $response = $this->post_request( $body ); - if ( isset( $response->status ) && true === $response->status ) { - $sub = $response; - } - return $sub; - } -} \ No newline at end of file diff --git a/includes/classes/class-retry-submit.php b/includes/classes/class-retry-submit.php deleted file mode 100644 index 4a4c5eb..0000000 --- a/includes/classes/class-retry-submit.php +++ /dev/null @@ -1,208 +0,0 @@ -helpers = new Helpers(); - $this->new_code = $this->generate_code() . '_2'; - $retry_record = $this->helpers->get_db_record( $this->code ); - if ( false !== $retry_record ) { - $this->retry_meta = $retry_record; - $this->form_id = $this->retry_meta->post_id; - $this->meta = $this->helpers->parse_meta_values( get_post( $this->form_id ) ); - } - } - - /** - * The action for the retry form. - * - * @return void - */ - public function retry_action() { - if ( ! isset( $_POST['pf-nonce'] ) || false === wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['pf-nonce'] ) ), 'pff-paystack-retry' ) ) { - $response = array( - 'result' => 'failed', - 'message' => __( 'Nonce verification is required.', 'pff-paystack' ), - ); - // Exit here, for not processing further because of the error. - exit( wp_json_encode( $response ) ); - } - - // False positive, we are using isset() to verify it exists before sanitization. - // phpcs:ignore WordPress.Security.ValidatedSanitizedInput - if ( isset( $_POST['code'] ) && '' !== trim( wp_unslash( $_POST['code'] ) ) ) { - $this->code = sanitize_text_field( wp_unslash( $_POST['code'] ) ); - } else { - $response = array( - 'result' => 'failed', - 'message' => __( 'Code is required', 'pff-paystack' ), - ); - // Exit here, for not processing further because of the error. - exit( wp_json_encode( $response ) ); - } - do_action( 'kkd_pff_paystack_before_save' ); - - /** - * Setup our data to be processed. - */ - $this->setup_data(); - - if ( 0 !== $this->form_id ) { - $subaccount = $this->meta['subaccount']; - $txnbearer = $this->meta['txnbearer']; - $transaction_charge = (int) $this->meta['merchantamount']; - $transaction_charge *= 100; - $fixedmetadata = json_decode( $this->retry_meta->metadata ); - $quantity = 1; - foreach ( $fixedmetadata as $nkey => $nvalue ) { - if ( 'Quantity' === $nvalue->variable_name ) { - $quantity = $nvalue->value; - } - if ( 'Full_Name' === $nvalue->variable_name ) { - $fullname = $nvalue->value; - } - } - } - - if ( empty( $this->meta['subaccount'] ) ) { - $subaccount = null; - $txnbearer = null; - $transaction_charge = null; - } - - if ( empty( $transaction_charge ) || 0 === $transaction_charge ) { - $transaction_charge = null; - } - - $this->update_retry_code(); - - $response = array( - 'result' => 'success', - 'code' => $this->new_code, - 'plan' => $this->retry_meta->plan, - 'quantity' => $quantity, - 'email' => $this->retry_meta->email, - 'name' => $fullname, - 'total' => $this->retry_meta->amount * 100, - 'custom_fields' => $fixedmetadata, - 'currency' => $this->meta['currency'], - 'subaccount' => $subaccount, - 'txnbearer' => $txnbearer, - 'transaction_charge' => $transaction_charge, - ); - - // We create 2 nonces here - // 1 incase the payment fails, and the user needs to try again. - // 2 if the payment is successful and the confirmation ajax needs to run. - $response['retryNonce'] = wp_create_nonce( 'pff-paystack-retry' ); - $response['confirmNonce'] = wp_create_nonce( 'pff-paystack-confirm' ); - - echo wp_json_encode( $response ); - - die(); - } - - /** - * Generate a unique Paystack code that does not yet exist in the database. - * - * @return string Generated unique code. - */ - public function generate_code() { - do { - $code = $this->helpers->generate_new_code(); - $check = $this->helpers->check_code( $code ); - } while ( $check ); - - return $code; - } - - /** - * Updates the DB row with the new transaction code. - * - * @return void - */ - protected function update_retry_code() { - global $wpdb; - $return = false; - $table = $wpdb->prefix . PFF_PAYSTACK_TABLE; - // phpcs:ignore WordPress.DB.DirectDatabaseQuery - $return = $wpdb->query( - $wpdb->prepare( - "UPDATE %i SET txn_code_2 = %s WHERE txn_code = %s", - $table, - $this->new_code, - $this->code - ) - ); - return $return; - } -} \ No newline at end of file diff --git a/includes/classes/class-settings.php b/includes/classes/class-settings.php deleted file mode 100644 index 5c835de..0000000 --- a/includes/classes/class-settings.php +++ /dev/null @@ -1,194 +0,0 @@ -fields = array( - 'general' => array( - 'mode' => array( - 'title' => __( 'Mode', 'pff-paystack' ), - 'type' => 'select', - 'default' => 'test', - ), - 'tsk' => array( - 'title' => __( 'Test Secret Key', 'pff-paystack' ), - 'type' => 'password', - 'default' => '', - ), - 'tpk' => array( - 'title' => __( 'Test Public Key', 'pff-paystack' ), - 'type' => 'text', - 'default' => '', - ), - 'lsk' => array( - 'title' => __( 'Live Secret Key', 'pff-paystack' ), - 'type' => 'password', - 'default' => '', - ), - 'lpk' => array( - 'title' => __( 'Live Public Key', 'pff-paystack' ), - 'type' => 'text', - 'default' => '', - ), - ), - 'fees' => array( - 'prc' => array( - 'title' => __( 'Percentage', 'pff-paystack' ), - 'type' => 'text', - 'default' => 1.5, - ), - 'ths' => array( - 'title' => __( 'Threshold
(amount above which Paystack adds the fixed amount below)', 'pff-paystack' ), - 'type' => 'text', - 'default' => 2500, - ), - 'adc' => array( - 'title' => __( 'Additional Charge
(amount added to percentage fee when transaction amount is above threshold) ', 'pff-paystack' ), - 'type' => 'text', - 'default' => 100, - ), - 'cap' => array( - 'title' => __( 'Cap
(maximum charge paystack can charge on your transactions)', 'pff-paystack' ), - 'type' => 'text', - 'default' => 2000, - ), - ), - ); - add_action( 'admin_menu', [ $this, 'register_settings_page' ] ); - add_action( 'admin_menu', [ $this, 'register_settings_fields' ] ); - } - - /** - * Registers our settings sub page under the Paystack Forms menu item. - * - * @return void - */ - public function register_settings_page() { - add_submenu_page( 'edit.php?post_type=paystack_form', __( 'Settings', 'pff-paystack' ), __( 'Settings', 'pff-paystack' ), 'edit_posts', 'settings', [ $this, 'output_settings_page' ] ); - } - - /** - * Registers our Settings fields with the WP API. - * - * @return void - */ - public function register_settings_fields() { - $fields = $this->get_settings_fields(); - // Run through each group, and the fields in there. - foreach ( $fields as $group => $fields ) { - foreach ( $fields as $field_key => $args ) { - register_setting( 'kkd-pff-paystack-settings-group', $field_key ); - } - } - } - - public function output_settings_page() { - ?> -
-

-

- - here', 'pff-paystack' ) ); ?> - -
- get_settings_fields(); - ?> - - $field ) { - ?> - - - - - -
- - - - - -
-
- -

- $field ) { - ?> - - - - - -
- -
- - - -
-
- fields ); - } - - /** - * Checks to see if the curren value is selected. - * - * @param string $value - * @param string $compare - * @return string - */ - public function is_option_selected( $value, $compare ) { - if ( $value == $compare ) { - $result = "selected"; - } else { - $result = ""; - } - return $result; - } -} diff --git a/includes/classes/class-setup.php b/includes/classes/class-setup.php deleted file mode 100644 index b8b94dc..0000000 --- a/includes/classes/class-setup.php +++ /dev/null @@ -1,152 +0,0 @@ - __( 'Paystack Forms', 'paystack_form' ), - 'singular_name' => __( 'Paystack Form', 'paystack_form' ), - 'add_new' => __( 'Add New', 'paystack_form' ), - 'add_new_item' => __( 'Add Paystack Form', 'paystack_form' ), - 'edit_item' => __( 'Edit Paystack Form', 'paystack_form' ), - 'new_item' => __( 'Paystack Form', 'paystack_form' ), - 'view_item' => __( 'View Paystack Form', 'paystack_form' ), - 'all_items' => __( 'All Forms', 'paystack_form' ), - 'search_items' => __( 'Search Paystack Forms', 'paystack_form' ), - 'not_found' => __( 'No Paystack Forms found', 'paystack_form' ), - 'not_found_in_trash' => __( 'No Paystack Forms found in Trash', 'paystack_form' ), - 'parent_item_colon' => __( 'Parent Paystack Form:', 'paystack_form' ), - 'menu_name' => __( 'Paystack Forms', 'paystack_form' ), - ]; - - $args = [ - 'labels' => $labels, - 'hierarchical' => true, - 'description' => __( 'Paystack Forms filterable by genre', 'paystack_form' ), - 'supports' => array( 'title', 'editor' ), - 'public' => true, - 'show_ui' => true, - 'show_in_menu' => true, - 'show_in_rest' => false, - 'menu_position' => 5, - 'menu_icon' => PFF_PAYSTACK_PLUGIN_URL . '/assets/images/logo.png', - 'show_in_nav_menus' => true, - 'publicly_queryable' => true, - 'exclude_from_search' => false, - 'has_archive' => false, - 'query_var' => true, - 'can_export' => true, - 'rewrite' => false, - 'comments' => false, - 'capability_type' => 'post', - ]; - register_post_type( 'paystack_form', $args ); - } - - /** - * Load the plugin text domain for translation. - */ - public function load_plugin_textdomain() { - load_plugin_textdomain( 'pff-paystack', false, PFF_PAYSTACK_PLUGIN_PATH . '/languages/' ); - } - - /** - * Add a link to our settings page in the plugin action links. - */ - public function add_action_links( $links ) { - $settings_link = array( - '' . __( 'Settings', 'pff-paystack' ) . '', - ); - return array_merge( $settings_link, $links ); - } - - /** - * Enqueues our admin css. - * - * @param string $hook - * @return void - */ - public function admin_enqueue_styles( $hook ) { - if ( $hook != 'paystack_form_page_submissions' && $hook != 'paystack_form_page_settings' ) { - return; - } - wp_enqueue_style( PFF_PLUGIN_NAME, PFF_PAYSTACK_PLUGIN_URL . '/assets/css/paystack-admin.css', array(), PFF_PAYSTACK_VERSION, 'all' ); - } - - /** - * Enqueue the Administration scripts. - * - * @return void - */ - public function admin_enqueue_scripts() { - wp_enqueue_script( PFF_PLUGIN_NAME, PFF_PAYSTACK_PLUGIN_URL . '/assets/js/paystack-admin.js', array( 'jquery' ), PFF_PAYSTACK_VERSION, false ); - } - - /** - * Enques our frontend styles - * - * @return void - */ - public function enqueue_styles() { - wp_enqueue_style( PFF_PLUGIN_NAME . '-style', PFF_PAYSTACK_PLUGIN_URL . '/assets/css/pff-paystack.css', array(), PFF_PAYSTACK_VERSION, 'all' ); - wp_enqueue_style( PFF_PLUGIN_NAME . '-font-awesome', PFF_PAYSTACK_PLUGIN_URL . '/assets/css/font-awesome.min.css', array(), PFF_PAYSTACK_VERSION, 'all' ); - } - - /** - * Enqueue the frontend scripts. - * - * @return void - */ - public function enqueue_scripts() { - - $page_content = get_the_content(); - if ( ! has_shortcode( $page_content, 'pff-paystack' ) ) { - return; - } - - wp_enqueue_script( 'blockUI', PFF_PAYSTACK_PLUGIN_URL . '/assets/js/jquery.blockUI.min.js', array( 'jquery', 'jquery-ui-core' ), PFF_PAYSTACK_VERSION, true ); - - wp_register_script( 'Paystack', 'https://js.paystack.co/v1/inline.js', false, PFF_PAYSTACK_VERSION, true ); - wp_enqueue_script( 'Paystack' ); - - wp_enqueue_script( PFF_PLUGIN_NAME . '-public', PFF_PAYSTACK_PLUGIN_URL . '/assets/js/paystack-public.js', array( 'jquery' ), PFF_PAYSTACK_VERSION, true ); - - $helpers = new Helpers(); - $js_args = [ - 'key' => $helpers->get_public_key(), - 'fee' => $helpers->get_fees(), - ]; - wp_localize_script( PFF_PLUGIN_NAME . '-public', 'pffSettings', $js_args , PFF_PAYSTACK_VERSION, true ); - } -} diff --git a/includes/classes/class-submissions.php b/includes/classes/class-submissions.php deleted file mode 100644 index 3191905..0000000 --- a/includes/classes/class-submissions.php +++ /dev/null @@ -1,183 +0,0 @@ -get_payments_list_table(); - $data = $payments_table->prepare_items(); - ?> -
-
-

-

- -

- 0 ) { ?> -
- - - -
- -
-
-
-
-
-
- display(); ?> -
- get_payments_by_id( $form_id ); - - if ( count( $all_data ) > 0 ) { - $header = $all_data[0]; - - $csv_output .= "#,"; - $csv_output .= "Email,"; - $csv_output .= "Amount,"; - $csv_output .= "Date Paid,"; - $csv_output .= "Reference,"; - - $new = json_decode( $header->metadata ); - if ( array_key_exists( 0, $new ) ) { - foreach ( $new as $item ) { - $csv_output .= $this->prep_csv_data( $item->display_name ) . ','; - } - } elseif ( count( $new ) > 0 ) { - foreach ( $new as $key => $item ) { - $csv_output .= $this->prep_csv_data( $key ) . ','; - } - } - - $csv_output .= "\n"; - - foreach ( $all_data as $key => $dbdata ) { - $newkey = $key + 1; - $txn_code = '' !== $dbdata->txn_code_2 ? $dbdata->txn_code_2 : $dbdata->txn_code; - - $csv_output .= $this->prep_csv_data( $newkey ) . ','; - $csv_output .= $this->prep_csv_data( $dbdata->email ) . ','; - $csv_output .= $this->prep_csv_data( $currency . ' ' . $dbdata->amount ) . ','; - $csv_output .= $this->prep_csv_data( substr( $dbdata->paid_at, 0, 10 ) ) . ','; - $csv_output .= $this->prep_csv_data( $txn_code ) . ','; - - $new = json_decode( $dbdata->metadata ); - if ( array_key_exists( 0, $new ) ) { - foreach ( $new as $item ) { - $csv_output .= $this->prep_csv_data( $item->value ) . ','; - } - } elseif ( count( $new ) > 0 ) { - foreach ( $new as $item ) { - $csv_output .= $this->prep_csv_data( $item ) . ','; - } - } - - $csv_output .= "\n"; - } - - $filename = $obj->post_title . "_payments_" . gmdate( 'Y-m-d_H-i' ); - - header( 'Content-Type: application/vnd.ms-excel' ); - header( 'Content-Disposition: attachment; filename="' . $filename . '.csv"' ); - echo $csv_output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- CSV output must not be escaped. - exit; - } - } -} diff --git a/includes/classes/class-tinymce-plugin.php b/includes/classes/class-tinymce-plugin.php deleted file mode 100644 index da59a86..0000000 --- a/includes/classes/class-tinymce-plugin.php +++ /dev/null @@ -1,70 +0,0 @@ -percentage = $percentage; - $this->additional_charge = $additional_charge; - $this->crossover_total = $crossover_total; - $this->cap = $cap; - $this->__setup(); - } - - /** - * Setup method to initialize calculated values. - */ - private function __setup() { - $this->charge_divider = $this->__charge_divider(); - $this->crossover = $this->__crossover(); - $this->flatline_plus_charge = $this->__flatline_plus_charge(); - $this->flatline = $this->__flatline(); - } - - /** - * Calculate charge divider. - * - * @return float Charge divider. - */ - private function __charge_divider() { - return floatval( 1 - $this->percentage ); - } - - /** - * Calculate crossover value. - * - * @return float Crossover value. - */ - private function __crossover() { - return ceil( ( $this->crossover_total * $this->charge_divider ) - $this->additional_charge ); - } - - /** - * Calculate flatline plus charge. - * - * @return float Flatline plus charge. - */ - private function __flatline_plus_charge() { - return floor( ( $this->cap - $this->additional_charge ) / $this->percentage ); - } - - /** - * Calculate flatline value. - * - * @return float Flatline value. - */ - private function __flatline() { - return $this->flatline_plus_charge - $this->cap; - } - - /** - * Add charge for amount in kobo. - * - * @param int $amountinkobo Amount in kobo. - * @return float Charged amount. - */ - public function add_for_kobo( $amountinkobo ) { - if ( $amountinkobo > $this->flatline ) { - return $amountinkobo + $this->cap; - } elseif ( $amountinkobo > $this->crossover ) { - return ceil( ( $amountinkobo + $this->additional_charge ) / $this->charge_divider ); - } else { - return ceil( $amountinkobo / $this->charge_divider ); - } - } - - /** - * Add charge for amount in NGN. - * - * @param int $amountinngn Amount in NGN. - * @return float Charged amount. - */ - public function add_for_ngn( $amountinngn ) { - return $this->add_for_kobo( ceil( $amountinngn * 100 ) ) / 100; - } -} diff --git a/includes/classes/class-transaction-verify.php b/includes/classes/class-transaction-verify.php deleted file mode 100644 index b141570..0000000 --- a/includes/classes/class-transaction-verify.php +++ /dev/null @@ -1,73 +0,0 @@ -set_module( 'transaction/verify' ); - } - - /** - * Send a request to Paystack and get the Plan Object. - * - * @return boolean|object - */ - public function verify_transaction( $code = '' ) { - $return = false; - if ( '' === $code || ! $this->api_ready() ) { - return false; - } - - $this->set_url_args( $code ); - $response = $this->get_request(); - $return = $this->verify_response( $response ); - return $return; - } - - /** - * Reviews the transaction and returns success or an error and a message. - * - * @param object $response - * @return boolean - */ - public function verify_response( $response ) { - $return = $response; - if ( false === $response ) { - $return = [ - 'message' => __( 'Payment Verification Failed', 'pff-paystack' ), - 'result' => 'failed', - ]; - } else { - if ( 'success' === $response->data->status ) { - $return = [ - 'message' => __( 'Payment Verification Passed', 'pff-paystack' ), - 'result' => 'success', - 'data' => wp_json_encode( $response->data ), - ]; - } else { - $return = [ - 'message' => __( 'Transaction Failed/Invalid Code', 'pff-paystack' ), - 'result' => 'failed', - ]; - } - } - return $return; - } -} \ No newline at end of file diff --git a/includes/classes/deprecated.php b/includes/classes/deprecated.php deleted file mode 100644 index ffe53e1..0000000 --- a/includes/classes/deprecated.php +++ /dev/null @@ -1,14 +0,0 @@ - $item) { + if ($item->type == 'text') { + $text.= '
+ + '.$item->value.' +
'; + }else{ + $text.= '
+ + link +
'; + } + + } + }else{ + $text = ''; + if (count($new) > 0) { + foreach ($new as $key => $item) { + $text.= '
+ + '.$item.' +
'; + } + } + } + // + return $text; +} + + global $wpdb; + $table = $wpdb->prefix.KKD_PFF_PAYSTACK_TABLE; + $record = $wpdb->get_results($wpdb->prepare("SELECT * FROM %s WHERE txn_code = %s", $table, $code)); + +if (array_key_exists("0", $record)) { + get_header(); + $dbdata = $record[0]; + $currency = get_post_meta($dbdata->post_id, '_currency', true); + + + + + ?> +
+
+
+
+
+ + +
+ +
+ Payment Invoice +
+ +
+
+ + email); ?> +
+
+ + amount)); ?> +
+ metadata)); ?> + +
+ + created_at); ?> +
+ paid == 1) {?> +
+ + Successful +
+ + + +
+
+ + +
+
+
+
+
+ \n" -"Language-Team: LANGUAGE \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"POT-Creation-Date: 2024-10-04T13:52:09+00:00\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"X-Generator: WP-CLI 2.8.1\n" -"X-Domain: plugin-payment-forms-for-wordpress\n" - -#. Plugin Name of the plugin -msgid "Payment Forms for Paystack" -msgstr "" - -#. Plugin URI of the plugin -msgid "https://github.com/PaystackHQ/Wordpress-Payment-forms-for-Paystack" -msgstr "" - -#. Description of the plugin -msgid "Payment Forms for Paystack allows you create forms that will be used to bill clients for goods and services via Paystack." -msgstr "" - -#. Author of the plugin -msgid "Paystack" -msgstr "" - -#. Author URI of the plugin -msgid "http://paystack.com" -msgstr "" diff --git a/languages/pff-paystack-en_US.mo b/languages/pff-paystack-en_US.mo deleted file mode 100644 index 3ddee17..0000000 Binary files a/languages/pff-paystack-en_US.mo and /dev/null differ diff --git a/languages/pff-paystack-en_US.po b/languages/pff-paystack-en_US.po deleted file mode 100644 index c5e1bc9..0000000 --- a/languages/pff-paystack-en_US.po +++ /dev/null @@ -1,35 +0,0 @@ -# Copyright (C) 2024 Paystack -# This file is distributed under the GPL-2.0+. -msgid "" -msgstr "" -"Project-Id-Version: Payment Forms for Paystack 4.0.0\n" -"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/plugin-payment-forms-for-wordpress\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"POT-Creation-Date: 2024-10-04T13:52:09+00:00\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"X-Generator: WP-CLI 2.8.1\n" -"X-Domain: plugin-payment-forms-for-wordpress\n" - -#. Plugin Name of the plugin -msgid "Payment Forms for Paystack" -msgstr "" - -#. Plugin URI of the plugin -msgid "https://github.com/PaystackHQ/Wordpress-Payment-forms-for-Paystack" -msgstr "" - -#. Description of the plugin -msgid "Payment Forms for Paystack allows you create forms that will be used to bill clients for goods and services via Paystack." -msgstr "" - -#. Author of the plugin -msgid "Paystack" -msgstr "" - -#. Author URI of the plugin -msgid "http://paystack.com" -msgstr "" diff --git a/languages/pff-paystack.pot b/languages/pff-paystack.pot index c5e1bc9..e69de29 100644 --- a/languages/pff-paystack.pot +++ b/languages/pff-paystack.pot @@ -1,35 +0,0 @@ -# Copyright (C) 2024 Paystack -# This file is distributed under the GPL-2.0+. -msgid "" -msgstr "" -"Project-Id-Version: Payment Forms for Paystack 4.0.0\n" -"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/plugin-payment-forms-for-wordpress\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"POT-Creation-Date: 2024-10-04T13:52:09+00:00\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"X-Generator: WP-CLI 2.8.1\n" -"X-Domain: plugin-payment-forms-for-wordpress\n" - -#. Plugin Name of the plugin -msgid "Payment Forms for Paystack" -msgstr "" - -#. Plugin URI of the plugin -msgid "https://github.com/PaystackHQ/Wordpress-Payment-forms-for-Paystack" -msgstr "" - -#. Description of the plugin -msgid "Payment Forms for Paystack allows you create forms that will be used to bill clients for goods and services via Paystack." -msgstr "" - -#. Author of the plugin -msgid "Paystack" -msgstr "" - -#. Author URI of the plugin -msgid "http://paystack.com" -msgstr "" diff --git a/package.json b/package.json deleted file mode 100644 index 9a4e3b0..0000000 --- a/package.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "name": "pff-paystack", - "version": "4.0.0", - "description": "Paystack Payment forms for WordPress", - "main": "gulpfile.js", - "scripts": { - "build-pot": "wp i18n make-pot . languages/pff-paystack.pot", - "build-mopo": "rm -R languages/pff-paystack-en_EN.mo && cp languages/pff-paystack.pot languages/pff-paystack-en_EN.po && wp i18n make-mo languages", - "translate-US": "cp languages/pff-paystack-en_EN.po languages/pff-paystack-en_US.po && cp languages/pff-paystack-en_EN.mo languages/pff-paystack-en_US.mo" - } -} diff --git a/paystack-forms.php b/paystack-forms.php index a27e361..124525b 100644 --- a/paystack-forms.php +++ b/paystack-forms.php @@ -3,7 +3,7 @@ Plugin Name: Payment Forms for Paystack Plugin URI: https://github.com/PaystackHQ/Wordpress-Payment-forms-for-Paystack Description: Payment Forms for Paystack allows you create forms that will be used to bill clients for goods and services via Paystack. - Version: 4.0.0 + Version: 3.4.2 Author: Paystack Author URI: http://paystack.com License: GPL-2.0+ @@ -13,33 +13,231 @@ if (!defined('WPINC')) { die; } -define( 'PFF_PAYSTACK_PLUGIN_PATH', plugin_dir_path( __FILE__ ) ); -define( 'PFF_PAYSTACK_PLUGIN_URL', plugin_dir_url( __FILE__ ) ); -define( 'PFF_PAYSTACK_MAIN_FILE', __FILE__ ); -define( 'PFF_PAYSTACK_VERSION', '4.0.0' ); -define( 'PFF_PAYSTACK_TABLE', 'paystack_forms_payments' ); -define( 'PFF_PLUGIN_BASENAME', plugin_basename(__FILE__) ); -define( 'PFF_PLUGIN_NAME', 'pff-paystack' ); +define('KKD_PFF_PAYSTACK_PLUGIN_PATH', plugins_url(__FILE__)); +define('KKD_PFF_PAYSTACK_MAIN_FILE', __FILE__); +define('KKD_PFF_PAYSTACK_VERSION', '3.4.2'); +define('KKD_PFF_PAYSTACK_TABLE', 'paystack_forms_payments'); -// Transaction definitions -define( 'PFF_PAYSTACK_PERCENTAGE', 1.5 ); -define( 'PFF_PAYSTACK_CROSSOVER_TOTAL', 2500 ); -define( 'PFF_PAYSTACK_ADDITIONAL_CHARGE', 100 ); -define( 'PFF_PAYSTACK_LOCAL_CAP', 2000 ); +define('KKD_PFF_PLUGIN_BASENAME', plugin_basename(__FILE__)); -/*define('PFF_PAYSTACK_CHARGE_DIVIDER', floatval( 1 - PFF_PAYSTACK_PERCENTAGE ) ); -define('PFF_PAYSTACK_CROSSOVER_AMOUNT', intval( ( PFF_PAYSTACK_CROSSOVER_TOTAL * PFF_PAYSTACK_CHARGE_DIVIDER ) - PFF_PAYSTACK_ADDITIONAL_CHARGE ) ); -define('PFF_PAYSTACK_FLATLINE_AMOUNT_PLUS_CHARGE', intval( ( PFF_PAYSTACK_LOCAL_CAP - PFF_PAYSTACK_ADDITIONAL_CHARGE ) / PFF_PAYSTACK_PERCENTAGE ) ); -define('PFF_PAYSTACK_FLATLINE_AMOUNT', PFF_PAYSTACK_FLATLINE_AMOUNT_PLUS_CHARGE - PFF_PAYSTACK_LOCAL_CAP );*/ +// fix some badly enqueued scripts with no sense of HTTPS +add_action('wp_print_scripts', 'kkd_pff_paystack_enqueueScriptsFix', 100); +add_action('wp_print_styles', 'kkd_pff_paystack_enqueueStylesFix', 100); -include_once PFF_PAYSTACK_PLUGIN_PATH . '/includes/classes/class-paystack-forms.php'; +/** + * force plugins to load scripts with SSL if page is SSL + */ +function kkd_pff_paystack_enqueueScriptsFix() +{ + if (!is_admin()) { + if (!empty($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] != "off")) { + global $wp_scripts; + foreach ((array) $wp_scripts->registered as $script) { + if (stripos($script->src, 'http://', 0) !== false) { + $script->src = str_replace('http://', 'https://', $script->src); + } + } + } + } +} /** - * Returns an instance of the Paystack Payment forms Object - * - * @return object \paystack\payment_forms\Payment_Forms() + * force plugins to load styles with SSL if page is SSL */ -function pff_paystack() { - return \paystack\payment_forms\Payment_Forms::get_instance(); +function kkd_pff_paystack_enqueueStylesFix() +{ + if (!is_admin()) { + if (!empty($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] != "off")) { + global $wp_styles; + foreach ((array) $wp_styles->registered as $script) { + if (stripos($script->src, 'http://', 0) !== false) { + $script->src = str_replace('http://', 'https://', $script->src); + } + } + } + } +} + +function kkd_pff_tl_save_error() +{ + update_option('plugin_error', ob_get_contents()); +} +add_action('activated_plugin', 'kkd_pff_tl_save_error'); +/* Then to display the error message: */ +echo get_option('plugin_error'); + + +function kkd_pff_paystack_activate_paystack_forms() +{ + include_once plugin_dir_path(__FILE__) . 'includes/class-paystack-forms-activator.php'; + Kkd_Pff_Paystack_Activator::activate(); +} + +register_activation_hook(__FILE__, 'kkd_pff_paystack_activate_paystack_forms'); + + +require plugin_dir_path(__FILE__) . 'includes/class-paystack-forms.php'; + +function kkd_pff_paystack_run_paystack_forms() +{ + $plugin = new Kkd_Pff_Paystack(); + $plugin->run(); +} +kkd_pff_paystack_run_paystack_forms(); + +function kkd_pff_paystack_shortcode_button_script() +{ + if (wp_script_is("quicktags")) { + ?> + + non_wp_rules['paystackinvoice$'] = $plugin_url; WP_PLUGIN_URL . '/data-fetcher/list-data.php' +// $wp_rewrite->non_wp_rules['paystackinvoice/$'] = $plugin_url; +// file_put_contents(ABSPATH.'.htaccess', $wp_rewrite->mod_rewrite_rules() ); +// } +// add_action( 'init', 'my_rewrite' ); +// function my_rewrite() { +// global $wp_rewrite; +// add_rewrite_rule('paystackinvoice$', KKD_PFF_PAYSTACK_PLUGIN_PATH. 'includes/paystack-invoice.php', 'top'); +// add_rewrite_rule('paystackinvoice/$', KKD_PFF_PAYSTACK_PLUGIN_PATH. 'includes/paystack-invoice.php', 'top'); +// // add_rewrite_rule('paystackinvoice/$', plugins_url( 'includes/paystack-invoice.php', __FILE__ ), 'top'); +// $wp_rewrite->flush_rules(true); // This should really be done in a plugin activation +// } + +add_action('init', 'kkd_pff_init'); +function kkd_pff_init() +{ + add_rewrite_rule('^paystackinvoice$', 'index.php?kkd_pff_stats=true', 'top'); +} + +// But WordPress has a whitelist of variables it allows, so we must put it on that list +add_action('query_vars', 'kkd_pff_query_vars'); +function kkd_pff_query_vars($query_vars) +{ + $query_vars[] = 'kkd_pff_stats'; + return $query_vars; +} + +// If this is done, we can access it later +// This example checks very early in the process: +// if the variable is set, we include our page and stop execution after it +add_action('parse_request', 'kkd_pff_parse_request'); +function kkd_pff_parse_request(&$wp) +{ + if (array_key_exists('kkd_pff_stats', $wp->query_vars)) { + include dirname(__FILE__) . '/includes/paystack-invoice.php'; + exit(); + } } -$_GLOBAL['pff_paystack'] = pff_paystack(); +// add_action( 'init', 'kkd_pff_paystack_webhook_url_rewrite' ); +// function kkd_pff_paystack_webhook_url_rewrite(){ +// global $wp_rewrite; +// $plugin_url = plugins_url( 'includes/paystack-webhook.php', __FILE__ ); +// $plugin_url = substr( $plugin_url, strlen( home_url() ) + 1 ); +// $wp_rewrite->non_wp_rules['kkd_wppf_webhoook$'] = $plugin_url; +// $wp_rewrite->non_wp_rules['kkd_wppf_webhoook/$'] = $plugin_url; +// file_put_contents(ABSPATH.'.htaccess', $wp_rewrite->mod_rewrite_rules() ); +// } \ No newline at end of file diff --git a/public/class-paystack-forms-public-for-old-themes.php b/public/class-paystack-forms-public-for-old-themes.php new file mode 100644 index 0000000..5ca97a0 --- /dev/null +++ b/public/class-paystack-forms-public-for-old-themes.php @@ -0,0 +1,1880 @@ +plugin_name = $plugin_name; + $this->version = $version; + } + public function enqueue_styles() + { + wp_enqueue_style($this->plugin_name.'1', plugin_dir_url(__FILE__) . 'css/pff-paystack-style.css', array(), $this->version, 'all'); + wp_enqueue_style($this->plugin_name.'2', plugin_dir_url(__FILE__) . 'css/font-awesome.min.css', array(), $this->version, 'all'); + } + + public static function fetchPublicKey() + { + $mode = esc_attr(get_option('mode')); + if ($mode == 'test') { + $key = esc_attr(get_option('tpk')); + } else { + $key = esc_attr(get_option('lpk')); + } + return $key; + } + + public static function fetchFeeSettings() + { + $ret = []; + $ret['prc'] = intval(floatval(esc_attr(get_option('prc', 1.5))) * 100) / 10000; + $ret['ths'] = intval(floatval(esc_attr(get_option('ths', 2500))) * 100); + $ret['adc'] = intval(floatval(esc_attr(get_option('adc', 100))) * 100); + $ret['cap'] = intval(floatval(esc_attr(get_option('cap', 2000))) * 100); + return $ret; + } + + public function enqueue_scripts() + { + wp_enqueue_script('blockUI', plugin_dir_url(__FILE__) . 'js/jquery.blockUI.min.js', false, $this->version); + wp_enqueue_script('jquery-ui-core'); + wp_register_script('Paystack', 'https://js.paystack.co/v1/inline.js', false, '1'); + wp_enqueue_script('Paystack'); + wp_enqueue_script('paystack_frontend', plugin_dir_url(__FILE__) . 'js/paystack-forms-public.js', false, $this->version); + wp_localize_script('paystack_frontend', 'kkd_pff_settings', array('key'=> Kkd_Pff_Paystack_Public::fetchPublicKey(), 'fee'=>Kkd_Pff_Paystack_Public::fetchFeeSettings()), $this->version, true, true); + } +} + +define('KKD_PFF_PAYSTACK_PERCENTAGE', 0.015); +define('KKD_PFF_PAYSTACK_CROSSOVER_TOTAL', 250000); +define('KKD_PFF_PAYSTACK_ADDITIONAL_CHARGE', 10000); +define('KKD_PFF_PAYSTACK_LOCAL_CAP', 200000); + +define('KKD_PFF_PAYSTACK_CHARGE_DIVIDER', floatval(1-KKD_PFF_PAYSTACK_PERCENTAGE)); +define('KKD_PFF_PAYSTACK_CROSSOVER_AMOUNT', intval((KKD_PFF_PAYSTACK_CROSSOVER_TOTAL*KKD_PFF_PAYSTACK_CHARGE_DIVIDER)-KKD_PFF_PAYSTACK_ADDITIONAL_CHARGE)); +define('KKD_PFF_PAYSTACK_FLATLINE_AMOUNT_PLUS_CHARGE', intval((KKD_PFF_PAYSTACK_LOCAL_CAP-KKD_PFF_PAYSTACK_ADDITIONAL_CHARGE)/KKD_PFF_PAYSTACK_PERCENTAGE)); +define('KKD_PFF_PAYSTACK_FLATLINE_AMOUNT', KKD_PFF_PAYSTACK_FLATLINE_AMOUNT_PLUS_CHARGE - KKD_PFF_PAYSTACK_LOCAL_CAP); + +function kkd_pff_paystack_add_paystack_charge($amount) +{ + // $amountinkobo = $amount; // * 100; + $charge = 0; + $amount = intval($amount); + if ($amount <= 2500) { + $charge = floatval($amount*KKD_PFF_PAYSTACK_PERCENTAGE); + } else { + $charge = floatval($amount*KKD_PFF_PAYSTACK_PERCENTAGE)+100; + } + if ($charge > 2000) { + $charge = 2000; + } + $amount += $charge; + return $amount; + // if ($amountinkobo > KKD_PFF_PAYSTACK_FLATLINE_AMOUNT) + // return ($amountinkobo + KKD_PFF_PAYSTACK_LOCAL_CAP)/100; + // elseif ($amountinkobo > KKD_PFF_PAYSTACK_CROSSOVER_AMOUNT) + // return (intval(($amountinkobo + KKD_PFF_PAYSTACK_ADDITIONAL_CHARGE) / KKD_PFF_PAYSTACK_CHARGE_DIVIDER))/100; + // else + // return (intval($amountinkobo / KKD_PFF_PAYSTACK_CHARGE_DIVIDER))/100; +} + +add_filter("wp_mail_content_type", "kkd_pff_paystack_mail_content_type"); +function kkd_pff_paystack_mail_content_type() +{ + return "text/html"; +} +add_filter("wp_mail_from_name", "kkd_pff_paystack_mail_from_name"); +function kkd_pff_paystack_mail_from_name() +{ + $name = get_option('blogname'); + return $name; +} + + +function kkd_pff_paystack_send_invoice($currency, $amount, $name, $email, $code) +{ + // echo date('F j,Y'); + $user_email = stripslashes($email); + + $email_subject = "Payment Invoice for ".$currency.' '.number_format($amount); + + ob_start(); ?> + + + + + + + + + + + + + + + + + + + " . "\r\n"); + $headers = "From: ".$website."<$admin_email>" . "\r\n"; + wp_mail($user_email, $email_subject, $message, $headers); +} +function kkd_pff_paystack_send_receipt($id, $currency, $amount, $name, $email, $code, $metadata) +{ + // echo date('F j,Y'); + $user_email = stripslashes($email); + $subject = get_post_meta($id, '_subject', true); + $merchant = get_post_meta($id, '_merchant', true); + $heading = get_post_meta($id, '_heading', true); + $sitemessage = get_post_meta($id, '_message', true); + + $email_subject =$subject; + + ob_start(); ?> + + + + + + + + + + + + + + + + + + + + " . "\r\n"); + $headers = "From: ".$website."<$admin_email>" . "\r\n"; + wp_mail($user_email, $email_subject, $message, $headers); +} +function kkd_pff_paystack_send_receipt_owner($id, $currency, $amount, $name, $email, $code, $metadata) +{ + // echo date('F j,Y'); + $user_email = stripslashes($email); + $subject = "You just received a payment"; + $heading = get_post_meta($id, '_heading', true); + $sitemessage = get_post_meta($id, '_message', true); + + $email_subject =$subject; + + ob_start(); ?> + + + + + + + + + + + + + + + + + + + + " . "\r\n"); + $headers = "From: ".$website."<$admin_email>" . "\r\n"; + wp_mail($admin_email, $email_subject, $message, $headers); +} +function kkd_pff_paystack_fetch_plan($code) +{ + $mode = esc_attr(get_option('mode')); + if ($mode == 'test') { + $key = esc_attr(get_option('tsk')); + } else { + $key = esc_attr(get_option('lsk')); + } + $paystack_url = 'https://api.paystack.co/plan/' . $code; + $headers = array( + 'Authorization' => 'Bearer ' . $key + ); + $args = array( + 'headers' => $headers, + 'timeout' => 60 + ); + $request = wp_remote_get($paystack_url, $args); + if (! is_wp_error($request)) { + $paystack_response = json_decode(wp_remote_retrieve_body($request)); + } + return $paystack_response; +} +function kkd_pff_paystack_form_shortcode($atts) +{ + ob_start(); + + // Ensure the current user is populated + global $current_user; + wp_get_current_user(); + $user_id = $current_user->ID; + $email = sanitize_email($current_user->user_email); + $fname = sanitize_text_field($current_user->user_firstname); + $lname = sanitize_text_field($current_user->user_lastname); + $fullname = $fname || $lname ? trim($fname . ' ' . $lname) : ''; + + // Use array access for shortcode attributes + $atts = shortcode_atts(array('id' => 0), $atts, 'paystack_form'); + $id = intval($atts['id']); // Ensure $id is an integer + + $pk = Kkd_Pff_Paystack_Public::fetchPublicKey(); + if (!$pk) { + $settingslink = esc_url(get_admin_url(null, 'edit.php?post_type=paystack_form&page=class-paystack-forms-admin.php')); + echo "
You must set your Paystack API keys first settings
"; + return ob_get_clean(); // Return early to avoid further processing + } + + if ($id > 0) { + $obj = get_post($id); + if ($obj && $obj->post_type === 'paystack_form') { + // Fetch and sanitize meta values + $meta_keys = [ + '_amount', '_successmsg', '_paybtn', '_loggedin', '_txncharge', + '_currency', '_recur', '_recurplan', '_usequantity', '_quantity', + '_useagreement', '_agreementlink', '_minimum', '_variableamount', + '_usevariableamount', '_hidetitle' + ]; + $meta = []; + foreach ($meta_keys as $key) { + $meta[$key] = sanitize_text_field(get_post_meta($id, $key, true)); + } + + // Ensure minimum defaults are set + $meta['_minimum'] = $meta['_minimum'] === "" ? 0 : $meta['_minimum']; + $meta['_usevariableamount'] = $meta['_usevariableamount'] === "" ? 0 : $meta['_usevariableamount']; + + // Process variable amount options if applicable + $paymentoptions = []; + if ($meta['_usevariableamount'] == 1) { + $paymentoptions = explode(',', $meta['_variableamount']); + $paymentoptions = array_map('sanitize_text_field', $paymentoptions); + } + $showbtn = true; + $planerrorcode = 'Input Correct Recurring Plan Code'; + $recur = $meta['_recur']; + $recurplan = $meta['_recurplan']; + if ($meta['_recur']== 'plan') { + if ($meta['_recurplan'] == '' || $meta['_recurplan'] == '') { + $showbtn = false; + } else { + $plan = kkd_pff_paystack_fetch_plan($meta['_recurplan']); + if (isset($plan->data->amount)) { + $planamount = $plan->data->amount/100; + } else { + $showbtn = false; + } + } + } + // Check if the form should be displayed based on user login status + $show_form = ($user_id != 0 && $meta['_loggedin'] == 'yes') || $meta['_loggedin'] == 'no'; + + if ($show_form) { + // Form title + if ($meta['_hidetitle'] != 1) { + echo "

" . esc_html($obj->post_title) . "

"; + } + + // Start form output + echo '
+
'; + + // Hidden inputs + echo ' + + + '; + + // Full Name input + echo '
+ +
+ +
+
'; + + // Email input + echo '
+ +
+ +
+
'; + + // Amount selection with consideration for variable amounts, minimum payments, and recurring plans + echo '
+ +
'; + + if ($usevariableamount == 0) { + if ($minimum == 1) { + echo ' Minimum payable amount ' . esc_html($currency) . ' ' . esc_html(number_format($amount)) . ''; + } + if ($recur == 'plan') { + if ($showbtn) { + echo ''; + } else { + echo '
+ +
'; + } + } elseif ($recur == 'optional') { + echo ''; + } else { + echo ''; + } + } else { + if ($usevariableamount == "") { + echo "Form Error, set variable amount string"; + } else { + if (count($paymentoptions) > 0) { + echo '
+ + +
'; + } + } + } + + // Transaction charge notice + if ($txncharge != 'merchant' && $recur != 'plan') { + echo 'Transaction Charge: , Total:'; + } + + echo '
'; + + // Quantity selection + if ($recur == 'no' && $usequantity == 'yes' && ($usevariableamount == 1 || $amount != 0)) { + echo '
+ +
+ +
'; + } + + // Recurring payment options + if ($recur == 'optional') { + echo '
+ +
+
'; + } + + // Plan details for recurring payments + if ($recur == 'plan' && $showbtn) { + echo ''; + echo '
+ +
'; + } + echo(do_shortcode($obj->post_content)); + + // Agreement terms + if ($useagreement == 'yes') { + echo '
+ +

'; + } + + + // Form submission controls + echo '
+* are compulsory
+cardlogos +'; + if ($showbtn) { + echo ''; + } + echo '
'; + } else { + echo "
You must be logged in to make a payment.
"; + } + } else { + echo "
Invalid Paystack form ID or the form does not exist.
"; + } + } else { + echo "
No Paystack form ID provided.
"; + } + + return ob_get_clean(); +} +add_shortcode('paystack_form', 'kkd_pff_paystack_form_shortcode'); + +add_shortcode('pff-paystack', 'kkd_pff_paystack_form_shortcode'); + +function kkd_pff_paystack_datepicker_shortcode($atts) +{ + $atts = shortcode_atts( + array( + 'name' => __('Title', 'text-domain'), + 'required' => '0', + ), + $atts, + 'datepicker' + ); + $name = sanitize_text_field($atts['name']); + $required = $atts['required'] === 'required' ? 'required' : ''; + + $id = uniqid('datepicker-'); + + $code = '
+ +
+
'; + + return $code; +} +add_shortcode('datepicker', 'kkd_pff_paystack_datepicker_shortcode'); + + + +function kkd_pff_paystack_text_shortcode($atts) +{ + $atts = shortcode_atts( + array( + 'name' => __('Title', 'text-domain'), + 'required' => '0', + ), + $atts, + 'text' + ); + $name = sanitize_text_field($atts['name']); + $required = $atts['required'] === 'required' ? 'required' : ''; + + $id = uniqid('text-'); + + $code = '
+ +
+
'; + + return $code; +} +add_shortcode('text', 'kkd_pff_paystack_text_shortcode'); + +function kkd_pff_paystack_select_shortcode($atts) +{ + $atts = shortcode_atts( + array( + 'name' => __('Title', 'text-domain'), + 'options' => '', + 'required' => '0', + ), + $atts, + 'select' + ); + + $name = sanitize_text_field($atts['name']); + $options = array_map('sanitize_text_field', explode(',', $atts['options'])); + $required = $atts['required'] === 'required' ? 'required' : ''; + + $id = uniqid('select-'); + + $code = '
+ +
+
'; + + return $code; +} +add_shortcode('select', 'kkd_pff_paystack_select_shortcode'); + +function kkd_pff_paystack_radio_shortcode($atts) +{ + $atts = shortcode_atts( + array( + 'name' => __('Title', 'text-domain'), + 'options' => '', + 'required' => '0', + ), + $atts, + 'radio' + ); + + $name = sanitize_text_field($atts['name']); + $options = array_map('sanitize_text_field', explode(',', $atts['options'])); + $required = $atts['required'] === 'required' ? 'required' : ''; + + $code = '
+ +
'; + + foreach ($options as $index => $option) { + $id = uniqid('radio-'); + $isChecked = $index == 0 ? 'checked' : ''; + $code .= ''; + } + + $code .= '
'; + + return $code; +} +add_shortcode('radio', 'kkd_pff_paystack_radio_shortcode'); + +function kkd_pff_paystack_checkbox_shortcode($atts) +{ + $atts = shortcode_atts( + array( + 'name' => __('Title', 'text-domain'), + 'options' => '', + 'required' => '0', + ), + $atts, + 'checkbox' + ); + + $name = sanitize_text_field($atts['name']); + $options = array_map('sanitize_text_field', explode(',', $atts['options'])); + $required = $atts['required'] === 'required' ? 'required' : ''; + + $code = '
+ +
'; + + foreach ($options as $option) { + $id = uniqid('checkbox-'); + $code .= ''; + } + + $code .= '
'; + + return $code; +} +add_shortcode('checkbox', 'kkd_pff_paystack_checkbox_shortcode'); +function kkd_pff_paystack_textarea_shortcode($atts) +{ + $atts = shortcode_atts( + array( + 'name' => __('Title', 'text-domain'), + 'required' => '0', + ), + $atts, + 'textarea' + ); + + $name = sanitize_text_field($atts['name']); + $required = $atts['required'] === 'required' ? 'required' : ''; + + $id = uniqid('textarea-'); + + $code = '
+ +
+
'; + + return $code; +} +add_shortcode('textarea', 'kkd_pff_paystack_textarea_shortcode'); + +function kkd_pff_paystack_input_shortcode($atts) +{ + $atts = shortcode_atts( + array( + 'name' => __('Title', 'text-domain'), + 'required' => '0', + ), + $atts, + 'input' + ); + + $name = sanitize_text_field($atts['name']); + $required = $atts['required'] === 'required' ? 'required' : ''; + + $fileInputId = uniqid('file-input-'); + $textInputId = uniqid('text-input-'); + + $code = '
+ +
+
+ '.__('Browse', 'text-domain').' + +
+ +
'; + + return $code; +} +add_shortcode('input', 'kkd_pff_paystack_input_shortcode'); + +// Save the Metabox Data +function kkd_pff_paystack_generate_new_code($length = 10) +{ + $characters = '06EFGHI9KL'.time().'MNOPJRSUVW01YZ923234'.time().'ABCD5678QXT'; + $charactersLength = strlen($characters); + $randomString = ''; + for ($i = 0; $i < $length; $i++) { + $randomString .= $characters[rand(0, $charactersLength - 1)]; + } + return time()."_".$randomString; +} +function kkd_pff_paystack_check_code($code) +{ + global $wpdb; + $table = $wpdb->prefix.KKD_PFF_PAYSTACK_TABLE; + $code = sanitize_text_field($code); + $o_exist = $wpdb->get_results($wpdb->prepare("SELECT * FROM {$table} WHERE txn_code = %s", $code)); + + if (count($o_exist) > 0) { + $result = true; + } else { + $result = false; + } + + return $result; +} +function kkd_pff_paystack_generate_code() +{ + $code = 0; + $check = true; + while ($check) { + $code = kkd_pff_paystack_generate_new_code(); + $check = kkd_pff_paystack_check_code($code); + } + + return $code; +} +function kkd_pff_paystack_get_the_user_ip() +{ + if (! empty($_SERVER['HTTP_CLIENT_IP'])) { + $ip = $_SERVER['HTTP_CLIENT_IP']; + } elseif (! empty($_SERVER['HTTP_X_FORWARDED_FOR'])) { + $ip = $_SERVER['HTTP_X_FORWARDED_FOR']; + } else { + $ip = $_SERVER['REMOTE_ADDR']; + } + return $ip; +} + +add_action('wp_ajax_kkd_pff_paystack_submit_action', 'kkd_pff_paystack_submit_action'); +add_action('wp_ajax_nopriv_kkd_pff_paystack_submit_action', 'kkd_pff_paystack_submit_action'); +function kkd_pff_paystack_submit_action() +{ + if (trim($_POST['pf-pemail']) == '') { + $response['result'] = 'failed'; + $response['message'] = 'Email is required'; + + // Exit here, for not processing further because of the error + exit(json_encode($response)); + } + + // Hookable location. Allows other plugins use a fresh submission before it is saved to the database. + // Such a plugin only needs do + // add_action( 'kkd_pff_paystack_before_save', 'function_to_use_posted_values' ); + // somewhere in their code; + do_action('kkd_pff_paystack_before_save'); + + global $wpdb; + $code = kkd_pff_paystack_generate_code(); + + $table = $wpdb->prefix.KKD_PFF_PAYSTACK_TABLE; + $metadata = $_POST; + $fullname = $_POST['pf-fname']; + $recur = $_POST['pf-recur']; + unset($metadata['action']); + unset($metadata['pf-recur']); + unset($metadata['pf-id']); + unset($metadata['pf-pemail']); + unset($metadata['pf-amount']); + unset($metadata['pf-user_id']); + unset($metadata['pf-interval']); + + // echo '
';
+    // print_r($_POST);
+
+    $fixedmetadata = kkd_pff_paystack_meta_as_custom_fields($metadata);
+    // print_r($fixedmetadata );
+    $filelimit = get_post_meta($_POST["pf-id"], '_filelimit', true);
+    $currency = get_post_meta($_POST["pf-id"], '_currency', true);
+    $formamount = get_post_meta($_POST["pf-id"], '_amount', true);/// From form
+    $recur = get_post_meta($_POST["pf-id"], '_recur', true);
+    $subaccount = get_post_meta($_POST["pf-id"], '_subaccount', true);
+    $txnbearer = get_post_meta($_POST["pf-id"], '_txnbearer', true);
+    $transaction_charge = get_post_meta($_POST["pf-id"], '_merchantamount', true);
+    $transaction_charge = $transaction_charge*100;
+        
+    $txncharge = get_post_meta($_POST["pf-id"], '_txncharge', true);
+    $minimum = get_post_meta($_POST["pf-id"], '_minimum', true);
+    $variableamount = get_post_meta($_POST["pf-id"], '_variableamount', true);
+    $usevariableamount = get_post_meta($_POST["pf-id"], '_usevariableamount', true);
+    $amount = (int)str_replace(' ', '', $_POST["pf-amount"]);
+    $variablename = $_POST["pf-vname"];
+    // pf-vname
+    $originalamount = $amount;
+    $quantity = 1;
+    $usequantity = get_post_meta($_POST["pf-id"], '_usequantity', true);
+
+    if (($recur == 'no') && ($formamount != 0)) {
+        $amount = (int)str_replace(' ', '', $formamount);
+    }
+    if ($minimum == 1 && $formamount != 0) {
+        if ($originalamount < $formamount) {
+            $amount = $formamount;
+        } else {
+            $amount = $originalamount;
+        }
+    }
+    if ($usevariableamount == 1) {
+        $paymentoptions = explode(',', $variableamount);
+        if (count($paymentoptions) > 0) {
+            foreach ($paymentoptions as $key => $paymentoption) {
+                list($a, $b) = explode(':', $paymentoption);
+                if ($variablename == $a) {
+                    $amount = $b;
+                }
+            }
+        }
+    }
+    $fixedmetadata[] =  array(
+    'display_name' => 'Unit Price',
+    'variable_name' => 'Unit_Price',
+    'type' => 'text',
+    'value' => $currency.number_format($amount)
+    );
+    if ($usequantity != 'no') {
+        $quantity = $_POST["pf-quantity"];
+        $unitamount = (int)str_replace(' ', '', $amount);
+        $amount = $quantity*$unitamount;
+    }
+        
+    
+    
+    if ($txncharge == 'customer') {
+        $amount = kkd_pff_paystack_add_paystack_charge($amount);
+    }
+    $maxFileSize = $filelimit * 1024 * 1024;
+
+    if (!empty($_FILES)) {
+        foreach ($_FILES as $keyname => $value) {
+            if ($value['size'] > 0) {
+                if ($value['size'] > $maxFileSize) {
+                    $response['result'] = 'failed';
+                    $response['message'] = 'Max upload size is '.$filelimit."MB";
+                    exit(json_encode($response));
+                } else {
+                    $attachment_id = media_handle_upload($keyname, $_POST["pf-id"]);
+                    $url = wp_get_attachment_url($attachment_id);
+                    $fixedmetadata[] =  array(
+                    'display_name' => ucwords(str_replace("_", " ", $keyname)),
+                    'variable_name' => $keyname,
+                    'type' => 'link',
+                    'value' => $url
+                    );
+                }
+            } else {
+                $fixedmetadata[] =  array(
+                'display_name' => ucwords(str_replace("_", " ", $keyname)),
+                'variable_name' => $keyname,
+                'type' => 'text',
+                'value' => 'No file Uploaded'
+                );
+            }
+        }
+    }
+    $plancode = 'none';
+    if ($recur != 'no') {
+        if ($recur == 'optional') {
+            $interval = $_POST['pf-interval'];
+            if ($interval != 'no') {
+                unset($metadata['pf-interval']);
+                $mode =  esc_attr(get_option('mode'));
+                if ($mode == 'test') {
+                    $key = esc_attr(get_option('tsk'));
+                } else {
+                    $key = esc_attr(get_option('lsk'));
+                }
+                $koboamount = $amount*100;
+                //Create Plan
+                $paystack_url = 'https://api.paystack.co/plan';
+                $check_url = 'https://api.paystack.co/plan?amount='.$koboamount.'&interval='.$interval;
+                $headers = array(
+                'Content-Type'    => 'application/json',
+                'Authorization' => 'Bearer ' . $key
+                );
+
+                $checkargs = array(
+                'headers'    => $headers,
+                'timeout'    => 60
+                );
+                // Check if plan exist
+                $checkrequest = wp_remote_get($check_url, $checkargs);
+                if (!is_wp_error($checkrequest)) {
+                    $response = json_decode(wp_remote_retrieve_body($checkrequest));
+                    if ($response->meta->total >= 1) {
+                        $plan = $response->data[0];
+                        $plancode = $plan->plan_code;
+                        $fixedmetadata[] =  array(
+                        'display_name' => 'Plan Interval',
+                        'variable_name' => 'Plan Interval',
+                        'type' => 'text',
+                        'value' => $plan->interval
+                        );
+                    } else {
+                        //Create Plan
+                        $body = array(
+                        'name'                        => $currency.number_format($originalamount).' ['.$currency.number_format($amount).'] - '.$interval,
+                        'amount'                    => $koboamount,
+                        'interval'        => $interval
+                        );
+                        $args = array(
+                        'body'        => json_encode($body),
+                        'headers'    => $headers,
+                        'timeout'    => 60
+                        );
+
+                        $request = wp_remote_post($paystack_url, $args);
+                        if (! is_wp_error($request)) {
+                            $paystack_response = json_decode(wp_remote_retrieve_body($request));
+                            $plancode    = $paystack_response->data->plan_code;
+                            $fixedmetadata[] =  array(
+                            'display_name' => 'Plan Interval',
+                            'variable_name' => 'Plan Interval',
+                            'type' => 'text',
+                            'value' => $paystack_response->data->interval
+                            );
+                        }
+                    }
+                }
+            }
+        } else {
+            //Use Plan Code
+            $plancode = $_POST['pf-plancode'];
+            unset($metadata['pf-plancode']);
+        }
+    }
+
+    if ($plancode != 'none') {
+        $fixedmetadata[] =  array(
+        'display_name' => 'Plan',
+        'variable_name' => 'Plan',
+        'type' => 'text',
+        'value' => $plancode
+        );
+    }
+
+    $insert = array(
+        'post_id' => intval($_POST["pf-id"]),
+        'email' => sanitize_email($_POST["pf-pemail"]),
+        'user_id' => intval($_POST["pf-user_id"]),
+        'amount' => sanitize_text_field($amount),
+        'plan' => sanitize_text_field($plancode),
+        'ip' => kkd_pff_paystack_get_the_user_ip(), // Ensure this function returns a sanitized IP address
+        'txn_code' => sanitize_text_field($code),
+        'metadata' => wp_json_encode($fixedmetadata) // Use wp_json_encode for WordPress environments
+    );
+    
+    $exist = $wpdb->get_results(
+        $wpdb->prepare(
+            "SELECT * FROM $table WHERE post_id = %d AND email = %s AND user_id = %d AND amount = %s AND plan = %s AND ip = %s AND paid = '0' AND metadata = %s",
+            $insert['post_id'], $insert['email'], $insert['user_id'], $insert['amount'], $insert['plan'], $insert['ip'], $insert['metadata']
+        )
+    );
+    if (count($exist) > 0) {
+        // $insert['txn_code'] = $code;
+        // $insert['plan'] = $exist[0]->plan;
+        $wpdb->query(
+            $wpdb->prepare(
+                "UPDATE {$table} SET txn_code = %s, plan = %s WHERE id = %d",
+                $code,
+                $insert['plan'],
+                $exist[0]->id
+            )
+        );
+    } else {
+        $wpdb->insert(
+            $table,
+            $insert
+        );
+        // if("yes" == get_post_meta($insert['post_id'],'_sendinvoice',true)){
+        kkd_pff_paystack_send_invoice($currency, $insert['amount'], $fullname, $insert['email'], $code);
+        // }
+    }
+    if ($subaccount == "" || !isset($subaccount)) {
+        $subaccount = null;
+        $txnbearer = null;
+        $transaction_charge = null;
+    }
+    if ($transaction_charge == "" || $transaction_charge == 0 || $transaction_charge == null) {
+        $transaction_charge = null;
+    }
+
+    $amount = floatval($insert['amount'])*100;
+    $response = array(
+         'result' => 'success',
+         'code' => $insert['txn_code'],
+         'plan' => $insert['plan'],
+         'quantity' => $quantity,
+         'email' => $insert['email'],
+         'name' => $fullname,
+         'total' => round($amount),
+         'custom_fields' => $fixedmetadata,
+         'currency' => $currency,
+    'subaccount' => $subaccount,
+    'txnbearer' => $txnbearer,
+    'transaction_charge' => $transaction_charge
+    );
+    // print_r($response);
+    echo json_encode($response, JSON_NUMERIC_CHECK);
+
+    die();
+}
+
+function kkd_pff_paystack_meta_as_custom_fields($metadata)
+{
+    $custom_fields = array();
+    foreach ($metadata as $key => $value) {
+        if (is_array($value)) {
+            $value = implode(', ', $value);
+        }
+        if ($key == 'pf-fname') {
+            $custom_fields[] =  array(
+            'display_name' => 'Full Name',
+            'variable_name' => 'Full_Name',
+             'type' => 'text',
+             'value' => $value
+            );
+        } elseif ($key == 'pf-plancode') {
+            $custom_fields[] =  array(
+            'display_name' => 'Plan',
+            'variable_name' => 'Plan',
+             'type' => 'text',
+             'value' => $value
+            );
+        } elseif ($key == 'pf-vname') {
+            $custom_fields[] =  array(
+            'display_name' => 'Payment Option',
+            'variable_name' => 'Payment Option',
+             'type' => 'text',
+             'value' => $value
+            );
+        } elseif ($key == 'pf-interval') {
+            $custom_fields[] =  array(
+            'display_name' => 'Plan Interval',
+            'variable_name' => 'Plan Interval',
+             'type' => 'text',
+             'value' => $value
+            );
+        } elseif ($key == 'pf-quantity') {
+            $custom_fields[] =  array(
+            'display_name' => 'Quantity',
+            'variable_name' => 'Quantity',
+             'type' => 'text',
+             'value' => $value
+            );
+        } else {
+            $custom_fields[] =  array(
+            'display_name' => ucwords(str_replace("_", " ", $key)),
+            'variable_name' => $key,
+             'type' => 'text',
+             'value' => $value
+            );
+        }
+    }
+    return $custom_fields;
+}
+
+add_action('wp_ajax_kkd_pff_paystack_confirm_payment', 'kkd_pff_paystack_confirm_payment');
+add_action('wp_ajax_nopriv_kkd_pff_paystack_confirm_payment', 'kkd_pff_paystack_confirm_payment');
+
+function kkd_pff_paystack_confirm_payment()
+{
+    if (trim($_POST['code']) == '') {
+        $response['error'] = true;
+        $response['error_message'] = "Did you make a payment?";
+
+        exit(json_encode($response));
+    }
+    global $wpdb;
+    $table = $wpdb->prefix.KKD_PFF_PAYSTACK_TABLE;
+    $code = sanitize_text_field($_POST['code']);
+    $table = $wpdb->prefix . KKD_PFF_PAYSTACK_TABLE;
+    $record = $wpdb->get_results($wpdb->prepare("SELECT * FROM {$table} WHERE txn_code = %s", $code));
+    if (array_key_exists("0", $record)) {
+        $payment_array = $record[0];
+        $amount = get_post_meta($payment_array->post_id, '_amount', true);
+        $recur = get_post_meta($payment_array->post_id, '_recur', true);
+        $currency = get_post_meta($payment_array->post_id, '_currency', true);
+        $txncharge = get_post_meta($payment_array->post_id, '_txncharge', true);
+        $redirect = get_post_meta($payment_array->post_id, '_redirect', true);
+        $minimum = get_post_meta($payment_array->post_id, '_minimum', true);
+        $usevariableamount = get_post_meta($payment_array->post_id, '_usevariableamount', true);
+        $variableamount = get_post_meta($payment_array->post_id, '_variableamount', true);
+
+        if ($minimum == 1 && $amount != 0) {
+            if ($payment_array->amount < $formamount) {
+                $amount = $formamount;
+            } else {
+                $amount = $payment_array->amount;
+            }
+        }
+        $oamount = $amount;
+        $mode =  esc_attr(get_option('mode'));
+        if ($mode == 'test') {
+            $key = esc_attr(get_option('tsk'));
+        } else {
+            $key = esc_attr(get_option('lsk'));
+        }
+        $paystack_url = 'https://api.paystack.co/transaction/verify/' . $code;
+        $headers = array(
+        'Authorization' => 'Bearer ' . $key
+        );
+        $args = array(
+        'headers'    => $headers,
+        'timeout'    => 60
+        );
+        $request = wp_remote_get($paystack_url, $args);
+        if (! is_wp_error($request) && 200 == wp_remote_retrieve_response_code($request)) {
+            $paystack_response = json_decode(wp_remote_retrieve_body($request));
+            if ('success' == $paystack_response->data->status) {
+                $customer_code  = $paystack_response->data->customer->customer_code;
+                $amount_paid    = $paystack_response->data->amount / 100;
+                $paystack_ref     = $paystack_response->data->reference;
+                $paid_at        = $paystack_response->data->transaction_date;
+                if ($recur == 'optional' || $recur == 'plan') {
+                    $wpdb->update($table, array( 'paid' => 1,'amount' => $amount_paid, 'paid_at' => $paid_at), array('txn_code'=>$paystack_ref));
+                    $thankyou = get_post_meta($payment_array->post_id, '_successmsg', true);
+                    $message = $thankyou;
+                    $result = "success";
+                } else {
+                    if ($amount == 0 || $usevariableamount == 1) {
+                        $wpdb->update($table, array( 'paid' => 1,'amount' => $amount_paid, 'paid_at' => $paid_at), array('txn_code'=>$paystack_ref));
+                        $thankyou = get_post_meta($payment_array->post_id, '_successmsg', true);
+                        $message = $thankyou;
+                        $result = "success";
+                        // kkd_pff_paystack_send_receipt($currency,$amount,$name,$payment_array->email,$code,$metadata)
+                    } else {
+                        if ($txncharge == 'customer') {
+                            if ($minimum == 0 && $amount != 0) {
+                                $oamount = kkd_pff_paystack_add_paystack_charge($oamount);
+                            }
+                        }
+                        if ($oamount !=  $amount_paid) {
+                            $message = "Invalid amount Paid. Amount required is ".$currency."".number_format($oamount)."";
+                            $result = "failed";
+                        } else {
+                            $wpdb->update($table, array( 'paid' => 1, 'paid_at' => $paid_at), array('txn_code'=>$paystack_ref));
+                            $thankyou = get_post_meta($payment_array->post_id, '_successmsg', true);
+                            $message = $thankyou;
+                            $result = "success";
+                        }
+                    }
+                }
+            } else {
+                $message = "Transaction Failed/Invalid Code";
+                $result = "failed";
+            }
+        } else {
+            $message = "Payment Verifiction Failed";
+            $result = "failed";
+        }
+    } else {
+        $message = "Payment Verification Failed.";
+        $result = "failed";
+    }
+
+    if ($result == 'success') {
+        ///
+        //Create Plan
+        $enabled_custom_plan = get_post_meta($payment_array->post_id, '_startdate_enabled', true);
+        if ($enabled_custom_plan == 1) {
+            $mode =  esc_attr(get_option('mode'));
+            if ($mode == 'test') {
+                $key = esc_attr(get_option('tsk'));
+            } else {
+                $key = esc_attr(get_option('lsk'));
+            }
+            //Create Plan
+            $paystack_url = 'https://api.paystack.co/subscription';
+            $headers = array(
+            'Content-Type'    => 'application/json',
+            'Authorization' => 'Bearer ' . $key
+            );
+            $custom_plan = get_post_meta($payment_array->post_id, '_startdate_plan_code', true);
+            $days = get_post_meta($payment_array->post_id, '_startdate_days', true);
+
+            $start_date = date("c", strtotime("+".$days." days"));
+            $body = array(
+            'start_date'    => $start_date,
+            'plan'            => $custom_plan,
+            'customer'        => $customer_code
+            );
+            $args = array(
+            'body'        => json_encode($body),
+            'headers'    => $headers,
+            'timeout'    => 60
+            );
+
+            $request = wp_remote_post($paystack_url, $args);
+            if (! is_wp_error($request)) {
+                $paystack_response = json_decode(wp_remote_retrieve_body($request));
+                $plancode    = $paystack_response->data->subscription_code;
+                // $message.= $message.'Subscribed
'.$plancode.'sssss'; + } + } + + $sendreceipt = get_post_meta($payment_array->post_id, '_sendreceipt', true); + if ($sendreceipt == 'yes') { + $decoded = json_decode($payment_array->metadata); + $fullname = $decoded[0]->value; + kkd_pff_paystack_send_receipt($payment_array->post_id, $currency, $amount_paid, $fullname, $payment_array->email, $paystack_ref, $payment_array->metadata); + kkd_pff_paystack_send_receipt_owner($payment_array->post_id, $currency, $amount_paid, $fullname, $payment_array->email, $paystack_ref, $payment_array->metadata); + } + } + $response = array( + 'result' => $result, + 'message' => $message, + ); + if ($result == 'success' && $redirect != '') { + $response['result'] = 'success2'; + $response['link'] = $redirect; + } + + + echo json_encode($response); + + die(); +} + + +add_action('wp_ajax_kkd_pff_paystack_retry_action', 'kkd_pff_paystack_retry_action'); +add_action('wp_ajax_nopriv_kkd_pff_paystack_retry_action', 'kkd_pff_paystack_retry_action'); +function kkd_pff_paystack_retry_action() +{ + if (trim($_POST['code']) == '') { + $response['result'] = 'failed'; + $response['message'] = 'Cde is required'; + + // Exit here, for not processing further because of the error + exit(json_encode($response)); + } + do_action('kkd_pff_paystack_before_save'); + + global $wpdb; + $newcode = kkd_pff_paystack_generate_code(); + $newcode = $newcode.'_2'; + $insert = array(); + + $code = sanitize_text_field($_POST['code']); + $table = $wpdb->prefix . KKD_PFF_PAYSTACK_TABLE; + $record = $wpdb->get_results($wpdb->prepare("SELECT * FROM {$table} WHERE txn_code = %s", $code)); + if (array_key_exists("0", $record)) { + $dbdata = $record[0]; + $plan = $dbdata->plan; + $quantity = 1; + $wpdb->update($table, array( 'txn_code_2' => $newcode), array('txn_code' => $code)); + + $currency = get_post_meta($dbdata->post_id, '_currency', true); + $subaccount = get_post_meta($dbdata->post_id, '_subaccount', true); + $txnbearer = get_post_meta($dbdata->post_id, '_txnbearer', true); + $transaction_charge = get_post_meta($dbdata->post_id, '_merchantamount', true); + $transaction_charge = $transaction_charge*100; + $fixedmetadata = kkd_pff_paystack_meta_as_custom_fields($dbdata->metadata); + $nmeta = json_decode($dbdata->metadata); + foreach ($nmeta as $nkey => $nvalue) { + if ($nvalue->variable_name == 'Quantity') { + $quantity = $nvalue->value; + } + if ($nvalue->variable_name == 'Full_Name') { + $fullname = $nvalue->value; + } + } + } + if ($subaccount == "" || !isset($subaccount)) { + $subaccount = null; + $txnbearer = null; + $transaction_charge = null; + } + if ($transaction_charge == "" || $transaction_charge == 0 || $transaction_charge == null || !isset($transaction_charge)) { + $transaction_charge = null; + } + $response = array( + 'result' => 'success', + 'code' => $newcode, + 'plan' => $plan, + 'quantity' => $quantity, + 'email' => $dbdata->email, + 'name' => $fullname, + 'total' => $dbdata->amount*100, + 'custom_fields' => $fixedmetadata, + 'subaccount' => $subaccount, + 'txnbearer' => $txnbearer, + 'transaction_charge' => $transaction_charge + ); + echo json_encode($response); + + die(); +} +add_action('wp_ajax_kkd_pff_paystack_rconfirm_payment', 'kkd_pff_paystack_rconfirm_payment'); +add_action('wp_ajax_nopriv_kkd_pff_paystack_rconfirm_payment', 'kkd_pff_paystack_rconfirm_payment'); + +function kkd_pff_paystack_rconfirm_payment() +{ + if (trim($_POST['code']) == '') { + $response['error'] = true; + $response['error_message'] = "Did you make a payment?"; + + exit(json_encode($response)); + } + global $wpdb; + $table = $wpdb->prefix.KKD_PFF_PAYSTACK_TABLE; + $code = sanitize_text_field($_POST['code']); + $record = $wpdb->get_results($wpdb->prepare("SELECT * FROM {$table} WHERE txn_code_2 = %s", $code)); + + if (array_key_exists("0", $record)) { + $payment_array = $record[0]; + $amount = get_post_meta($payment_array->post_id, '_amount', true); + $recur = get_post_meta($payment_array->post_id, '_recur', true); + $currency = get_post_meta($payment_array->post_id, '_currency', true); + $txncharge = get_post_meta($payment_array->post_id, '_txncharge', true); + $redirect = get_post_meta($payment_array->post_id, '_redirect', true); + + + $mode = esc_attr(get_option('mode')); + if ($mode == 'test') { + $key = esc_attr(get_option('tsk')); + } else { + $key = esc_attr(get_option('lsk')); + } + $paystack_url = 'https://api.paystack.co/transaction/verify/' . $code; + $headers = array( + 'Authorization' => 'Bearer ' . $key + ); + $args = array( + 'headers' => $headers, + 'timeout' => 60 + ); + $request = wp_remote_get($paystack_url, $args); + if (! is_wp_error($request) && 200 == wp_remote_retrieve_response_code($request)) { + $paystack_response = json_decode(wp_remote_retrieve_body($request)); + if ('success' == $paystack_response->data->status) { + $amount_paid = $paystack_response->data->amount / 100; + $paystack_ref = $paystack_response->data->reference; + $paid_at = $paystack_response->data->transaction_date; + if ($recur == 'optional' || $recur == 'plan') { + $wpdb->update($table, array( 'paid' => 1,'amount' =>$amount_paid,'paid_at' => $paid_at), array('txn_code_2'=>$paystack_ref)); + $thankyou = get_post_meta($payment_array->post_id, '_successmsg', true); + $message = $thankyou; + $result = "success"; + } else { + if ($amount == 0) { + $wpdb->update($table, array( 'paid' => 1,'amount' =>$amount_paid,'paid_at' => $paid_at), array('txn_code_2'=>$paystack_ref)); + $thankyou = get_post_meta($payment_array->post_id, '_successmsg', true); + $message = $thankyou; + $result = "success"; + // kkd_pff_paystack_send_receipt($currency,$amount,$name,$payment_array->email,$code,$metadata) + } else { + $usequantity = get_post_meta($payment_array->post_id, '_usequantity', true); + if ($usequantity == 'no') { + $amount = (int)str_replace(' ', '', $amount); + } else { + $quantity = $_POST["quantity"]; + $unitamount = (int)str_replace(' ', '', $amount); + $amount = $quantity*$unitamount; + } + + + if ($txncharge == 'customer') { + $amount = kkd_pff_paystack_add_paystack_charge($amount); + } + if ($amount != $amount_paid) { + $message = "Invalid amount Paid. Amount required is ".$currency."".number_format($amount).""; + $result = "failed"; + } else { + $wpdb->update($table, array( 'paid' => 1, 'paid_at' => $paid_at), array('txn_code_2'=>$paystack_ref)); + $thankyou = get_post_meta($payment_array->post_id, '_successmsg', true); + $message = $thankyou; + $result = "success"; + } + } + } + } else { + $message = "Transaction Failed/Invalid Code"; + $result = "failed"; + } + } + } else { + $message = "Payment Verification Failed."; + $result = "failed"; + } + + if ($result == 'success') { + $sendreceipt = get_post_meta($payment_array->post_id, '_sendreceipt', true); + if ($sendreceipt == 'yes') { + $decoded = json_decode($payment_array->metadata); + $fullname = $decoded[0]->value; + kkd_pff_paystack_send_receipt($payment_array->post_id, $currency, $amount_paid, $fullname, $payment_array->email, $paystack_ref, $payment_array->metadata); + kkd_pff_paystack_send_receipt_owner($payment_array->post_id, $currency, $amount_paid, $fullname, $payment_array->email, $paystack_ref, $payment_array->metadata); + } + } + $response = array( + 'result' => $result, + 'message' => $message, + ); + if ($result == 'success' && $redirect != '') { + $response['result'] = 'success2'; + $response['link'] = $redirect; + } + + + echo json_encode($response); + + die(); +} diff --git a/public/class-paystack-forms-public.php b/public/class-paystack-forms-public.php new file mode 100644 index 0000000..0cbc42d --- /dev/null +++ b/public/class-paystack-forms-public.php @@ -0,0 +1,3141 @@ +plugin_name = $plugin_name; + $this->version = $version; + } + public function enqueue_styles() + { + wp_enqueue_style($this->plugin_name . '1', plugin_dir_url(__FILE__) . 'css/pff-paystack-style.css', array(), $this->version, 'all'); + wp_enqueue_style($this->plugin_name . '2', plugin_dir_url(__FILE__) . 'css/font-awesome.min.css', array(), $this->version, 'all'); + } + + public static function fetchPublicKey() + { + $mode = esc_attr(get_option('mode')); + if ($mode == 'test') { + $key = esc_attr(get_option('tpk')); + } else { + $key = esc_attr(get_option('lpk')); + } + return $key; + } + + public static function fetchFeeSettings() + { + $ret = []; + $ret['prc'] = intval(floatval(esc_attr(get_option('prc', 1.5))) * 100) / 10000; + $ret['ths'] = intval(floatval(esc_attr(get_option('ths', 2500))) * 100); + $ret['adc'] = intval(floatval(esc_attr(get_option('adc', 100))) * 100); + $ret['cap'] = intval(floatval(esc_attr(get_option('cap', 2000))) * 100); + return $ret; + } + + public function enqueue_scripts() + { + global $posts; + $pattern = get_shortcode_regex(); + preg_match('/'.$pattern.'/s', $posts[0]->post_content, $matches); + + wp_enqueue_script('blockUI', plugin_dir_url(__FILE__) . 'js/jquery.blockUI.min.js', array('jquery'), $this->version, true, true); + wp_enqueue_script('jquery-ui-core'); + + if(is_array($matches)) { + if(count($matches) > 0) { + if($matches[2] == 'pff-paystack') { + wp_register_script('Paystack', 'https://js.paystack.co/v1/inline.js', false, '1'); + wp_enqueue_script('Paystack'); + wp_enqueue_script('paystack_frontend', plugin_dir_url(__FILE__) . 'js/paystack-forms-public.js', array('jquery'), $this->version, true, true); + wp_localize_script('paystack_frontend', 'kkd_pff_settings', array('key' => Kkd_Pff_Paystack_Public::fetchPublicKey(), 'fee' => Kkd_Pff_Paystack_Public::fetchFeeSettings()), $this->version, true, true); + } + } + } + + + // wp_enqueue_script('blockUI', plugin_dir_url(__FILE__) . 'js/jquery.blockUI.min.js', array('jquery'), $this->version, true, true); + // wp_enqueue_script('jquery-ui-core'); + // wp_register_script('Paystack', 'https://js.paystack.co/v1/inline.js', false, '1'); + // wp_enqueue_script('Paystack'); + // wp_enqueue_script('paystack_frontend', plugin_dir_url(__FILE__) . 'js/paystack-forms-public.js', array('jquery'), $this->version, true, true); + // wp_localize_script('paystack_frontend', 'kkd_pff_settings', array('key' => Kkd_Pff_Paystack_Public::fetchPublicKey(), 'fee' => Kkd_Pff_Paystack_Public::fetchFeeSettings()), $this->version, true, true); + } +} + +define('KKD_PFF_PAYSTACK_PERCENTAGE', 0.015); +define('KKD_PFF_PAYSTACK_CROSSOVER_TOTAL', 250000); +define('KKD_PFF_PAYSTACK_ADDITIONAL_CHARGE', 10000); +define('KKD_PFF_PAYSTACK_LOCAL_CAP', 200000); + +define('KKD_PFF_PAYSTACK_CHARGE_DIVIDER', floatval(1 - KKD_PFF_PAYSTACK_PERCENTAGE)); +define('KKD_PFF_PAYSTACK_CROSSOVER_AMOUNT', intval((KKD_PFF_PAYSTACK_CROSSOVER_TOTAL * KKD_PFF_PAYSTACK_CHARGE_DIVIDER) - KKD_PFF_PAYSTACK_ADDITIONAL_CHARGE)); +define('KKD_PFF_PAYSTACK_FLATLINE_AMOUNT_PLUS_CHARGE', intval((KKD_PFF_PAYSTACK_LOCAL_CAP - KKD_PFF_PAYSTACK_ADDITIONAL_CHARGE) / KKD_PFF_PAYSTACK_PERCENTAGE)); +define('KKD_PFF_PAYSTACK_FLATLINE_AMOUNT', KKD_PFF_PAYSTACK_FLATLINE_AMOUNT_PLUS_CHARGE - KKD_PFF_PAYSTACK_LOCAL_CAP); + +class Kkd_Pff_Paystack_PaystackCharge +{ + public $percentage; + public $additional_charge; + public $crossover_total; + public $cap; + + public $charge_divider; + public $crossover; + public $flatline_plus_charge; + public $flatline; + + public function __construct($percentage = 0.015, $additional_charge = 10000, $crossover_total = 250000, $cap = 200000) + { + $this->percentage = $percentage; + $this->additional_charge = $additional_charge; + $this->crossover_total = $crossover_total; + $this->cap = $cap; + $this->__setup(); + } + + private function __setup() + { + $this->charge_divider = $this->__charge_divider(); + $this->crossover = $this->__crossover(); + $this->flatline_plus_charge = $this->__flatline_plus_charge(); + $this->flatline = $this->__flatline(); + } + + private function __charge_divider() + { + return floatval(1 - $this->percentage); + } + + private function __crossover() + { + return ceil(($this->crossover_total * $this->charge_divider) - $this->additional_charge); + } + + private function __flatline_plus_charge() + { + return floor(($this->cap - $this->additional_charge) / $this->percentage); + } + + private function __flatline() + { + return $this->flatline_plus_charge - $this->cap; + } + + public function add_for_kobo($amountinkobo) + { + if ($amountinkobo > $this->flatline) { + return $amountinkobo + $this->cap; + } elseif ($amountinkobo > $this->crossover) { + return ceil(($amountinkobo + $this->additional_charge) / $this->charge_divider); + } else { + return ceil($amountinkobo / $this->charge_divider); + } + } + + public function add_for_ngn($amountinngn) + { + return $this->add_for_kobo(ceil($amountinngn * 100)) / 100; + } +} + +function kkd_pff_paystack_add_paystack_charge($amount) +{ + $feeSettings = Kkd_Pff_Paystack_Public::fetchFeeSettings(); + $pc = new Kkd_Pff_Paystack_PaystackCharge( + $feeSettings['prc'], + $feeSettings['adc'], + $feeSettings['ths'], + $feeSettings['cap'] + ); + return $pc->add_for_ngn($amount); +} + +add_filter("wp_mail_content_type", "kkd_pff_paystack_mail_content_type"); +function kkd_pff_paystack_mail_content_type() +{ + return "text/html"; +} +add_filter("wp_mail_from_name", "kkd_pff_paystack_mail_from_name"); +function kkd_pff_paystack_mail_from_name() +{ + $name = get_option('blogname'); + return $name; +} + + +function kkd_pff_paystack_send_invoice($currency, $amount, $name, $email, $code) +{ + // echo date('F j,Y'); + $user_email = stripslashes($email); + + $email_subject = "Payment Invoice for " . $currency . ' ' . number_format($amount); + + ob_start(); ?> + + + + + + + + + + + + + + + + + + + + + + " . "\r\n"); + $headers = "From: " . $website . "<$admin_email>" . "\r\n"; + wp_mail($user_email, $email_subject, $message, $headers); +} +function kkd_pff_paystack_send_receipt($id, $currency, $amount, $name, $email, $code, $metadata) +{ + // echo date('F j,Y'); + // error_log(print_r("Sending reciept", TRUE)); + $user_email = stripslashes($email); + $subject = get_post_meta($id, '_subject', true); + $merchant = get_post_meta($id, '_merchant', true); + $heading = get_post_meta($id, '_heading', true); + $sitemessage = get_post_meta($id, '_message', true); + + $email_subject = $subject; + + ob_start(); ?> + + + + + + + + + + + + + + + + + + + + + + + " . "\r\n"); + $headers = "From: " . $website . "<$admin_email>" . "\r\n"; + wp_mail($user_email, $email_subject, $message, $headers); +} +function kkd_pff_paystack_send_receipt_owner($id, $currency, $amount, $name, $email, $code, $metadata) +{ + // echo date('F j,Y'); + $user_email = stripslashes($email); + $subject = "You just received a payment"; + $heading = get_post_meta($id, '_heading', true); + $sitemessage = get_post_meta($id, '_message', true); + + $email_subject = $subject; + + ob_start(); ?> + + + + + + + + + + + + + + + + + + + + + + + " . "\r\n"); + $headers = "From: " . $website . "<$admin_email>" . "\r\n"; + wp_mail($admin_email, $email_subject, $message, $headers); +} +function kkd_pff_paystack_fetch_plan($code) +{ + $mode = esc_attr(get_option('mode')); + if ($mode == 'test') { + $key = esc_attr(get_option('tsk')); + } else { + $key = esc_attr(get_option('lsk')); + } + $paystack_url = 'https://api.paystack.co/plan/' . $code; + $headers = array( + 'Authorization' => 'Bearer ' . $key + ); + $args = array( + 'headers' => $headers, + 'timeout' => 60 + ); + $request = wp_remote_get($paystack_url, $args); + if (!is_wp_error($request)) { + $paystack_response = json_decode(wp_remote_retrieve_body($request)); + } + return $paystack_response; +} +function kkd_pff_paystack_form_shortcode($atts) +{ + ob_start(); + + // Ensure the current user is populated + global $current_user; + wp_get_current_user(); + $user_id = $current_user->ID; + $email = sanitize_email($current_user->user_email); + $fname = sanitize_text_field($current_user->user_firstname); + $lname = sanitize_text_field($current_user->user_lastname); + $fullname = $fname || $lname ? trim($fname . ' ' . $lname) : ''; + + // Use array access for shortcode attributes + $atts = shortcode_atts(array('id' => 0), $atts, 'paystack_form'); + $id = intval($atts['id']); // Ensure $id is an integer + + $pk = Kkd_Pff_Paystack_Public::fetchPublicKey(); + if (!$pk) { + $settingslink = esc_url(get_admin_url(null, 'edit.php?post_type=paystack_form&page=class-paystack-forms-admin.php')); + echo "
You must set your Paystack API keys first settings
"; + return ob_get_clean(); // Return early to avoid further processing + } + + if ($id > 0) { + $obj = get_post($id); + if ($obj && $obj->post_type === 'paystack_form') { + // Fetch and sanitize meta values + $meta_keys = [ + '_amount', '_successmsg', '_paybtn', '_loggedin', '_txncharge', + '_currency', '_recur', '_recurplan', '_usequantity', '_quantity', + '_useagreement', '_agreementlink', '_minimum', '_variableamount', + '_usevariableamount', '_hidetitle' + ]; + $meta = []; + foreach ($meta_keys as $key) { + $meta[$key] = sanitize_text_field(get_post_meta($id, $key, true)); + } + + // Ensure minimum defaults are set + $meta['_minimum'] = $meta['_minimum'] === "" ? 0 : $meta['_minimum']; + $meta['_usevariableamount'] = $meta['_usevariableamount'] === "" ? 0 : $meta['_usevariableamount']; + $meta['_usequantity'] = $meta['_usequantity'] === "" ? 'no' : $meta['_usequantity']; + $minimum = floatval($meta['_minimum']); + $currency = $meta['_currency'] === "" ? 'NGN' : $meta['_currency']; + $txncharge = floatval($meta['_txncharge']); + // Process variable amount options if applicable + $paymentoptions = []; + if ($meta['_usevariableamount'] == 1) { + $paymentoptions = explode(',', $meta['_variableamount']); + $paymentoptions = array_map('sanitize_text_field', $paymentoptions); + } + $showbtn = true; + $planerrorcode = 'Input Correct Recurring Plan Code'; + $recur = $meta['_recur']; + $recurplan = $meta['_recurplan']; + if ($meta['_recur']== 'plan') { + if ($meta['_recurplan'] == '' || $meta['_recurplan'] == '') { + $showbtn = false; + } else { + $plan = kkd_pff_paystack_fetch_plan($meta['_recurplan']); + if (isset($plan->data->amount)) { + $planamount = $plan->data->amount/100; + } else { + $showbtn = false; + } + } + } + // Check if the form should be displayed based on user login status + $show_form = ($user_id != 0 && $meta['_loggedin'] == 'yes') || $meta['_loggedin'] == 'no'; + + if ($show_form) { + // Form title + if ($meta['_hidetitle'] != 1) { + echo "

" . esc_html($obj->post_title) . "

"; + } + + // Start form output + echo '
+
'; + + // Hidden inputs + echo ' + + + '; + + // Full Name input + echo '
+ +
+ +
+
'; + + // Email input + echo '
+ +
+ +
+
'; + + // Amount selection with consideration for variable amounts, minimum payments, and recurring plans + echo '
+ +
'; + + if ($usevariableamount == 0) { + if ($minimum == 1) { + echo ' Minimum payable amount ' . esc_html($currency) . ' ' . esc_html(number_format($amount)) . ''; + } + if ($recur == 'plan') { + if ($showbtn) { + echo ''; + } else { + echo '
+ +
'; + } + } elseif ($recur == 'optional') { + echo ''; + } else { + echo ''; + } + } else { + if ($usevariableamount == "") { + echo "Form Error, set variable amount string"; + } else { + if (count($paymentoptions) > 0) { + echo '
+ + +
'; + } + } + } + + // Transaction charge notice + if ($txncharge != 'merchant' && $recur != 'plan') { + echo 'Transaction Charge: , Total:'; + } + + echo '
'; + + // Quantity selection + if ($recur == 'no' && $usequantity == 'yes' && ($usevariableamount == 1 || $amount != 0)) { + echo '
+ +
+ +
'; + } + + // Recurring payment options + if ($recur == 'optional') { + echo '
+ +
+
'; + } + + // Plan details for recurring payments + if ($recur == 'plan' && $showbtn) { + echo ''; + echo '
+ +
'; + } + echo(do_shortcode($obj->post_content)); + + // Agreement terms + if ($useagreement == 'yes') { + echo '
+ +

'; + } + + + // Form submission controls + echo '
+ * are compulsory
+ cardlogos + '; + if ($showbtn) { + echo ''; + } + echo '
'; + } else { + echo "
You must be logged in to make a payment.
"; + } + } else { + echo "
Invalid Paystack form ID or the form does not exist.
"; + } + } else { + echo "
No Paystack form ID provided.
"; + } + + return ob_get_clean(); +} +add_shortcode('paystack_form', 'kkd_pff_paystack_form_shortcode'); + +add_shortcode('pff-paystack', 'kkd_pff_paystack_form_shortcode'); + +function kkd_pff_paystack_datepicker_shortcode($atts) +{ + $atts = shortcode_atts( + array( + 'name' => __('Title', 'text-domain'), + 'required' => '0', + ), + $atts, + 'datepicker' + ); + $name = sanitize_text_field($atts['name']); + $required = $atts['required'] === 'required' ? 'required' : ''; + + $id = uniqid('datepicker-'); + + $code = '
+ +
+
'; + + return $code; +} +add_shortcode('datepicker', 'kkd_pff_paystack_datepicker_shortcode'); + + + +function kkd_pff_paystack_text_shortcode($atts) +{ + $atts = shortcode_atts( + array( + 'name' => __('Title', 'text-domain'), + 'required' => '0', + ), + $atts, + 'text' + ); + $name = sanitize_text_field($atts['name']); + $required = $atts['required'] === 'required' ? 'required' : ''; + + $id = uniqid('text-'); + + $code = '
+ +
+
'; + + return $code; +} +add_shortcode('text', 'kkd_pff_paystack_text_shortcode'); + +function kkd_pff_paystack_select_shortcode($atts) +{ + $atts = shortcode_atts( + array( + 'name' => __('Title', 'text-domain'), + 'options' => '', + 'required' => '0', + ), + $atts, + 'select' + ); + + $name = sanitize_text_field($atts['name']); + $options = array_map('sanitize_text_field', explode(',', $atts['options'])); + $required = $atts['required'] === 'required' ? 'required' : ''; + + $id = uniqid('select-'); + + $code = '
+ +
+
'; + + return $code; +} +add_shortcode('select', 'kkd_pff_paystack_select_shortcode'); + +function kkd_pff_paystack_radio_shortcode($atts) +{ + $atts = shortcode_atts( + array( + 'name' => __('Title', 'text-domain'), + 'options' => '', + 'required' => '0', + ), + $atts, + 'radio' + ); + + $name = sanitize_text_field($atts['name']); + $options = array_map('sanitize_text_field', explode(',', $atts['options'])); + $required = $atts['required'] === 'required' ? 'required' : ''; + + $code = '
+ +
'; + + foreach ($options as $index => $option) { + $id = uniqid('radio-'); + $isChecked = $index == 0 ? 'checked' : ''; + $code .= ''; + } + + $code .= '
'; + + return $code; +} +add_shortcode('radio', 'kkd_pff_paystack_radio_shortcode'); + +function kkd_pff_paystack_checkbox_shortcode($atts) +{ + $atts = shortcode_atts( + array( + 'name' => __('Title', 'text-domain'), + 'options' => '', + 'required' => '0', + ), + $atts, + 'checkbox' + ); + + $name = sanitize_text_field($atts['name']); + $options = array_map('sanitize_text_field', explode(',', $atts['options'])); + $required = $atts['required'] === 'required' ? 'required' : ''; + + $code = '
+ +
'; + + foreach ($options as $option) { + $id = uniqid('checkbox-'); + $code .= ''; + } + + $code .= '
'; + + return $code; +} +add_shortcode('checkbox', 'kkd_pff_paystack_checkbox_shortcode'); +function kkd_pff_paystack_textarea_shortcode($atts) +{ + $atts = shortcode_atts( + array( + 'name' => __('Title', 'text-domain'), + 'required' => '0', + ), + $atts, + 'textarea' + ); + + $name = sanitize_text_field($atts['name']); + $required = $atts['required'] === 'required' ? 'required' : ''; + + $id = uniqid('textarea-'); + + $code = '
+ +
+
'; + + return $code; +} +add_shortcode('textarea', 'kkd_pff_paystack_textarea_shortcode'); + +function kkd_pff_paystack_input_shortcode($atts) +{ + $atts = shortcode_atts( + array( + 'name' => __('Title', 'text-domain'), + 'required' => '0', + ), + $atts, + 'input' + ); + + $name = sanitize_text_field($atts['name']); + $required = $atts['required'] === 'required' ? 'required' : ''; + + $fileInputId = uniqid('file-input-'); + $textInputId = uniqid('text-input-'); + + $code = '
+ +
+
+ '.__('Browse', 'text-domain').' + +
+ +
'; + + return $code; +} +add_shortcode('input', 'kkd_pff_paystack_input_shortcode'); + +// Save the Metabox Data +function kkd_pff_paystack_generate_new_code($length = 10) +{ + $characters = '06EFGHI9KL' . time() . 'MNOPJRSUVW01YZ923234' . time() . 'ABCD5678QXT'; + $charactersLength = strlen($characters); + $randomString = ''; + for ($i = 0; $i < $length; $i++) { + $randomString .= $characters[rand(0, $charactersLength - 1)]; + } + return time() . "_" . $randomString; +} +function kkd_pff_paystack_check_code($code) +{ + global $wpdb; + $table = $wpdb->prefix . KKD_PFF_PAYSTACK_TABLE; + + $o_exist = $wpdb->get_results($wpdb->prepare("SELECT * FROM {$table} WHERE txn_code = %s", $code)); + + if (count($o_exist) > 0) { + $result = true; + } else { + $result = false; + } + + return $result; +} +function kkd_pff_paystack_generate_code() +{ + $code = 0; + $check = true; + while ($check) { + $code = kkd_pff_paystack_generate_new_code(); + $check = kkd_pff_paystack_check_code($code); + } + + return $code; +} +function kkd_pff_paystack_get_the_user_ip() +{ + if (!empty($_SERVER['HTTP_CLIENT_IP'])) { + $ip = $_SERVER['HTTP_CLIENT_IP']; + } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) { + $ip = $_SERVER['HTTP_X_FORWARDED_FOR']; + } else { + $ip = $_SERVER['REMOTE_ADDR']; + } + return $ip; +} + +add_action('wp_ajax_kkd_pff_paystack_submit_action', 'kkd_pff_paystack_submit_action'); +add_action('wp_ajax_nopriv_kkd_pff_paystack_submit_action', 'kkd_pff_paystack_submit_action'); +function kkd_pff_paystack_submit_action() +{ + if (trim($_POST['pf-pemail']) == '') { + $response['result'] = 'failed'; + $response['message'] = 'Email is required'; + + // Exit here, for not processing further because of the error + exit(json_encode($response)); + } + + // Hookable location. Allows other plugins use a fresh submission before it is saved to the database. + // Such a plugin only needs do + // add_action( 'kkd_pff_paystack_before_save', 'function_to_use_posted_values' ); + // somewhere in their code; + do_action('kkd_pff_paystack_before_save'); + + global $wpdb; + $code = kkd_pff_paystack_generate_code(); + + $table = $wpdb->prefix . KKD_PFF_PAYSTACK_TABLE; + $metadata = $_POST; + $fullname = $_POST['pf-fname']; + $recur = $_POST['pf-recur']; + unset($metadata['action']); + unset($metadata['pf-recur']); + unset($metadata['pf-id']); + unset($metadata['pf-pemail']); + unset($metadata['pf-amount']); + unset($metadata['pf-user_id']); + unset($metadata['pf-interval']); + + // echo '
';
+    // print_r($_POST);
+
+    $untouchedmetadata = kkd_pff_paystack_meta_as_custom_fields($metadata);
+    $fixedmetadata = [];
+    // print_r($fixedmetadata );
+    $filelimit = get_post_meta($_POST["pf-id"], '_filelimit', true);
+    $currency = get_post_meta($_POST["pf-id"], '_currency', true);
+    $formamount = get_post_meta($_POST["pf-id"], '_amount', true); /// From form
+    $recur = get_post_meta($_POST["pf-id"], '_recur', true);
+    $subaccount = get_post_meta($_POST["pf-id"], '_subaccount', true);
+    $txnbearer = get_post_meta($_POST["pf-id"], '_txnbearer', true);
+    $transaction_charge = get_post_meta($_POST["pf-id"], '_merchantamount', true);
+    $transaction_charge = intval(floatval($transaction_charge) * 100);
+
+    $txncharge = get_post_meta($_POST["pf-id"], '_txncharge', true);
+    $minimum = get_post_meta($_POST["pf-id"], '_minimum', true);
+    $variableamount = get_post_meta($_POST["pf-id"], '_variableamount', true);
+    $usevariableamount = get_post_meta($_POST["pf-id"], '_usevariableamount', true);
+    $amount = (int) str_replace(' ', '', $_POST["pf-amount"]);
+    $variablename = $_POST["pf-vname"];
+    $originalamount = $amount;
+    $quantity = 1;
+    $usequantity = get_post_meta($_POST["pf-id"], '_usequantity', true);
+
+    if (($recur == 'no') && (floatval($formamount) != 0)) {
+        $amount = (int) str_replace(' ', '', floatval($formamount));
+    }
+    if ($minimum == 1 && floatval($formamount) != 0) {
+        if ($originalamount < floatval($formamount)) {
+            $amount = floatval($formamount);
+        } else {
+            $amount = $originalamount;
+        }
+    }
+    if ($usevariableamount == 1) {
+        $paymentoptions = explode(',', $variableamount);
+        if (count($paymentoptions) > 0) {
+            foreach ($paymentoptions as $key => $paymentoption) {
+                list($a, $b) = explode(':', $paymentoption);
+                if ($variablename == $a) {
+                    $amount = $b;
+                }
+            }
+        }
+    }
+    $fixedmetadata[] =  array(
+        'display_name' => 'Unit Price',
+        'variable_name' => 'Unit_Price',
+        'type' => 'text',
+        'value' => $currency . number_format($amount)
+    );
+    if ($usequantity === 'yes' && !(($recur === 'optional') || ($recur === 'plan'))) {
+        $quantity = $_POST["pf-quantity"];
+        $unitamount = (int) str_replace(' ', '', $amount);
+        $amount = $quantity * $unitamount;
+    }
+    //--------------------------------------
+
+    //--------------------------------------
+    if ($txncharge == 'customer') {
+        $amount = kkd_pff_paystack_add_paystack_charge($amount);
+    }
+    $maxFileSize = $filelimit * 1024 * 1024;
+
+    if (!empty($_FILES)) {
+        foreach ($_FILES as $keyname => $value) {
+            if ($value['size'] > 0) {
+                if ($value['size'] > $maxFileSize) {
+                    $response['result'] = 'failed';
+                    $response['message'] = 'Max upload size is ' . $filelimit . "MB";
+                    exit(json_encode($response));
+                } else {
+                    $attachment_id = media_handle_upload($keyname, $_POST["pf-id"]);
+                    $url = wp_get_attachment_url($attachment_id);
+                    $fixedmetadata[] =  array(
+                        'display_name' => ucwords(str_replace("_", " ", $keyname)),
+                        'variable_name' => $keyname,
+                        'type' => 'link',
+                        'value' => $url
+                    );
+                }
+            } else {
+                $fixedmetadata[] =  array(
+                    'display_name' => ucwords(str_replace("_", " ", $keyname)),
+                    'variable_name' => $keyname,
+                    'type' => 'text',
+                    'value' => 'No file Uploaded'
+                );
+            }
+        }
+    }
+    $plancode = 'none';
+    if ($recur != 'no') {
+        if ($recur == 'optional') {
+            $interval = $_POST['pf-interval'];
+            if ($interval != 'no') {
+                unset($metadata['pf-interval']);
+                $mode =  esc_attr(get_option('mode'));
+                if ($mode == 'test') {
+                    $key = esc_attr(get_option('tsk'));
+                } else {
+                    $key = esc_attr(get_option('lsk'));
+                }
+                $koboamount = $amount * 100;
+                //Create Plan
+                $paystack_url = 'https://api.paystack.co/plan';
+                $check_url = 'https://api.paystack.co/plan?amount=' . $koboamount . '&interval=' . $interval;
+                $headers = array(
+                    'Content-Type'    => 'application/json',
+                    'Authorization' => 'Bearer ' . $key
+                );
+
+                $checkargs = array(
+                    'headers'    => $headers,
+                    'timeout'    => 60
+                );
+                // Check if plan exist
+                $checkrequest = wp_remote_get($check_url, $checkargs);
+                if (!is_wp_error($checkrequest)) {
+                    $response = json_decode(wp_remote_retrieve_body($checkrequest));
+                    if ($response->meta->total >= 1) {
+                        $plan = $response->data[0];
+                        $plancode = $plan->plan_code;
+                        $fixedmetadata[] =  array(
+                            'display_name' => 'Plan Interval',
+                            'variable_name' => 'Plan Interval',
+                            'type' => 'text',
+                            'value' => $plan->interval
+                        );
+                    } else {
+                        //Create Plan
+                        $body = array(
+                            'name'     => $currency . number_format($originalamount) . ' [' . $currency . number_format($amount) . '] - ' . $interval,
+                            'amount'   => $koboamount,
+                            'interval' => $interval
+                        );
+                        $args = array(
+                            'body'     => json_encode($body),
+                            'headers'  => $headers,
+                            'timeout'  => 60
+                        );
+
+                        $request = wp_remote_post($paystack_url, $args);
+                        if (!is_wp_error($request)) {
+                            $paystack_response = json_decode(wp_remote_retrieve_body($request));
+                            $plancode    = $paystack_response->data->plan_code;
+                            $fixedmetadata[] =  array(
+                                'display_name' => 'Plan Interval',
+                                'variable_name' => 'Plan Interval',
+                                'type' => 'text',
+                                'value' => $paystack_response->data->interval
+                            );
+                        }
+                    }
+                }
+            }
+        } else {
+            //Use Plan Code
+            $plancode = $_POST['pf-plancode'];
+            unset($metadata['pf-plancode']);
+        }
+    }
+
+    if ($plancode != 'none') {
+        $fixedmetadata[] =  array(
+            'display_name' => 'Plan',
+            'variable_name' => 'Plan',
+            'type' => 'text',
+            'value' => $plancode
+        );
+    }
+
+    $fixedmetadata = json_decode(json_encode($fixedmetadata, JSON_NUMERIC_CHECK), true);
+    $fixedmetadata = array_merge($untouchedmetadata, $fixedmetadata);
+
+    $insert = array(
+        'post_id' => sanitize_text_field($_POST["pf-id"]),
+        'email' => sanitize_email($_POST["pf-pemail"]),
+        'user_id' => sanitize_text_field($_POST["pf-user_id"]),
+        'amount' => sanitize_text_field($_POST["amount"]), // Assuming $amount comes from $_POST
+        'plan' => sanitize_text_field($_POST["plancode"]), // Assuming $plancode comes from $_POST
+        'ip' => kkd_pff_paystack_get_the_user_ip(), // Make sure this function returns a sanitized IP
+        'txn_code' => sanitize_text_field($_POST['code']), // Assuming $code comes from $_POST
+        'metadata' => wp_json_encode($_POST["fixedmetadata"]) // Assuming $fixedmetadata comes from $_POST
+    );
+    
+    $exist = $wpdb->get_results(
+        $wpdb->prepare(
+            "SELECT * FROM {$table} WHERE post_id = %s AND email = %s AND user_id = %s AND amount = %s AND plan = %s AND ip = %s AND paid = '0' AND metadata = %s",
+            $insert['post_id'], $insert['email'], $insert['user_id'], $insert['amount'], $insert['plan'], $insert['ip'], $insert['metadata']
+        )
+    );
+    if (count($exist) > 0) {
+        // $insert['txn_code'] = $code;
+        // $insert['plan'] = $exist[0]->plan;
+        $wpdb->update($table, array('txn_code' => $code, 'plan' => $insert['plan']), array('id' => $exist[0]->id));
+    } else {
+        $wpdb->insert(
+            $table,
+            $insert
+        );
+        if("yes" == get_post_meta($insert['post_id'], '_sendinvoice', true)) {
+            kkd_pff_paystack_send_invoice($currency, $insert['amount'], $fullname, $insert['email'], $code);
+        }
+    }
+    if ($subaccount == "" || !isset($subaccount)) {
+        $subaccount = null;
+        $txnbearer = null;
+        $transaction_charge = null;
+    }
+    if ($transaction_charge == "" || $transaction_charge == 0 || $transaction_charge == null) {
+        $transaction_charge = null;
+    }
+
+    $amount = floatval($insert['amount']) * 100;
+    $response = array(
+        'result' => 'success',
+        'code' => $insert['txn_code'],
+        'plan' => $insert['plan'],
+        'quantity' => $quantity,
+        'email' => $insert['email'],
+        'name' => $fullname,
+        'total' => round($amount),
+        'currency' => $currency,
+        'custom_fields' => $fixedmetadata,
+        'subaccount' => $subaccount,
+        'txnbearer' => $txnbearer,
+        'transaction_charge' => $transaction_charge
+    );
+
+    //-------------------------------------------------------------------------------------------
+
+    // $pstk_logger = new paystack_plugin_tracker('pff-paystack', Kkd_Pff_Paystack_Public::fetchPublicKey());
+    // $pstk_logger->log_transaction_attempt($code);
+
+    echo json_encode($response);
+    die();
+}
+
+function kkd_pff_paystack_meta_as_custom_fields($metadata)
+{
+    $custom_fields = array();
+    foreach ($metadata as $key => $value) {
+        if (is_array($value)) {
+            $value = implode(', ', $value);
+        }
+        if ($key == 'pf-fname') {
+            $custom_fields[] =  array(
+                'display_name' => 'Full Name',
+                'variable_name' => 'Full_Name',
+                'type' => 'text',
+                'value' => $value
+            );
+        } elseif ($key == 'pf-plancode') {
+            $custom_fields[] =  array(
+                'display_name' => 'Plan',
+                'variable_name' => 'Plan',
+                'type' => 'text',
+                'value' => $value
+            );
+        } elseif ($key == 'pf-vname') {
+            $custom_fields[] =  array(
+                'display_name' => 'Payment Option',
+                'variable_name' => 'Payment Option',
+                'type' => 'text',
+                'value' => $value
+            );
+        } elseif ($key == 'pf-interval') {
+            $custom_fields[] =  array(
+                'display_name' => 'Plan Interval',
+                'variable_name' => 'Plan Interval',
+                'type' => 'text',
+                'value' => $value
+            );
+        } elseif ($key == 'pf-quantity') {
+            $custom_fields[] =  array(
+                'display_name' => 'Quantity',
+                'variable_name' => 'Quantity',
+                'type' => 'text',
+                'value' => $value
+            );
+        } else {
+            $custom_fields[] =  array(
+                'display_name' => ucwords(str_replace("_", " ", $key)),
+                'variable_name' => $key,
+                'type' => 'text',
+                'value' => (string) $value
+            );
+        }
+    }
+    return $custom_fields;
+}
+
+add_action('wp_ajax_kkd_pff_paystack_confirm_payment', 'kkd_pff_paystack_confirm_payment');
+add_action('wp_ajax_nopriv_kkd_pff_paystack_confirm_payment', 'kkd_pff_paystack_confirm_payment');
+
+function kkd_pff_paystack_confirm_payment()
+{
+    if (trim($_POST['code']) == '') {
+        $response['error'] = true;
+        $response['error_message'] = "Did you make a payment?";
+
+        exit(json_encode($response));
+    }
+    global $wpdb;
+    $table = $wpdb->prefix . KKD_PFF_PAYSTACK_TABLE;
+   
+    $code = sanitize_text_field($_POST['code']);
+
+    $record = $wpdb->get_results($wpdb->prepare("SELECT * FROM {$table} WHERE txn_code = %s", $code));
+    if (array_key_exists("0", $record)) {
+        $payment_array = $record[0];
+        $amount = get_post_meta($payment_array->post_id, '_amount', true);
+        $recur = get_post_meta($payment_array->post_id, '_recur', true);
+        $currency = get_post_meta($payment_array->post_id, '_currency', true);
+        $txncharge = get_post_meta($payment_array->post_id, '_txncharge', true);
+        $redirect = get_post_meta($payment_array->post_id, '_redirect', true);
+        $minimum = get_post_meta($payment_array->post_id, '_minimum', true);
+        $usevariableamount = get_post_meta($payment_array->post_id, '_usevariableamount', true);
+        $variableamount = get_post_meta($payment_array->post_id, '_variableamount', true);
+
+        // if ($minimum == 1 && floatval($amount) != 0) {
+        //     if ($payment_array->amount < floatval($formamount)) {
+        //         $amount = floatval($formamount);
+        //     } else {
+        //         $amount = $payment_array->amount;
+        //     }
+        // }
+
+        $amount = $payment_array->amount;
+
+        $oamount = $amount;
+        $mode =  esc_attr(get_option('mode'));
+        if ($mode == 'test') {
+            $key = esc_attr(get_option('tsk'));
+        } else {
+            $key = esc_attr(get_option('lsk'));
+        }
+        $paystack_url = 'https://api.paystack.co/transaction/verify/' . $code;
+        $headers = array(
+            'Authorization' => 'Bearer ' . $key
+        );
+        $args = array(
+            'headers'    => $headers,
+            'timeout'    => 60
+        );
+        $request = wp_remote_get($paystack_url, $args);
+        if (!is_wp_error($request) && 200 == wp_remote_retrieve_response_code($request)) {
+            $paystack_response = json_decode(wp_remote_retrieve_body($request));
+            if ('success' == $paystack_response->data->status) {
+                //=============================================================
+             
+                $usequantity = get_post_meta($payment_array->post_id, '_usequantity', true);
+                if ($usequantity = "yes") {
+                    $quantity = $_POST["quantity"];
+                    $sold = get_post_meta($payment_array->post_id, '_sold', true);
+                    // error_log(print_r("sold", TRUE)); 
+                    // error_log(print_r($sold, TRUE)); 
+                    // error_log(print_r(" -  -  - -- - --  - -  --  - ", TRUE));
+                    // error_log(print_r("Qty", TRUE));  
+                    // error_log(print_r($quantity, TRUE)); 
+                    if ($sold == '') {
+                        $sold = '0';
+                    }
+                    $sold = $sold + $quantity;
+                }
+
+
+                if (get_post_meta($payment_array->post_id, '_sold', false)) { // If the custom field already has a value
+                  
+                    update_post_meta($payment_array->post_id, '_sold', $sold);
+                } else { // If the custom field doesn't have a value
+                    add_post_meta($payment_array->post_id, '_sold', $sold);
+                }
+                //=============================================================
+                $customer_code = $paystack_response->data->customer->customer_code;
+                $amount_paid    = $paystack_response->data->amount / 100;
+                $paystack_ref     = $paystack_response->data->reference;
+                $paid_at        = $paystack_response->data->transaction_date;
+                if ($recur == 'optional' || $recur == 'plan') {
+                    $wpdb->update($table, array('paid' => 1, 'amount' => $amount_paid, 'paid_at' => $paid_at), array('txn_code' => $paystack_ref));
+                    $thankyou = get_post_meta($payment_array->post_id, '_successmsg', true);
+                    $message = $thankyou;
+                    $result = "success";
+                } else {
+                    if ($amount == 0 || $usevariableamount == 1) {
+                        $wpdb->update($table, array('paid' => 1, 'amount' => $amount_paid, 'paid_at' => $paid_at), array('txn_code' => $paystack_ref));
+                        $thankyou = get_post_meta($payment_array->post_id, '_successmsg', true);
+                        $message = $thankyou;
+                        $result = "success";
+                        // kkd_pff_paystack_send_receipt($currency,$amount,$name,$payment_array->email,$code,$metadata)
+                    } else {
+                        if ($oamount !=  $amount_paid) {
+                            $message = "Invalid amount Paid. Amount required is " . $currency . "" . number_format($oamount) . "";
+                            $result = "failed";
+                        } else {
+                            $wpdb->update($table, array('paid' => 1, 'paid_at' => $paid_at), array('txn_code' => $paystack_ref));
+                            $thankyou = get_post_meta($payment_array->post_id, '_successmsg', true);
+                            $message = $thankyou;
+                            $result = "success";
+                        }
+                    }
+                }
+            } else {
+                $message = "Transaction Failed/Invalid Code";
+                $result = "failed";
+            }
+        } else {
+            $message = "Payment Verifiction Failed";
+            $result = "failed";
+        }
+    } else {
+        $message = "Payment Verification Failed.";
+        $result = "failed";
+    }
+
+    if ($result == 'success') {
+        ///
+        //Create Plan
+        $pstk_logger = new kkd_pff_paystack_plugin_tracker('pff-paystack', Kkd_Pff_Paystack_Public::fetchPublicKey());
+        $pstk_logger->log_transaction_success($code);
+        $enabled_custom_plan = get_post_meta($payment_array->post_id, '_startdate_enabled', true);
+        if ($enabled_custom_plan == 1) {
+            $mode =  esc_attr(get_option('mode'));
+            if ($mode == 'test') {
+                $key = esc_attr(get_option('tsk'));
+            } else {
+                $key = esc_attr(get_option('lsk'));
+            }
+            //Create Plan
+            $paystack_url = 'https://api.paystack.co/subscription';
+            $headers = array(
+                'Content-Type'    => 'application/json',
+                'Authorization' => 'Bearer ' . $key
+            );
+            $custom_plan = get_post_meta($payment_array->post_id, '_startdate_plan_code', true);
+            $days = get_post_meta($payment_array->post_id, '_startdate_days', true);
+
+            $start_date = date("c", strtotime("+" . $days . " days"));
+            $body = array(
+                'start_date'    => $start_date,
+                'plan'            => $custom_plan,
+                'customer'        => $customer_code
+            );
+            $args = array(
+                'body'        => json_encode($body),
+                'headers'    => $headers,
+                'timeout'    => 60
+            );
+
+            $request = wp_remote_post($paystack_url, $args);
+            if (!is_wp_error($request)) {
+                $paystack_response = json_decode(wp_remote_retrieve_body($request));
+                $plancode    = $paystack_response->data->subscription_code;
+                // $message.= $message.'Subscribed
'.$plancode.'sssss'; + } + } + + $sendreceipt = get_post_meta($payment_array->post_id, '_sendreceipt', true); + if ($sendreceipt == 'yes') { + $decoded = json_decode($payment_array->metadata); + $fullname = $decoded[1]->value; + kkd_pff_paystack_send_receipt($payment_array->post_id, $currency, $amount_paid, $fullname, $payment_array->email, $paystack_ref, $payment_array->metadata); + kkd_pff_paystack_send_receipt_owner($payment_array->post_id, $currency, $amount_paid, $fullname, $payment_array->email, $paystack_ref, $payment_array->metadata); + } + } + $response = array( + 'result' => $result, + 'message' => $message, + ); + if ($result == 'success' && $redirect != '') { + $response['result'] = 'success2'; + $response['link'] = $redirect; + } + + + echo json_encode($response); + + die(); +} + + +add_action('wp_ajax_kkd_pff_paystack_retry_action', 'kkd_pff_paystack_retry_action'); +add_action('wp_ajax_nopriv_kkd_pff_paystack_retry_action', 'kkd_pff_paystack_retry_action'); +function kkd_pff_paystack_retry_action() +{ + if (trim($_POST['code']) == '') { + $response['result'] = 'failed'; + $response['message'] = 'Cde is required'; + + // Exit here, for not processing further because of the error + exit(json_encode($response)); + } + do_action('kkd_pff_paystack_before_save'); + + global $wpdb; + + $code = sanitize_text_field($_POST['code']); + $newcode = kkd_pff_paystack_generate_code(); // Ensure this function returns a sanitized string + $newcode .= '_2'; + $insert = array(); + $table = $wpdb->prefix . KKD_PFF_PAYSTACK_TABLE; + + $record = $wpdb->get_results($wpdb->prepare("SELECT * FROM {$table} WHERE txn_code = %s", $code)); + + if (array_key_exists("0", $record)) { + $dbdata = $record[0]; + $plan = $dbdata->plan; + $quantity = 1; + $wpdb->update($table, array('txn_code_2' => $newcode), array('txn_code' => $code)); + + $currency = get_post_meta($dbdata->post_id, '_currency', true); + $subaccount = get_post_meta($dbdata->post_id, '_subaccount', true); + $txnbearer = get_post_meta($dbdata->post_id, '_txnbearer', true); + $transaction_charge = get_post_meta($dbdata->post_id, '_merchantamount', true); + $transaction_charge = $transaction_charge * 100; + $fixedmetadata = kkd_pff_paystack_meta_as_custom_fields($dbdata->metadata); + $nmeta = json_decode($dbdata->metadata); + foreach ($nmeta as $nkey => $nvalue) { + if ($nvalue->variable_name == 'Quantity') { + $quantity = $nvalue->value; + } + if ($nvalue->variable_name == 'Full_Name') { + $fullname = $nvalue->value; + } + } + } + if ($subaccount == "" || !isset($subaccount)) { + $subaccount = null; + $txnbearer = null; + $transaction_charge = null; + } + if ($transaction_charge == "" || $transaction_charge == 0 || $transaction_charge == null || !isset($transaction_charge)) { + $transaction_charge = null; + } + $response = array( + 'result' => 'success', + 'code' => $newcode, + 'plan' => $plan, + 'quantity' => $quantity, + 'email' => $dbdata->email, + 'name' => $fullname, + 'total' => $dbdata->amount * 100, + 'custom_fields' => $fixedmetadata, + 'currency' => $currency, + 'subaccount' => $subaccount, + 'txnbearer' => $txnbearer, + 'transaction_charge' => $transaction_charge + ); + echo json_encode($response); + + die(); +} +add_action('wp_ajax_kkd_pff_paystack_rconfirm_payment', 'kkd_pff_paystack_rconfirm_payment'); +add_action('wp_ajax_nopriv_kkd_pff_paystack_rconfirm_payment', 'kkd_pff_paystack_rconfirm_payment'); + +function kkd_pff_paystack_rconfirm_payment() +{ + if (trim($_POST['code']) == '') { + $response['error'] = true; + $response['error_message'] = "Did you make a payment?"; + + exit(json_encode($response)); + } + global $wpdb; + $table = $wpdb->prefix . KKD_PFF_PAYSTACK_TABLE; + $code = sanitize_text_field($_POST['code']); + $record = $wpdb->get_results($wpdb->prepare("SELECT * FROM {$table} WHERE txn_code_2 = %s", $code)); + if (array_key_exists("0", $record)) { + $payment_array = $record[0]; + $amount = get_post_meta($payment_array->post_id, '_amount', true); + $recur = get_post_meta($payment_array->post_id, '_recur', true); + $currency = get_post_meta($payment_array->post_id, '_currency', true); + $txncharge = get_post_meta($payment_array->post_id, '_txncharge', true); + $redirect = get_post_meta($payment_array->post_id, '_redirect', true); + + + $mode = esc_attr(get_option('mode')); + if ($mode == 'test') { + $key = esc_attr(get_option('tsk')); + } else { + $key = esc_attr(get_option('lsk')); + } + $paystack_url = 'https://api.paystack.co/transaction/verify/' . $code; + $headers = array( + 'Authorization' => 'Bearer ' . $key + ); + $args = array( + 'headers' => $headers, + 'timeout' => 60 + ); + $request = wp_remote_get($paystack_url, $args); + if (!is_wp_error($request) && 200 == wp_remote_retrieve_response_code($request)) { + $paystack_response = json_decode(wp_remote_retrieve_body($request)); + if ('success' == $paystack_response->data->status) { + $amount_paid = $paystack_response->data->amount / 100; + $paystack_ref = $paystack_response->data->reference; + if ($recur == 'optional' || $recur == 'plan') { + $wpdb->update($table, array('paid' => 1, 'amount' => $amount_paid), array('txn_code_2' => $paystack_ref)); + $thankyou = get_post_meta($payment_array->post_id, '_successmsg', true); + $message = $thankyou; + $result = "success"; + } else { + if ($amount == 0) { + $wpdb->update($table, array('paid' => 1, 'amount' => $amount_paid, 'paid_at' => $paid_at), array('txn_code_2' => $paystack_ref)); + $thankyou = get_post_meta($payment_array->post_id, '_successmsg', true); + $message = $thankyou; + $result = "success"; + // kkd_pff_paystack_send_receipt($currency,$amount,$name,$payment_array->email,$code,$metadata) + } else { + $usequantity = get_post_meta($payment_array->post_id, '_usequantity', true); + if ($usequantity == 'no') { + $amount = (int) str_replace(' ', '', $amount); + } else { + $quantity = $_POST["quantity"]; + $unitamount = (int) str_replace(' ', '', $amount); + $amount = $quantity * $unitamount; + } + + + if ($txncharge == 'customer') { + $amount = kkd_pff_paystack_add_paystack_charge($amount); + } + if ($amount != $amount_paid) { + $message = "Invalid amount Paid. Amount required is " . $currency . "" . number_format($amount) . ""; + $result = "failed"; + } else { + $wpdb->update($table, array('paid' => 1, 'paid_at' => $paid_at), array('txn_code_2' => $paystack_ref)); + $thankyou = get_post_meta($payment_array->post_id, '_successmsg', true); + $message = $thankyou; + $result = "success"; + } + } + } + } else { + $message = "Transaction Failed/Invalid Code"; + $result = "failed"; + } + } + } else { + $message = "Payment Verification Failed."; + $result = "failed"; + } + + if ($result == 'success') { + //Log to amplitude + $pstk_logger = new paystack_plugin_tracker('pff-paystack', Kkd_Pff_Paystack_Public::fetchPublicKey()); + $pstk_logger->log_transaction_success($code); + $sendreceipt = get_post_meta($payment_array->post_id, '_sendreceipt', true); + if ($sendreceipt == 'yes') { + $decoded = json_decode($payment_array->metadata); + $fullname = $decoded[1]->value; + kkd_pff_paystack_send_receipt($payment_array->post_id, $currency, $amount_paid, $fullname, $payment_array->email, $paystack_ref, $payment_array->metadata); + kkd_pff_paystack_send_receipt_owner($payment_array->post_id, $currency, $amount_paid, $fullname, $payment_array->email, $paystack_ref, $payment_array->metadata); + } + } + $response = array( + 'result' => $result, + 'message' => $message, + ); + if ($result == 'success' && $redirect != '') { + $response['result'] = 'success2'; + $response['link'] = $redirect; + } + + + echo json_encode($response); + + die(); +} diff --git a/public/class-paystack-plugin-tracker.php b/public/class-paystack-plugin-tracker.php new file mode 100644 index 0000000..2f24b8b --- /dev/null +++ b/public/class-paystack-plugin-tracker.php @@ -0,0 +1,71 @@ +plugin_name = $plugin; + $this->public_key = $pk; + } + + /** + * Logs a successful transaction. + * + * @param string $trx_ref The transaction reference. + */ + public function logTransactionSuccess($trx_ref) + { + // Send reference to logger along with plugin name and public key + $url = "https://plugin-tracker.paystackintegrations.com/log/charge_success"; + + $fields = [ + 'plugin_name' => $this->plugin_name, + 'transaction_reference' => $trx_ref, + 'public_key' => $this->public_key, + ]; + + $fields_string = http_build_query($fields); + + $ch = curl_init(); + + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + + // Execute post + $result = curl_exec($ch); + } +} diff --git a/public/css/.DS_Store b/public/css/.DS_Store new file mode 100644 index 0000000..5008ddf Binary files /dev/null and b/public/css/.DS_Store differ diff --git a/assets/css/font-awesome.min.css b/public/css/font-awesome.min.css similarity index 100% rename from assets/css/font-awesome.min.css rename to public/css/font-awesome.min.css diff --git a/assets/css/pff-paystack.css b/public/css/pff-paystack-style.css similarity index 100% rename from assets/css/pff-paystack.css rename to public/css/pff-paystack-style.css diff --git a/assets/fonts/Graphik-Black.otf b/public/fonts/Graphik-Black.otf similarity index 100% rename from assets/fonts/Graphik-Black.otf rename to public/fonts/Graphik-Black.otf diff --git a/assets/fonts/Graphik-BlackItalic.otf b/public/fonts/Graphik-BlackItalic.otf similarity index 100% rename from assets/fonts/Graphik-BlackItalic.otf rename to public/fonts/Graphik-BlackItalic.otf diff --git a/assets/fonts/Graphik-Bold.otf b/public/fonts/Graphik-Bold.otf similarity index 100% rename from assets/fonts/Graphik-Bold.otf rename to public/fonts/Graphik-Bold.otf diff --git a/assets/fonts/Graphik-BoldItalic.otf b/public/fonts/Graphik-BoldItalic.otf similarity index 100% rename from assets/fonts/Graphik-BoldItalic.otf rename to public/fonts/Graphik-BoldItalic.otf diff --git a/assets/fonts/Graphik-Extralight.otf b/public/fonts/Graphik-Extralight.otf similarity index 100% rename from assets/fonts/Graphik-Extralight.otf rename to public/fonts/Graphik-Extralight.otf diff --git a/assets/fonts/Graphik-ExtralightItalic.otf b/public/fonts/Graphik-ExtralightItalic.otf similarity index 100% rename from assets/fonts/Graphik-ExtralightItalic.otf rename to public/fonts/Graphik-ExtralightItalic.otf diff --git a/assets/fonts/Graphik-Light.otf b/public/fonts/Graphik-Light.otf similarity index 100% rename from assets/fonts/Graphik-Light.otf rename to public/fonts/Graphik-Light.otf diff --git a/assets/fonts/Graphik-LightItalic.otf b/public/fonts/Graphik-LightItalic.otf similarity index 100% rename from assets/fonts/Graphik-LightItalic.otf rename to public/fonts/Graphik-LightItalic.otf diff --git a/assets/fonts/Graphik-Medium.otf b/public/fonts/Graphik-Medium.otf similarity index 100% rename from assets/fonts/Graphik-Medium.otf rename to public/fonts/Graphik-Medium.otf diff --git a/assets/fonts/Graphik-MediumItalic.otf b/public/fonts/Graphik-MediumItalic.otf similarity index 100% rename from assets/fonts/Graphik-MediumItalic.otf rename to public/fonts/Graphik-MediumItalic.otf diff --git a/assets/fonts/Graphik-Regular.otf b/public/fonts/Graphik-Regular.otf similarity index 100% rename from assets/fonts/Graphik-Regular.otf rename to public/fonts/Graphik-Regular.otf diff --git a/assets/fonts/Graphik-RegularItalic.otf b/public/fonts/Graphik-RegularItalic.otf similarity index 100% rename from assets/fonts/Graphik-RegularItalic.otf rename to public/fonts/Graphik-RegularItalic.otf diff --git a/assets/fonts/Graphik-Semibold.otf b/public/fonts/Graphik-Semibold.otf similarity index 100% rename from assets/fonts/Graphik-Semibold.otf rename to public/fonts/Graphik-Semibold.otf diff --git a/assets/fonts/Graphik-SemiboldItalic.otf b/public/fonts/Graphik-SemiboldItalic.otf similarity index 100% rename from assets/fonts/Graphik-SemiboldItalic.otf rename to public/fonts/Graphik-SemiboldItalic.otf diff --git a/assets/fonts/Graphik-Super.otf b/public/fonts/Graphik-Super.otf similarity index 100% rename from assets/fonts/Graphik-Super.otf rename to public/fonts/Graphik-Super.otf diff --git a/assets/fonts/Graphik-SuperItalic.otf b/public/fonts/Graphik-SuperItalic.otf similarity index 100% rename from assets/fonts/Graphik-SuperItalic.otf rename to public/fonts/Graphik-SuperItalic.otf diff --git a/assets/fonts/Graphik-Thin.otf b/public/fonts/Graphik-Thin.otf similarity index 100% rename from assets/fonts/Graphik-Thin.otf rename to public/fonts/Graphik-Thin.otf diff --git a/assets/fonts/Graphik-ThinItalic.otf b/public/fonts/Graphik-ThinItalic.otf similarity index 100% rename from assets/fonts/Graphik-ThinItalic.otf rename to public/fonts/Graphik-ThinItalic.otf diff --git a/assets/fonts/fontawesome-webfont-.eot b/public/fonts/fontawesome-webfont-.eot similarity index 100% rename from assets/fonts/fontawesome-webfont-.eot rename to public/fonts/fontawesome-webfont-.eot diff --git a/assets/fonts/fontawesome-webfont-v=4.2.0.eot b/public/fonts/fontawesome-webfont-v=4.2.0.eot similarity index 100% rename from assets/fonts/fontawesome-webfont-v=4.2.0.eot rename to public/fonts/fontawesome-webfont-v=4.2.0.eot diff --git a/assets/fonts/fontawesome-webfont-v=4.2.0.svg b/public/fonts/fontawesome-webfont-v=4.2.0.svg similarity index 100% rename from assets/fonts/fontawesome-webfont-v=4.2.0.svg rename to public/fonts/fontawesome-webfont-v=4.2.0.svg diff --git a/assets/fonts/fontawesome-webfont-v=4.2.0.ttf b/public/fonts/fontawesome-webfont-v=4.2.0.ttf similarity index 100% rename from assets/fonts/fontawesome-webfont-v=4.2.0.ttf rename to public/fonts/fontawesome-webfont-v=4.2.0.ttf diff --git a/assets/fonts/fontawesome-webfont-v=4.2.0.woff b/public/fonts/fontawesome-webfont-v=4.2.0.woff similarity index 100% rename from assets/fonts/fontawesome-webfont-v=4.2.0.woff rename to public/fonts/fontawesome-webfont-v=4.2.0.woff diff --git a/public/index.php b/public/index.php new file mode 100644 index 0000000..e71af0e --- /dev/null +++ b/public/index.php @@ -0,0 +1 @@ +"))}function a(t){var i="button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";return t.delegate(i,"mouseout",function(){e(this).removeClass("ui-state-hover"),-1!==this.className.indexOf("ui-datepicker-prev")&&e(this).removeClass("ui-datepicker-prev-hover"),-1!==this.className.indexOf("ui-datepicker-next")&&e(this).removeClass("ui-datepicker-next-hover")}).delegate(i,"mouseover",o)}function o(){e.datepicker._isDisabledDatepicker(d.inline?d.dpDiv.parent()[0]:d.input[0])||(e(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"),e(this).addClass("ui-state-hover"),-1!==this.className.indexOf("ui-datepicker-prev")&&e(this).addClass("ui-datepicker-prev-hover"),-1!==this.className.indexOf("ui-datepicker-next")&&e(this).addClass("ui-datepicker-next-hover"))}function r(t,i){e.extend(t,i);for(var s in i)null==i[s]&&(t[s]=i[s]);return t}e.ui=e.ui||{},e.extend(e.ui,{version:"1.11.4",keyCode:{BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38}}),e.fn.extend({scrollParent:function(t){var i=this.css("position"),s="absolute"===i,n=t?/(auto|scroll|hidden)/:/(auto|scroll)/,a=this.parents().filter(function(){var t=e(this);return s&&"static"===t.css("position")?!1:n.test(t.css("overflow")+t.css("overflow-y")+t.css("overflow-x"))}).eq(0);return"fixed"!==i&&a.length?a:e(this[0].ownerDocument||document)},uniqueId:function(){var e=0;return function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++e)})}}(),removeUniqueId:function(){return this.each(function(){/^ui-id-\d+$/.test(this.id)&&e(this).removeAttr("id")})}}),e.extend(e.expr[":"],{data:e.expr.createPseudo?e.expr.createPseudo(function(t){return function(i){return!!e.data(i,t)}}):function(t,i,s){return!!e.data(t,s[3])},focusable:function(i){return t(i,!isNaN(e.attr(i,"tabindex")))},tabbable:function(i){var s=e.attr(i,"tabindex"),n=isNaN(s);return(n||s>=0)&&t(i,!n)}}),e("").outerWidth(1).jquery||e.each(["Width","Height"],function(t,i){function s(t,i,s,a){return e.each(n,function(){i-=parseFloat(e.css(t,"padding"+this))||0,s&&(i-=parseFloat(e.css(t,"border"+this+"Width"))||0),a&&(i-=parseFloat(e.css(t,"margin"+this))||0)}),i}var n="Width"===i?["Left","Right"]:["Top","Bottom"],a=i.toLowerCase(),o={innerWidth:e.fn.innerWidth,innerHeight:e.fn.innerHeight,outerWidth:e.fn.outerWidth,outerHeight:e.fn.outerHeight};e.fn["inner"+i]=function(t){return void 0===t?o["inner"+i].call(this):this.each(function(){e(this).css(a,s(this,t)+"px")})},e.fn["outer"+i]=function(t,n){return"number"!=typeof t?o["outer"+i].call(this,t):this.each(function(){e(this).css(a,s(this,t,!0,n)+"px")})}}),e.fn.addBack||(e.fn.addBack=function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}),e("").data("a-b","a").removeData("a-b").data("a-b")&&(e.fn.removeData=function(t){return function(i){return arguments.length?t.call(this,e.camelCase(i)):t.call(this)}}(e.fn.removeData)),e.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase()),e.fn.extend({focus:function(t){return function(i,s){return"number"==typeof i?this.each(function(){var t=this;setTimeout(function(){e(t).focus(),s&&s.call(t)},i)}):t.apply(this,arguments)}}(e.fn.focus),disableSelection:function(){var e="onselectstart"in document.createElement("div")?"selectstart":"mousedown";return function(){return this.bind(e+".ui-disableSelection",function(e){e.preventDefault()})}}(),enableSelection:function(){return this.unbind(".ui-disableSelection")},zIndex:function(t){if(void 0!==t)return this.css("zIndex",t);if(this.length)for(var i,s,n=e(this[0]);n.length&&n[0]!==document;){if(i=n.css("position"),("absolute"===i||"relative"===i||"fixed"===i)&&(s=parseInt(n.css("zIndex"),10),!isNaN(s)&&0!==s))return s;n=n.parent()}return 0}}),e.ui.plugin={add:function(t,i,s){var n,a=e.ui[t].prototype;for(n in s)a.plugins[n]=a.plugins[n]||[],a.plugins[n].push([i,s[n]])},call:function(e,t,i,s){var n,a=e.plugins[t];if(a&&(s||e.element[0].parentNode&&11!==e.element[0].parentNode.nodeType))for(n=0;a.length>n;n++)e.options[a[n][0]]&&a[n][1].apply(e.element,i)}};var h=0,l=Array.prototype.slice;e.cleanData=function(t){return function(i){var s,n,a;for(a=0;null!=(n=i[a]);a++)try{s=e._data(n,"events"),s&&s.remove&&e(n).triggerHandler("remove")}catch(o){}t(i)}}(e.cleanData),e.widget=function(t,i,s){var n,a,o,r,h={},l=t.split(".")[0];return t=t.split(".")[1],n=l+"-"+t,s||(s=i,i=e.Widget),e.expr[":"][n.toLowerCase()]=function(t){return!!e.data(t,n)},e[l]=e[l]||{},a=e[l][t],o=e[l][t]=function(e,t){return this._createWidget?(arguments.length&&this._createWidget(e,t),void 0):new o(e,t)},e.extend(o,a,{version:s.version,_proto:e.extend({},s),_childConstructors:[]}),r=new i,r.options=e.widget.extend({},r.options),e.each(s,function(t,s){return e.isFunction(s)?(h[t]=function(){var e=function(){return i.prototype[t].apply(this,arguments)},n=function(e){return i.prototype[t].apply(this,e)};return function(){var t,i=this._super,a=this._superApply;return this._super=e,this._superApply=n,t=s.apply(this,arguments),this._super=i,this._superApply=a,t}}(),void 0):(h[t]=s,void 0)}),o.prototype=e.widget.extend(r,{widgetEventPrefix:a?r.widgetEventPrefix||t:t},h,{constructor:o,namespace:l,widgetName:t,widgetFullName:n}),a?(e.each(a._childConstructors,function(t,i){var s=i.prototype;e.widget(s.namespace+"."+s.widgetName,o,i._proto)}),delete a._childConstructors):i._childConstructors.push(o),e.widget.bridge(t,o),o},e.widget.extend=function(t){for(var i,s,n=l.call(arguments,1),a=0,o=n.length;o>a;a++)for(i in n[a])s=n[a][i],n[a].hasOwnProperty(i)&&void 0!==s&&(t[i]=e.isPlainObject(s)?e.isPlainObject(t[i])?e.widget.extend({},t[i],s):e.widget.extend({},s):s);return t},e.widget.bridge=function(t,i){var s=i.prototype.widgetFullName||t;e.fn[t]=function(n){var a="string"==typeof n,o=l.call(arguments,1),r=this;return a?this.each(function(){var i,a=e.data(this,s);return"instance"===n?(r=a,!1):a?e.isFunction(a[n])&&"_"!==n.charAt(0)?(i=a[n].apply(a,o),i!==a&&void 0!==i?(r=i&&i.jquery?r.pushStack(i.get()):i,!1):void 0):e.error("no such method '"+n+"' for "+t+" widget instance"):e.error("cannot call methods on "+t+" prior to initialization; "+"attempted to call method '"+n+"'")}):(o.length&&(n=e.widget.extend.apply(null,[n].concat(o))),this.each(function(){var t=e.data(this,s);t?(t.option(n||{}),t._init&&t._init()):e.data(this,s,new i(n,this))})),r}},e.Widget=function(){},e.Widget._childConstructors=[],e.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"
",options:{disabled:!1,create:null},_createWidget:function(t,i){i=e(i||this.defaultElement||this)[0],this.element=e(i),this.uuid=h++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=e(),this.hoverable=e(),this.focusable=e(),i!==this&&(e.data(i,this.widgetFullName,this),this._on(!0,this.element,{remove:function(e){e.target===i&&this.destroy()}}),this.document=e(i.style?i.ownerDocument:i.document||i),this.window=e(this.document[0].defaultView||this.document[0].parentWindow)),this.options=e.widget.extend({},this.options,this._getCreateOptions(),t),this._create(),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:e.noop,_getCreateEventData:e.noop,_create:e.noop,_init:e.noop,destroy:function(){this._destroy(),this.element.unbind(this.eventNamespace).removeData(this.widgetFullName).removeData(e.camelCase(this.widgetFullName)),this.widget().unbind(this.eventNamespace).removeAttr("aria-disabled").removeClass(this.widgetFullName+"-disabled "+"ui-state-disabled"),this.bindings.unbind(this.eventNamespace),this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus")},_destroy:e.noop,widget:function(){return this.element},option:function(t,i){var s,n,a,o=t;if(0===arguments.length)return e.widget.extend({},this.options);if("string"==typeof t)if(o={},s=t.split("."),t=s.shift(),s.length){for(n=o[t]=e.widget.extend({},this.options[t]),a=0;s.length-1>a;a++)n[s[a]]=n[s[a]]||{},n=n[s[a]];if(t=s.pop(),1===arguments.length)return void 0===n[t]?null:n[t];n[t]=i}else{if(1===arguments.length)return void 0===this.options[t]?null:this.options[t];o[t]=i}return this._setOptions(o),this},_setOptions:function(e){var t;for(t in e)this._setOption(t,e[t]);return this},_setOption:function(e,t){return this.options[e]=t,"disabled"===e&&(this.widget().toggleClass(this.widgetFullName+"-disabled",!!t),t&&(this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus"))),this},enable:function(){return this._setOptions({disabled:!1})},disable:function(){return this._setOptions({disabled:!0})},_on:function(t,i,s){var n,a=this;"boolean"!=typeof t&&(s=i,i=t,t=!1),s?(i=n=e(i),this.bindings=this.bindings.add(i)):(s=i,i=this.element,n=this.widget()),e.each(s,function(s,o){function r(){return t||a.options.disabled!==!0&&!e(this).hasClass("ui-state-disabled")?("string"==typeof o?a[o]:o).apply(a,arguments):void 0}"string"!=typeof o&&(r.guid=o.guid=o.guid||r.guid||e.guid++);var h=s.match(/^([\w:-]*)\s*(.*)$/),l=h[1]+a.eventNamespace,u=h[2];u?n.delegate(u,l,r):i.bind(l,r)})},_off:function(t,i){i=(i||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,t.unbind(i).undelegate(i),this.bindings=e(this.bindings.not(t).get()),this.focusable=e(this.focusable.not(t).get()),this.hoverable=e(this.hoverable.not(t).get())},_delay:function(e,t){function i(){return("string"==typeof e?s[e]:e).apply(s,arguments)}var s=this;return setTimeout(i,t||0)},_hoverable:function(t){this.hoverable=this.hoverable.add(t),this._on(t,{mouseenter:function(t){e(t.currentTarget).addClass("ui-state-hover")},mouseleave:function(t){e(t.currentTarget).removeClass("ui-state-hover")}})},_focusable:function(t){this.focusable=this.focusable.add(t),this._on(t,{focusin:function(t){e(t.currentTarget).addClass("ui-state-focus")},focusout:function(t){e(t.currentTarget).removeClass("ui-state-focus")}})},_trigger:function(t,i,s){var n,a,o=this.options[t];if(s=s||{},i=e.Event(i),i.type=(t===this.widgetEventPrefix?t:this.widgetEventPrefix+t).toLowerCase(),i.target=this.element[0],a=i.originalEvent)for(n in a)n in i||(i[n]=a[n]);return this.element.trigger(i,s),!(e.isFunction(o)&&o.apply(this.element[0],[i].concat(s))===!1||i.isDefaultPrevented())}},e.each({show:"fadeIn",hide:"fadeOut"},function(t,i){e.Widget.prototype["_"+t]=function(s,n,a){"string"==typeof n&&(n={effect:n});var o,r=n?n===!0||"number"==typeof n?i:n.effect||i:t;n=n||{},"number"==typeof n&&(n={duration:n}),o=!e.isEmptyObject(n),n.complete=a,n.delay&&s.delay(n.delay),o&&e.effects&&e.effects.effect[r]?s[t](n):r!==t&&s[r]?s[r](n.duration,n.easing,a):s.queue(function(i){e(this)[t](),a&&a.call(s[0]),i()})}}),e.widget;var u=!1;e(document).mouseup(function(){u=!1}),e.widget("ui.mouse",{version:"1.11.4",options:{cancel:"input,textarea,button,select,option",distance:1,delay:0},_mouseInit:function(){var t=this;this.element.bind("mousedown."+this.widgetName,function(e){return t._mouseDown(e)}).bind("click."+this.widgetName,function(i){return!0===e.data(i.target,t.widgetName+".preventClickEvent")?(e.removeData(i.target,t.widgetName+".preventClickEvent"),i.stopImmediatePropagation(),!1):void 0}),this.started=!1},_mouseDestroy:function(){this.element.unbind("."+this.widgetName),this._mouseMoveDelegate&&this.document.unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate)},_mouseDown:function(t){if(!u){this._mouseMoved=!1,this._mouseStarted&&this._mouseUp(t),this._mouseDownEvent=t;var i=this,s=1===t.which,n="string"==typeof this.options.cancel&&t.target.nodeName?e(t.target).closest(this.options.cancel).length:!1;return s&&!n&&this._mouseCapture(t)?(this.mouseDelayMet=!this.options.delay,this.mouseDelayMet||(this._mouseDelayTimer=setTimeout(function(){i.mouseDelayMet=!0},this.options.delay)),this._mouseDistanceMet(t)&&this._mouseDelayMet(t)&&(this._mouseStarted=this._mouseStart(t)!==!1,!this._mouseStarted)?(t.preventDefault(),!0):(!0===e.data(t.target,this.widgetName+".preventClickEvent")&&e.removeData(t.target,this.widgetName+".preventClickEvent"),this._mouseMoveDelegate=function(e){return i._mouseMove(e)},this._mouseUpDelegate=function(e){return i._mouseUp(e)},this.document.bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate),t.preventDefault(),u=!0,!0)):!0}},_mouseMove:function(t){if(this._mouseMoved){if(e.ui.ie&&(!document.documentMode||9>document.documentMode)&&!t.button)return this._mouseUp(t);if(!t.which)return this._mouseUp(t)}return(t.which||t.button)&&(this._mouseMoved=!0),this._mouseStarted?(this._mouseDrag(t),t.preventDefault()):(this._mouseDistanceMet(t)&&this._mouseDelayMet(t)&&(this._mouseStarted=this._mouseStart(this._mouseDownEvent,t)!==!1,this._mouseStarted?this._mouseDrag(t):this._mouseUp(t)),!this._mouseStarted)},_mouseUp:function(t){return this.document.unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,t.target===this._mouseDownEvent.target&&e.data(t.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(t)),u=!1,!1},_mouseDistanceMet:function(e){return Math.max(Math.abs(this._mouseDownEvent.pageX-e.pageX),Math.abs(this._mouseDownEvent.pageY-e.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}}),function(){function t(e,t,i){return[parseFloat(e[0])*(p.test(e[0])?t/100:1),parseFloat(e[1])*(p.test(e[1])?i/100:1)]}function i(t,i){return parseInt(e.css(t,i),10)||0}function s(t){var i=t[0];return 9===i.nodeType?{width:t.width(),height:t.height(),offset:{top:0,left:0}}:e.isWindow(i)?{width:t.width(),height:t.height(),offset:{top:t.scrollTop(),left:t.scrollLeft()}}:i.preventDefault?{width:0,height:0,offset:{top:i.pageY,left:i.pageX}}:{width:t.outerWidth(),height:t.outerHeight(),offset:t.offset()}}e.ui=e.ui||{};var n,a,o=Math.max,r=Math.abs,h=Math.round,l=/left|center|right/,u=/top|center|bottom/,d=/[\+\-]\d+(\.[\d]+)?%?/,c=/^\w+/,p=/%$/,f=e.fn.position;e.position={scrollbarWidth:function(){if(void 0!==n)return n;var t,i,s=e("
"),a=s.children()[0];return e("body").append(s),t=a.offsetWidth,s.css("overflow","scroll"),i=a.offsetWidth,t===i&&(i=s[0].clientWidth),s.remove(),n=t-i},getScrollInfo:function(t){var i=t.isWindow||t.isDocument?"":t.element.css("overflow-x"),s=t.isWindow||t.isDocument?"":t.element.css("overflow-y"),n="scroll"===i||"auto"===i&&t.widthi?"left":t>0?"right":"center",vertical:0>a?"top":s>0?"bottom":"middle"};d>m&&m>r(t+i)&&(h.horizontal="center"),c>g&&g>r(s+a)&&(h.vertical="middle"),h.important=o(r(t),r(i))>o(r(s),r(a))?"horizontal":"vertical",n.using.call(this,e,h)}),u.offset(e.extend(N,{using:l}))})},e.ui.position={fit:{left:function(e,t){var i,s=t.within,n=s.isWindow?s.scrollLeft:s.offset.left,a=s.width,r=e.left-t.collisionPosition.marginLeft,h=n-r,l=r+t.collisionWidth-a-n;t.collisionWidth>a?h>0&&0>=l?(i=e.left+h+t.collisionWidth-a-n,e.left+=h-i):e.left=l>0&&0>=h?n:h>l?n+a-t.collisionWidth:n:h>0?e.left+=h:l>0?e.left-=l:e.left=o(e.left-r,e.left)},top:function(e,t){var i,s=t.within,n=s.isWindow?s.scrollTop:s.offset.top,a=t.within.height,r=e.top-t.collisionPosition.marginTop,h=n-r,l=r+t.collisionHeight-a-n;t.collisionHeight>a?h>0&&0>=l?(i=e.top+h+t.collisionHeight-a-n,e.top+=h-i):e.top=l>0&&0>=h?n:h>l?n+a-t.collisionHeight:n:h>0?e.top+=h:l>0?e.top-=l:e.top=o(e.top-r,e.top)}},flip:{left:function(e,t){var i,s,n=t.within,a=n.offset.left+n.scrollLeft,o=n.width,h=n.isWindow?n.scrollLeft:n.offset.left,l=e.left-t.collisionPosition.marginLeft,u=l-h,d=l+t.collisionWidth-o-h,c="left"===t.my[0]?-t.elemWidth:"right"===t.my[0]?t.elemWidth:0,p="left"===t.at[0]?t.targetWidth:"right"===t.at[0]?-t.targetWidth:0,f=-2*t.offset[0];0>u?(i=e.left+c+p+f+t.collisionWidth-o-a,(0>i||r(u)>i)&&(e.left+=c+p+f)):d>0&&(s=e.left-t.collisionPosition.marginLeft+c+p+f-h,(s>0||d>r(s))&&(e.left+=c+p+f))},top:function(e,t){var i,s,n=t.within,a=n.offset.top+n.scrollTop,o=n.height,h=n.isWindow?n.scrollTop:n.offset.top,l=e.top-t.collisionPosition.marginTop,u=l-h,d=l+t.collisionHeight-o-h,c="top"===t.my[1],p=c?-t.elemHeight:"bottom"===t.my[1]?t.elemHeight:0,f="top"===t.at[1]?t.targetHeight:"bottom"===t.at[1]?-t.targetHeight:0,m=-2*t.offset[1];0>u?(s=e.top+p+f+m+t.collisionHeight-o-a,(0>s||r(u)>s)&&(e.top+=p+f+m)):d>0&&(i=e.top-t.collisionPosition.marginTop+p+f+m-h,(i>0||d>r(i))&&(e.top+=p+f+m))}},flipfit:{left:function(){e.ui.position.flip.left.apply(this,arguments),e.ui.position.fit.left.apply(this,arguments)},top:function(){e.ui.position.flip.top.apply(this,arguments),e.ui.position.fit.top.apply(this,arguments)}}},function(){var t,i,s,n,o,r=document.getElementsByTagName("body")[0],h=document.createElement("div");t=document.createElement(r?"div":"body"),s={visibility:"hidden",width:0,height:0,border:0,margin:0,background:"none"},r&&e.extend(s,{position:"absolute",left:"-1000px",top:"-1000px"});for(o in s)t.style[o]=s[o];t.appendChild(h),i=r||document.documentElement,i.insertBefore(t,i.firstChild),h.style.cssText="position: absolute; left: 10.7432222px;",n=e(h).offset().left,a=n>10&&11>n,t.innerHTML="",i.removeChild(t)}()}(),e.ui.position,e.widget("ui.menu",{version:"1.11.4",defaultElement:"