ID, $user->user_email, 'subscribed'); } //make_images_dir(); make_backup_dir(); // Mark setup completed update_option('dapper_setup_complete', true); } } register_activation_hook(__FILE__, 'dapper_activation'); /* // Depreciated in v1.1.1 to be removed in later versions // Checks for an images directory inside the dapper plugin // Creates the 'images' folder when plugin gets activated // Used for custom logos on login page */ function make_images_dir() { $dapper_root = plugin_dir_path(__FILE__); $image_dir = $dapper_root . '/images'; if (!file_exists($image_dir)){ wp_mkdir_p($image_dir); } } /* // Adds users to the dapper_mailing _list initially // Also manages the mailing list // Has three required arguments // @param $user_id integer id of user in mailing list // @param $email string email of user // @param $sub_status string 'subscribed' or 'unsubscribed' */ function update_mailing_list($user_id, $email, $sub_status) { global $wpdb; $table_name = $wpdb->prefix . 'dapper_mailing_list'; // Check if the user is already in the mailing list $existing_user = $wpdb->get_row($wpdb->prepare("SELECT * FROM $table_name WHERE user_id = %d", $user_id)); if (!$existing_user) { // If the user is not in the list, insert the new record $wpdb->insert( $table_name, array( 'user_id' => $user_id, 'email' => $email, 'subscription_status' => $sub_status, ), array('%d', '%s', '%s') ); } else { // If the user is already in the list, update the subscription status $wpdb->update( $table_name, array('subscription_status' => $sub_status), array('user_id' => $user_id), array('%s'), array('%d') ); } } /* // Called during intial run as part of the setup process // Generates the database table for the mailing list */ function create_mailing_list_table() { global $wpdb; $table_name = $wpdb->prefix . 'dapper_mailing_list'; $charset_collate = $wpdb->get_charset_collate(); $sql = "CREATE TABLE $table_name ( id mediumint(9) NOT NULL AUTO_INCREMENT, user_id mediumint(9) NOT NULL, email varchar(255) NOT NULL, subscription_status varchar(20) NOT NULL, PRIMARY KEY (id) ) $charset_collate;"; require_once ABSPATH . 'wp-admin/includes/upgrade.php'; dbDelta($sql); } /* // Get the total number of mailing list users // Returns an Integer */ function get_mailing_list_users() { global $wpdb; $table_name = $wpdb->prefix . 'dapper_mailing_list'; // Assuming your table has a WordPress prefix // Fetch users from the mailing list table $query = "SELECT * FROM $table_name"; $results = $wpdb->get_results($query); return $results; } /* // Removes a user from the dapper mailing list // Called from unsubscribe links asking for removal // Called when a user is manually removed from the mailing list // @param $user_id integer id of the passed in user required */ function remove_user_from_mailing_list($user_id) { global $wpdb; $table_name = $wpdb->prefix . 'dapper_mailing_list'; // Remove the user from the mailing list $wpdb->delete($table_name, array('user_id' => $user_id)); } // Create Email Template post type // Todo: Should probably move to some sort of init plugin function function create_email_template_post_type() { $labels = array( 'name' => __('Dapper'), 'singular_name' => __('Dapper'), 'add_new' => __('Add New Template'), 'add_new_item' => __('Add New Email Template'), 'edit_item' => __('Edit Email Template'), 'new_item' => __('New Email Template'), 'view_item' => __('View Email Template'), 'view_items' => __('View Email Templates'), 'search_items' => __('Search Email Templates'), 'not_found' => __('No Email Templates found'), 'not_found_in_trash' => __('No Email Templates found in Trash'), 'parent_item_colon' => '', 'all_items' => __('All Email Templates'), 'archives' => __('Email Template Archives'), 'attributes' => __('Email Template Attributes'), 'insert_into_item' => __('Insert into email template'), 'uploaded_to_this_item' => __('Uploaded to this email template'), 'featured_image' => _x('Featured Image', 'email template'), 'set_featured_image' => _x('Set featured image', 'email template'), 'remove_featured_image' => _x('Remove featured image', 'email template'), 'use_featured_image' => _x('Use as featured image', 'email template'), 'menu_name' => __('Dapper'), 'filter_items_list' => __('Filter email templates list'), 'items_list_navigation' => __('Email Templates list navigation'), 'items_list' => __('Email Templates list'), 'item_published' => __('Email Template published'), 'item_published_privately' => __('Email Template published privately'), 'item_reverted_to_draft' => __('Email Template reverted to draft'), 'item_scheduled' => __('Email Template scheduled'), 'item_updated' => __('Email Template updated'), ); $args = array( 'labels' => $labels, 'public' => true, 'has_archive' => true, 'supports' => array('title', 'editor'), 'menu_icon' => 'dashicons-email-alt', ); register_post_type('email_template', $args); } add_action('init', 'create_email_template_post_type'); // Create Campaign post type // Todo: Should most likly be in some sort of init plugin function function create_campaign_post_type() { register_post_type('email_campaign', array( 'labels' => array( 'name' => __('Email Campaigns'), 'singular_name' => __('Email Campaign') ), 'public' => true, 'has_archive' => true, 'supports' => array('title', 'editor'), 'show_in_menu' => false, ) ); } add_action('init', 'create_campaign_post_type'); // Useful for sending out daily newsletters function get_latest_email_template_id() { // Query to get the latest email template post $args = array( 'post_type' => 'email_template', 'posts_per_page' => 1, 'order' => 'DESC', 'orderby' => 'date', ); $template_query = new WP_Query($args); if ($template_query->have_posts()) { $template_query->the_post(); return get_the_ID(); // Return the ID of the latest email template post } return 0; // Return 0 if no template is found } /* // Actual email sending function calls wp_mail() // Requires three arguments: // @param string $to; the email recipient // @param string $subject; what the email is about // @param string $message; the body of the message to be sent can be html with embedded php. // Requires a working email server in conjuntion with webserver */ function send_custom_email($to, $subject, $message) { //$headers = array('Content-Type: text/html; charset=UTF-8'); // Additional headers if needed $headers = get_option('dapper_headers', ''); // Send the email wp_mail($to, $subject, $message, $headers); } // Define WooCommerce order statuses $order_statuses = array( 'completed' => 'completed', 'shipped' => 'shipped', 'delivered' => 'delivered', 'pending_payment' => 'pending', 'failed' => 'failed', 'draft' => 'checkout-draft', 'cancelled' => 'cancelled', 'refunded' => 'refunded', 'processing' => 'processing', 'on_hold' => 'on-hold', 'partial_shipped' => 'partial-shipped' // Add more statuses as needed ); function get_possible_order_statuses() { $order_statuses = array( 'wc-pending' => _x( 'Pending payment', 'Order status', 'woocommerce' ), 'wc-processing' => _x( 'Processing', 'Order status', 'woocommerce' ), 'wc-on-hold' => _x( 'On hold', 'Order status', 'woocommerce' ), 'wc-completed' => _x( 'Completed', 'Order status', 'woocommerce' ), 'wc-cancelled' => _x( 'Cancelled', 'Order status', 'woocommerce' ), 'wc-refunded' => _x( 'Refunded', 'Order status', 'woocommerce' ), 'wc-failed' => _x( 'Failed', 'Order status', 'woocommerce' ), ); return $order_statuses; } /** * Conditionally load WooCommerce-dependent features. Modulized use. */ function dapper_woo_conditional_load() { // Only proceed if WooCommerce exists AND toggle is enabled if ( ! class_exists( 'WooCommerce' ) || get_option( 'dapper_enable_woo_integration', 'on' ) !== 'on' ) { return; } // Called by the WooCommerce order delivered webhook when an order is marked delivered // Useful for sending out review links // Todo: make review template and set this function up for that use. function send_custom_email_on_order_completion($order_id) { // Get the order object $order = wc_get_order($order_id); // Get the customer email from the order $to = $order->get_billing_email(); // Get the name of the email template controlled in settings $template_name = get_option('dapper_woo_status_delivered', ''); // Get the email template content $message = get_email_template_content_by_name($template_name); // Replace placeholders with actual data $message = str_replace('[CustomerName]', $order->get_billing_first_name(), $message); $message = str_replace('[OrderNumber]', $order->get_order_number(), $message); // Get product names, quantities, and order total $product_info = array(); $total_quantity = 0; foreach ( $order->get_items() as $item_id => $item ) { $product = $item->get_product(); $quantity = $item->get_quantity(); $total_quantity += $quantity; // Guard against deleted/missing products if ( $product && is_object( $product ) && method_exists( $product, 'get_name' ) ) { $product_name = $product->get_name(); $original_product_slug = $product->get_slug(); $product_info[] = "$product_name (Qty: $quantity)"; // Slug cleanup and review link only if product exists $product_slug = preg_replace( '/-(s|m|l|xl|2xl|3xl|4xl|5xl)$/i', '', $original_product_slug ); $review_link = get_option( 'dapper_review_link_structure', '' ); $review_link .= "/$product_slug/#reviews"; $product_review_link = $review_link; $message = str_replace( "[ReviewLink_0]", $product_review_link, $message ); } else { // Fallback for missing product — still count quantity, use generic name $product_info[] = "Unknown Product (Qty: $quantity)"; dapper_debug_log( "Missing/deleted product in order #$order_id, item $item_id" ); // Note: No review link added for this item } } // Get the numeric order total without HTML or currency symbols $order_total_numeric = get_order_total_numeric($order_id); // Replace [ProductName], [Quantity], [OrderTotal] with actual data $message = str_replace('[ProductName]', implode(', ', $product_info), $message); $message = str_replace('[Quantity]', $total_quantity, $message); $message = str_replace('[OrderTotal]', $order_total_numeric, $message); // Replace [ReviewLink_*] placeholders with actual review links in your email template $message = preg_replace('/\[ReviewLink_(\d+)\]/', '[ReviewLink_$1]', $message); // Add more replacements as needed // Check if the email and template content exist if ($to && $message) { $subject = 'Order Delivered'; // Send the email send_custom_email($to, $subject, $message); } } /* Called by WooCommerce order status changed webhook callback when an order is marked shipped // Useful for sending the tracking info to the customer requires // Advanced Shipment Tracking for WooCommerce plugin otherwise tracking is null */ function send_custom_email_on_order_shipped($order_id) { // Get the order object $order = wc_get_order($order_id); // Get the customer email from the order $to = $order->get_billing_email(); // Get the name of the email template controlled in settings $template_name = get_option('dapper_woo_status_shipped', ''); // Get the email template content $message = get_email_template_content_by_name($template_name); // Replace placeholders with actual data $message = str_replace('[CustomerName]', $order->get_billing_first_name(), $message); $message = str_replace('[OrderNumber]', $order->get_order_number(), $message); // Get product names, quantities, and order total $product_info = array(); $total_quantity = 0; foreach ( $order->get_items() as $item_id => $item ) { $product = $item->get_product(); $quantity = $item->get_quantity(); $total_quantity += $quantity; if ( $product && is_object( $product ) && method_exists( $product, 'get_name' ) ) { $product_name = $product->get_name(); $product_info[] = "$product_name (Qty: $quantity)"; } else { $product_info[] = "Unknown Product (Qty: $quantity)"; dapper_debug_log( "Missing/deleted product in order #$order_id, item $item_id" ); } } // Get the numeric order total without HTML or currency symbols $order_total_numeric = get_order_total_numeric($order_id); // Replace [ProductName], [Quantity], [OrderTotal] with actual data $message = str_replace('[ProductName]', implode(', ', $product_info), $message); $message = str_replace('[Quantity]', $total_quantity, $message); $message = str_replace('[OrderTotal]', $order_total_numeric, $message); $order_notes = $order->get_customer_order_notes(); // Check if function exist if ( function_exists( 'ast_get_tracking_items' ) ) { $tracking_items = ast_get_tracking_items($order_id); foreach($tracking_items as $tracking_item){ $tracking_number = $tracking_item['tracking_number']; $tracking_provider = $tracking_item['formatted_tracking_provider']; $tracking_link = $tracking_item['formatted_tracking_link']; $date_shipped = date_i18n( get_option( 'date_format' ), $tracking_item['date_shipped'] ); if (!$tracking_number) { dapper_debug_log('Tracking number is blank/null/empty'); } if ($tracking_number) { dapper_debug_log('Tracking number is:' . $tracking_number); $message = str_replace('[TrackingNumber]', $tracking_number, $message); $message = str_replace('[TrackingLink]', $tracking_link, $message); } } } else { $message = str_replace('[TrackingNumber]', '', $message); $message = str_replace('[TrackingLink]', '', $message); } // Check if the email and template content exist if ($to && $message) { $subject = 'Order Shipped'; // Send the email send_custom_email($to, $subject, $message); } } ; /* // WooCommerce Order Status Changed Webhook Callback function // Handles the switch betweent different order statuses // Has three required arguments // @param $order_id integer the passed in Order // @param $old_status string the passed in old order status // @param $new_status string the passed in new order status */ function handle_woocommerce_order_status_changed($order_id, $old_status, $new_status) { global $order_statuses; // Debugging statements dapper_debug_log('New Status: ' . $new_status); dapper_debug_log('Order Statuses: ' . print_r($order_statuses, true)); dapper_debug_log( "Order status changed: Order #$order_id from '$old_status' to '$new_status'" ); // Check if the new status is in our defined statuses if (in_array($new_status, $order_statuses)) { // Perform actions based on the order status switch ($new_status) { case $order_statuses['delivered']: send_custom_email_on_order_completion($order_id); dapper_debug_log('Case 1: Delivered'); break; case $order_statuses['completed']: send_custom_email_on_order_shipped($order_id); dapper_debug_log('Case 2: Shipped(which is completed status actually)'); break; case $order_statuses['pending_payment']: dapper_debug_log('Case 3: Pending Payment'); break; case $order_statuses['processing']: dapper_debug_log('Case 4: Processing'); break; case $order_statuses['on_hold']: dapper_debug_log('Case 5: On Hold'); break; case $order_statuses['partial_shipped']: dapper_debug_log('Case 6: Partially Shipped'); break; case $order_statuses['cancelled']: dapper_debug_log('Case 7: Cancelled'); break; case $order_statuses['refunded']: dapper_debug_log('Case 8: Refunded'); break; case $order_statuses['failed']: dapper_debug_log('Case 9: Failed'); break; case $order_statuses['draft']: dapper_debug_log('Case 10: Draft'); break; default: dapper_debug_log('Unknown Status: ' . $new_status); // Add more cases for other statuses if needed } } } // Hook the status changed action add_action( 'woocommerce_order_status_changed', 'handle_woocommerce_order_status_changed', 10, 3 ); // Honeypot – only load if Woo + toggle on add_action( 'woocommerce_register_form_start', 'advanced_add_honeypots' ); add_filter( 'woocommerce_registration_errors', 'advanced_validate_registration', 10, 3 ); // Define the honeypot functions inside too (or keep them global if you prefer) function advanced_add_honeypots() { $random_name = 'hp_' . substr(str_shuffle('abcdefghijklmnopqrstuvwxyz'), 0, 8); // Random field name ?>

