diff --git a/.gitattributes b/.gitattributes
index dfe0770..c6b5b2f 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1,2 +1,17 @@
-# Auto detect text files and perform LF normalization
+# Auto-normalize line endings
* text=auto
+
+# Force text files to LF
+*.php text eol=lf
+*.js text eol=lf
+*.css text eol=lf
+*.md text eol=lf
+*.txt text eol=lf
+*.json text eol=lf
+
+# Binaries
+*.png binary
+*.jpg binary
+*.jpeg binary
+*.gif binary
+*.ico binary
diff --git a/dapper.php b/dapper.php
index ebd1cab..bb0d14c 100644
--- a/dapper.php
+++ b/dapper.php
@@ -38,7 +38,7 @@ function dapper_activation() {
foreach ($existing_users as $user) {
update_mailing_list($user->ID, $user->user_email, 'subscribed');
}
- make_images_dir();
+ //make_images_dir();
make_backup_dir();
// Mark setup completed
update_option('dapper_setup_complete', true);
@@ -47,6 +47,7 @@ function dapper_activation() {
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
@@ -581,6 +582,31 @@ function dapper_woo_conditional_load() {
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
// ===================
@@ -650,7 +676,12 @@ function dapper_woo_conditional_load() {
add_action('woocommerce_checkout_before_customer_details', 'dapper_add_custom_human_check');
function dapper_add_custom_human_check() {
- if (get_option('dapper_enable_paypal_human_check', 'on') !== 'on') return;
+ if (get_option('dapper_enable_paypal_human_check', 'on') !== 'on') {
+ return;
+ }
+ if ( ! dapper_is_paypal_payment_method() && ! is_checkout() ) {
+ return;
+ }
?>
@@ -663,62 +694,364 @@ function dapper_woo_conditional_load() {
+ // Function to show/hide based on current selected method
+ function updateHumanCheckVisibility() {
+ const selectedRadio = document.querySelector('input[name="payment_method"]:checked');
+ if (selectedRadio && paypalMethods.includes(selectedRadio.value)) {
+ checkDiv.style.display = 'block';
+ } else {
+ checkDiv.style.display = 'none';
+ }
+ }
+
+ // Run immediately on load
+ updateHumanCheckVisibility();
+
+ // Listen for changes on payment radios
+ document.querySelectorAll('input[name="payment_method"]').forEach(radio => {
+ radio.addEventListener('change', updateHumanCheckVisibility);
+ });
+
+ // Watch for dynamic payment section updates (WooCommerce often reloads parts via AJAX)
+ const paymentBox = document.querySelector('#payment') || document.body;
+ const observer = new MutationObserver(updateHumanCheckVisibility);
+ observer.observe(paymentBox, { childList: true, subtree: true });
+
+ // Token generation
+ const checkbox = document.getElementById('dapper_human_checkbox');
+ if (checkbox) {
+ checkbox.addEventListener('change', function() {
+ const tokenField = document.getElementById('dapper_human_token');
+ tokenField.value = this.checked
+ ? 'human_' + Math.random().toString(36).substring(2) + '_' + Date.now()
+ : '';
+ });
+ }
+ });
+
add('human_check_error', __('Please verify you are human to use PayPal.', 'dapper'));
- return;
+ $errors->add('human_check_error', __('Please check the "I\'m not a robot" box to continue with PayPal.', 'dapper'));
+ return;
}
- // Must be checked within 5 minutes
if (time() - $time > 300) {
- $errors->add('human_check_error', __('Verification timed out. Please try again.', 'dapper'));
- return;
+ $errors->add('human_check_error', __('Verification timed out. Please refresh and try again.', 'dapper'));
+ return;
}
- // Optional: token must start with 'human_' and be random-ish
if (strpos($token, 'human_') !== 0 || strlen($token) < 20) {
- $errors->add('human_check_error', __('Invalid verification. Please try again.', 'dapper'));
+ $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");
+ }
+ }
+ }
+
}