$value) { if (strpos($key, 'hp_') === 0 && !empty($value)) { $errors->add('honeypot_error', __('Spam detected. Registration blocked.', 'woocommerce')); return $errors; } } // Existing timestamp check... if (isset($_POST['form_timestamp']) && (time() - intval($_POST['form_timestamp']) < 5)) { $errors->add('timestamp_error', __('Submission too fast. Humans only.', 'woocommerce')); } // === NEW ENHANCED EMAIL PATTERN BLOCK === // Target common bot patterns: pure alphanumeric usernames 8+ chars, no dots/hyphens/underscores/numbers mixed naturally $email_lower = strtolower($email); $local_part = substr($email, 0, strpos($email, '@')); // List of domains the bots are currently using $suspicious_domains = array('hotmail.com', 'outlook.com', 'protonmail.com', 'gmail.com', 'yahoo.com'); // Add more if they switch $domain = substr(strrchr($email_lower, "@"), 1); if (in_array($domain, $suspicious_domains)) { // Pattern: only letters/numbers, 8+ characters, NO dots, hyphens, underscores, or other separators if (preg_match('/^[a-zA-Z0-9]{8,}$/', $local_part) && !str_contains($local_part, '.') && !str_contains($local_part, '-') && !str_contains($local_part, '_')) { $errors->add('email_pattern_error', __('Invalid email address. Please use a real, personal email.', 'woocommerce')); return $errors; // Early exit once blocked } } // === END NEW BLOCK === return $errors; } /** * Returns true if the current posted payment method is any known PayPal variant * * */ function dapper_is_paypal_payment_method() { if (!isset($_POST['payment_method'])) { return false; } $method = $_POST['payment_method']; $paypal_methods = [ 'paypal', 'ppec_paypal', // older PayPal Express Checkout 'ppcp-gateway', // PayPal Payments (most common now) 'paypal_express', 'braintree_paypal', // if using Braintree integration // add more here if you ever see other variants in logs ]; return in_array($method, $paypal_methods, true); } // =================== // CHECKOUT HONEYPOT + ANTI-BOT LAYERS // =================== // Add hidden fields to checkout form add_action('woocommerce_checkout_before_customer_details', 'dapper_checkout_honeypot_fields'); function dapper_checkout_honeypot_fields() { // Hidden honeypot field — bots tend to fill all inputs $honeypot_name = 'dapper_hp_' . wp_generate_password(8, false); // random per load ?>
$value) { if (strpos($key, 'dapper_hp_') === 0 && !empty(trim($value))) { $errors->add('dapper_honeypot_error', __('Sorry, we detected automated behavior. Please try again.', 'dapper')); return; } } // JS check: add tiny JS that sets the field (bots often ignore add('human_check_error', __('Please check the "I\'m not a robot" box to continue with PayPal.', 'dapper')); return; } if (time() - $time > 300) { $errors->add('human_check_error', __('Verification timed out. Please refresh and try again.', 'dapper')); return; } if (strpos($token, 'human_') !== 0 || strlen($token) < 20) { $errors->add('human_check_error', __('Invalid verification. Please try again.', 'dapper')); } } // 1. Checkbox on SINGLE PRODUCT pages (near PayPal button) add_action('woocommerce_paypal_payments_single_product_button', 'dapper_human_checkbox_product', 5); // Product page checkbox - use core Woo hook + JS to force show near Add to Cart / PayPal area add_action('woocommerce_after_add_to_cart_button', 'dapper_human_checkbox_product', 999); // High priority = late output function dapper_human_checkbox_product() { dapper_debug_log('Universal product checkbox output attempt - Product ID: ' . get_the_ID()); if (get_option('dapper_enable_paypal_human_check', 'on') !== 'on') { return; } global $product; if (!$product || !$product->is_purchasable()) return; ?>
Required: Human Verification for PayPal Express

This prevents automated spam. Takes 2 seconds.

Human Verification Required for PayPal Express

This quick check helps stop automated spam. Takes 2 seconds.

get_payment_method(); if (!in_array($method, ['ppcp-gateway', 'paypal', 'ppec_paypal', 'paypal_express'], true)) { return; } // Check token from product or cart (whichever was used) $token = trim($_POST['dapper_human_token_product'] ?? $_POST['dapper_human_token_cart'] ?? ''); $time = (int) ($_POST['dapper_human_time_product'] ?? $_POST['dapper_human_time_cart'] ?? 0); $token_ok = !empty($token) && strpos($token, 'human_') === 0 && strlen($token) >= 20 && (time() - $time <= 600); // 10 min window // If token is missing/invalid → check other bot signs if (!$token_ok) { $first = strtolower(trim($order->get_billing_first_name() ?: '')); $last = strtolower(trim($order->get_billing_last_name() ?: '')); $company = strtolower(trim($order->get_billing_company() ?: '')); $lowercase_name = ($first === $order->get_billing_first_name() && $last === $order->get_billing_last_name()); $suspicious_company = in_array($company, ['pogab', 'rayazifi', 'lunom', 'topap', 'potanginamo', '']) || preg_match('/^[a-z]{5,10}$/', $company); if ($lowercase_name || $suspicious_company || (float)$order->get_total_tax() === 0) { $order->update_status('cancelled', 'Blocked: Invalid or missing human verification for PayPal Express (bot pattern detected).'); dapper_debug_log("Blocked fake PayPal order #$order_id - No valid token | Name: $first $last | Company: $company"); } } } } add_action( 'plugins_loaded', 'dapper_woo_conditional_load' ); // Late hook – safe for class_exists() function add_campaign_management_page() { add_submenu_page( 'edit.php?post_type=email_template', // Parent menu slug 'Campaigns', // Page title 'Campaigns', // Menu title 'manage_options', // Capability required 'email-campaigns', // Page slug 'render_campaign_management_page' // Callback function to render the page ); } add_action('admin_menu', 'add_campaign_management_page'); function render_campaign_management_page() { ?>

Email Campaigns

Add New Campaign
prefix . 'dapper_mailing_list'; // Update the subscription status $wpdb->update( $table_name, array('subscription_status' => $new_status), array('user_id' => $user_id) ); } /* // Displays the Mailing List users on the setting page // Only one call */ function display_subscribed_users() { if ( ! current_user_can('manage_options') ) { wp_die( __('Sorry, you are not allowed to manage this.', 'dapper') ); } // ------------------- ADD THIS SECURITY CHECK ------------------- // Only process if it's a POST from our form if ( $_SERVER['REQUEST_METHOD'] === 'POST' ) { // This checks the nonce AND dies with error if invalid/missing check_admin_referer( 'dapper_subscription_action', 'dapper_subscription_nonce' ); // Now it's safe to process if (isset($_POST['update_subscription_status'])) { $user_id = intval($_POST['user_id']); $new_status = sanitize_text_field($_POST['new_status']); update_subscription_status($user_id, $new_status); } if (isset($_POST['remove_user_from_list'])) { $user_id = intval($_POST['user_id']); remove_user_from_mailing_list($user_id); } } // Retrieve mailing list users $mailing_list_users = get_mailing_list_users(); // Display users in HTML echo '

Mailing List Users

'; echo ''; echo ''; foreach ($mailing_list_users as $user) { echo ''; echo ''; echo ''; echo ''; echo ''; } echo '
EmailStatusAction
' . esc_html($user->email) . '' . esc_html($user->subscription_status) . ''; echo '
'; echo wp_nonce_field( 'dapper_subscription_action', 'dapper_subscription_nonce'); echo ''; echo ''; echo ''; echo ''; echo '
'; echo '
'; } function dapper_settings_page() { add_submenu_page( 'edit.php?post_type=email_template', 'Dapper Settings', 'Settings', 'manage_options', 'dapper-settings', 'dapper_settings_page_content' ); } function dapper_settings_page_content() { dapper_debug_log('settings page'); ?>

Dapper Settings

Debug Mode

Debug Mode adds entries to the webserver error log file.

> >

Shows a quick "I'm not a robot" checkbox when PayPal is selected. Helps block bots without third-party services.

Custom Admin Panel Login Logo

Toggles to enable the custom logo on the admin panel login.

>

Image files need to be formated for 120 pixels x 120 pixels

I Love Lana

'; } else { // Show a placeholder image when the custom logo is not set echo 'Generic Image'; } ?>

WooCommerce Integration

Enable automatic order status emails, tracking notifications, and registration anti-spam honeypot. Disable if not using WooCommerce.

>

Email Header

Example: From: Your Name <youremail@example.com>
Content-Type: text/html Reply-to: Your Name

Review Link Structure

Example: https://www.example.com/products

Order Status Delivered

Enter your template for WooCommerce Order Status Delivered Leave blank to disable

Order Status Shipped

Enter your template for WooCommerce Order Status Shipped Leave blank to disable

Order Status Partially Shipped

Enter your template for WooCommerce Order Status Partially Shipped Leave blank to disable

Order Status Pending Payment

Enter your template for WooCommerce Order Status Pending Payment Leave blank to disable

Order Status Processing

Enter your template for WooCommerce Order Status Processing Leave blank to disable

Order Status Failed

Enter your template for WooCommerce Order Status Failed Leave blank to disable

Order Status Draft

Enter your template for WooCommerce Order Status Draft Leave blank to disable

Order Status Refunded

Enter your template for WooCommerce Order Status Refunded Leave blank to disable

Order Status Cancelled

Enter your template for WooCommerce Order Status Cancelled Leave blank to disable

Order Status On Hold

Enter your template for WooCommerce Order Status On Hold Leave blank to disable

Backup created successfully! Refresh to see new files below.

'; } elseif ($_GET['backup'] === 'failed') { echo '

Backup failed — check debug log. Try unchecking some folders if memory is low.

'; } } ?>

Backup Settings

Configure what to include in backups. Uncheck large folders if you have memory limits.



Creates database export + selected folders. May take time on large sites.

Backup list function not available. Check if dapper_backup.php loaded correctly (syntax error?).

'; } ?>
prefix . 'dapper_mailing_list'; $where = ''; if (!empty($search)) { $where = "WHERE email LIKE '%$search%'"; } $sql = "SELECT * FROM $table_name $where LIMIT $per_page OFFSET $offset"; $users = $wpdb->get_results($sql); return $users; } /* // Register plugin settings through wordpress method register_setting */ function dapper_register_settings() { register_setting('dapper-settings-group', 'dapper_option'); register_setting('dapper-email-settings-group', 'dapper_headers'); register_setting('dapper-email-settings-group', 'dapper_review_link_structure'); register_setting('dapper-email-settings-group', 'dapper_woo_status_delivered'); register_setting('dapper-email-settings-group', 'dapper_woo_status_shipped'); register_setting('dapper-email-settings-group', 'dapper_woo_status_partial_shipped'); register_setting('dapper-email-settings-group', 'dapper_woo_status_processing'); register_setting('dapper-email-settings-group', 'dapper_woo_status_failed'); register_setting('dapper-email-settings-group', 'dapper_woo_status_draft'); register_setting('dapper-email-settings-group', 'dapper_woo_status_refunded'); register_setting('dapper-email-settings-group', 'dapper_woo_status_cancelled'); register_setting('dapper-email-settings-group', 'dapper_woo_status_on_hold'); register_setting('dapper-email-settings-group', 'dapper_woo_status_pending_payment'); register_setting('dapper-settings-group', 'dapper_enable_debug'); register_setting('dapper-settings-group', 'dapper_admin_panel_custom_logo_path'); register_setting('dapper-settings-group', 'dapper_admin_panel_custom_logo_enable'); register_setting('dapper-settings-group', 'dapper_setup_complete'); register_setting('dapper-settings-group', 'dapper_enable_backup'); register_setting('dapper-backup-group', 'dapper_enable_backup'); register_setting('dapper-settings-group', 'dapper_enable_woo_integration'); register_setting('dapper-backup-group', 'dapper_backup_include_media'); register_setting('dapper-backup-group', 'dapper_backup_themes'); register_setting('dapper-backup-group', 'dapper_backup_plugins'); register_setting('dapper-backup-group', 'dapper_backup_include_media'); register_setting('dapper-settings-group', 'dapper_enable_paypal_human_check'); // Add other settings as needed } add_action('admin_init', 'dapper_register_settings'); /* // Debug wrapper to add Dapper Debug to the front of all debuging messages // Call this instead of directly calling error_log // @param $message string of passed in message required */ function dapper_debug_log($message) { if (get_option('dapper_enable_debug', 0) == 'on') { error_log('[Dapper Debug] ' . $message); } } /* // Utility function used to get contents of an email template // to then swap out place holder data with real data // @param $template_name string name of passed in email template required // Returns an empty string if the passed in email template doesn't exist */ function get_email_template_content_by_name($template_name) { $template_post = get_page_by_title($template_name, OBJECT, 'email_template'); if ($template_post) { // Use 'post_content' to get the HTML content of the post return $template_post->post_content; } dapper_debug_log( "No email template found with title: " . $template_name ); return ''; // Return an empty string if the template is not found } /* // Retrieves the order total in Numeric value only // @param $order_id integer of passed in order id required // Returns 0 if $order_id is null */ function get_order_total_numeric($order_id) { if (! class_exists('WooCommerce')){ return 0; } $order = wc_get_order($order_id); return $order ? (float) $order->get_total() : 0; } /* // Persistent Object Cache clearing on update to prevent a race condition // @param $option passed in string from hook */ function dapper_clear_alloptions_cache($option) { if ( ! wp_installing() ) { $alloptions = wp_load_alloptions(); if ( isset( $alloptions[ $option ] ) ) { wp_cache_delete( 'alloptions', 'options' ); } } } add_action( 'added_option', 'dapper_clear_alloptions_cache' ); add_action( 'updated_option', 'dapper_clear_alloptions_cache' ); add_action( 'deleted_option', 'dapper_clear_alloptions_cache' ); /* // Customizing the login form on the admin panel // place your custom logo in your active theme folder inside a folder // named "images" and on the Dapper pluging settings page enter // the logo image path */ function dapper_login_logo() { if (get_option('dapper_admin_panel_custom_logo_enable') === 'on') { ?> 'dapper-settings', 'backup' => 'success', ), admin_url('admin.php') ); } else { $redirect = add_query_arg( array( 'page' => 'dapper-settings', 'backup' => 'failed', ), admin_url('admin.php') ); } wp_safe_redirect($redirect); exit; }