BaseIntegration.php
2 weeks ago
IntegrationInterface.php
2 weeks ago
IntegrationManager.php
2 weeks ago
MemberPressIntegration.php
2 weeks ago
WooCommerceIntegration.php
2 weeks ago
WooCommerceIntegration.php
255 lines
| 1 | <?php |
| 2 | |
| 3 | namespace LLAR\Core\Integrations; |
| 4 | |
| 5 | if ( ! defined( 'ABSPATH' ) ) { |
| 6 | exit; |
| 7 | } |
| 8 | |
| 9 | class WooCommerceIntegration extends BaseIntegration { |
| 10 | |
| 11 | /** |
| 12 | * Get the name of the plugin this integration supports |
| 13 | * |
| 14 | * @return string |
| 15 | */ |
| 16 | public function get_plugin_name() { |
| 17 | return 'WooCommerce'; |
| 18 | } |
| 19 | |
| 20 | /** |
| 21 | * Check if WooCommerce plugin is active |
| 22 | * |
| 23 | * @return bool |
| 24 | */ |
| 25 | public static function is_plugin_active() { |
| 26 | return function_exists( 'is_account_page' ) && function_exists( 'wc_add_notice' ); |
| 27 | } |
| 28 | |
| 29 | /** |
| 30 | * Register all hooks and filters for WooCommerce |
| 31 | * |
| 32 | * @return void |
| 33 | */ |
| 34 | public function register_hooks() { |
| 35 | if ( ! static::is_plugin_active() ) { |
| 36 | return; |
| 37 | } |
| 38 | |
| 39 | // Add notices to woocommerce login page |
| 40 | add_action( 'wp_head', array( $this, 'add_wc_notices' ) ); |
| 41 | |
| 42 | // Protect WooCommerce registration |
| 43 | add_action( 'woocommerce_register_post', array( $this, 'wc_register_post_handler' ), 10, 3 ); |
| 44 | add_filter( 'woocommerce_registration_errors', array( $this, 'wc_registration_errors_handler' ), 10, 3 ); |
| 45 | } |
| 46 | |
| 47 | /** |
| 48 | * Check if this is WooCommerce login page |
| 49 | * |
| 50 | * @return bool |
| 51 | */ |
| 52 | public function is_login_page() { |
| 53 | // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Only checking for presence, not processing |
| 54 | return static::is_plugin_active() && is_account_page() && isset( $_POST['username'] ); |
| 55 | } |
| 56 | |
| 57 | /** |
| 58 | * Get login credentials from the request |
| 59 | * |
| 60 | * @return array|null |
| 61 | */ |
| 62 | public function get_login_credentials() { |
| 63 | // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Reading POST data for validation, nonce checked by WooCommerce |
| 64 | if ( ! isset( $_POST['username'] ) || ! isset( $_POST['password'] ) ) { |
| 65 | return null; |
| 66 | } |
| 67 | |
| 68 | return array( |
| 69 | // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Reading POST data for validation, nonce checked by WooCommerce |
| 70 | 'username' => sanitize_text_field( wp_unslash( $_POST['username'] ) ), |
| 71 | // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Reading POST data for validation, nonce checked by WooCommerce |
| 72 | 'password' => wp_unslash( $_POST['password'] ), // Password should not be sanitized, but needs wp_unslash() to remove magic quotes |
| 73 | ); |
| 74 | } |
| 75 | |
| 76 | /** |
| 77 | * Get login identifier for WooCommerce auth flow. |
| 78 | * |
| 79 | * @return string |
| 80 | */ |
| 81 | public function get_login_identifier() { |
| 82 | // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Read-only access to request data |
| 83 | if ( ! isset( $_REQUEST['username'] ) ) { |
| 84 | return ''; |
| 85 | } |
| 86 | |
| 87 | // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Read-only access to request data |
| 88 | return sanitize_text_field( wp_unslash( $_REQUEST['username'] ) ); |
| 89 | } |
| 90 | |
| 91 | /** |
| 92 | * Display error message on WooCommerce login page |
| 93 | * |
| 94 | * @param string $message Error message |
| 95 | * @return void |
| 96 | */ |
| 97 | public function display_error( $message ) { |
| 98 | if ( static::is_plugin_active() && is_account_page() ) { |
| 99 | wc_add_notice( $message, 'error' ); |
| 100 | } |
| 101 | } |
| 102 | |
| 103 | /** |
| 104 | * Check if this is WooCommerce registration page |
| 105 | * |
| 106 | * @return bool |
| 107 | */ |
| 108 | public function is_registration_page() { |
| 109 | // WooCommerce uses standard WordPress registration fields |
| 110 | // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Only checking for presence, not processing |
| 111 | $result = static::is_plugin_active() && is_account_page() && ( isset( $_POST['user_login'] ) || isset( $_POST['user_email'] ) ); |
| 112 | return $result; |
| 113 | } |
| 114 | |
| 115 | /** |
| 116 | * Get registration data from the request |
| 117 | * |
| 118 | * @return array|null |
| 119 | */ |
| 120 | public function get_registration_data() { |
| 121 | // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Reading POST data for validation, nonce checked by WooCommerce |
| 122 | if ( empty( $_POST['user_login'] ) && empty( $_POST['user_email'] ) ) { |
| 123 | return null; |
| 124 | } |
| 125 | |
| 126 | // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Reading POST data for validation, nonce checked by WooCommerce |
| 127 | $user_login = isset( $_POST['user_login'] ) ? sanitize_text_field( wp_unslash( $_POST['user_login'] ) ) : ''; |
| 128 | // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Reading POST data for validation, nonce checked by WooCommerce |
| 129 | // Note: sanitize_email() is used here for form data retrieval, but sanitize_user() is used in wc_register_post_handler() |
| 130 | // for API calls to match the original API behavior |
| 131 | $user_email = isset( $_POST['user_email'] ) ? sanitize_email( wp_unslash( $_POST['user_email'] ) ) : ''; |
| 132 | |
| 133 | // Only return if at least one field is present |
| 134 | if ( empty( $user_login ) && empty( $user_email ) ) { |
| 135 | return null; |
| 136 | } |
| 137 | |
| 138 | return array( |
| 139 | 'username' => $user_login, |
| 140 | 'email' => $user_email, |
| 141 | ); |
| 142 | } |
| 143 | |
| 144 | /** |
| 145 | * Display error message on WooCommerce registration page |
| 146 | * |
| 147 | * @param string $message Error message |
| 148 | * @return void |
| 149 | */ |
| 150 | public function display_registration_error( $message ) { |
| 151 | if ( static::is_plugin_active() && is_account_page() ) { |
| 152 | wc_add_notice( $message, 'error' ); |
| 153 | } |
| 154 | } |
| 155 | |
| 156 | /** |
| 157 | * Errors on WooCommerce account page |
| 158 | */ |
| 159 | public function add_wc_notices() { |
| 160 | global $limit_login_just_lockedout, $limit_login_nonempty_credentials, $limit_login_my_error_shown; |
| 161 | |
| 162 | if ( ! $limit_login_nonempty_credentials ) { |
| 163 | return; |
| 164 | } |
| 165 | |
| 166 | // Prevent duplicate error messages if already shown elsewhere |
| 167 | if ( ! empty( $limit_login_my_error_shown ) ) { |
| 168 | return; |
| 169 | } |
| 170 | |
| 171 | /* |
| 172 | * During lockout we do not want to show any other error messages (like |
| 173 | * unknown user or empty password). |
| 174 | */ |
| 175 | // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Only checking POST for display logic, not processing |
| 176 | if ( empty( $_POST ) && ! $this->is_login_allowed() && ! $limit_login_just_lockedout ) { |
| 177 | if ( is_account_page() ) { |
| 178 | wc_add_notice( $this->get_error_message(), 'error' ); |
| 179 | // Mark error as shown to prevent duplicate messages |
| 180 | $limit_login_my_error_shown = true; |
| 181 | } |
| 182 | } |
| 183 | } |
| 184 | |
| 185 | /** |
| 186 | * For WooCommerce registration |
| 187 | * Check registration attempt before WooCommerce processes it |
| 188 | * |
| 189 | * @param string $username Username |
| 190 | * @param string $user_email User email |
| 191 | * @param WP_Error $errors Error object |
| 192 | * @return void |
| 193 | */ |
| 194 | public function wc_register_post_handler( $username, $user_email, $errors ) { |
| 195 | if ( ! $this->is_registration_limited() ) { |
| 196 | return; |
| 197 | } |
| 198 | |
| 199 | if ( empty( $username ) && empty( $user_email ) ) { |
| 200 | return; |
| 201 | } |
| 202 | |
| 203 | // Exit only if BOTH fields are invalid (empty or invalid) |
| 204 | // Continue if at least one field is valid |
| 205 | // Logic: exit if (username is invalid) AND (email is invalid) |
| 206 | $username_invalid = empty( $username ) || ! validate_username( $username ); |
| 207 | $email_invalid = empty( $user_email ) || ! is_email( $user_email ); |
| 208 | if ( $username_invalid && $email_invalid ) { |
| 209 | return; |
| 210 | } |
| 211 | |
| 212 | // Use sanitize_user() for username and sanitize_email() for email to match original API behavior |
| 213 | // This matches the behavior in llar_submit_login_form_register() |
| 214 | $user_login_sanitize = sanitize_user( $username ); |
| 215 | $user_email_sanitize = sanitize_email( $user_email ); |
| 216 | |
| 217 | // Check any non-empty |
| 218 | $check_combo = ! empty( $user_login_sanitize ) ? $user_login_sanitize : $user_email_sanitize; |
| 219 | |
| 220 | $response = $this->check_registration_api( $check_combo ); |
| 221 | |
| 222 | // If $user_login is not empty, we will also check $user_email |
| 223 | if ( ! empty( $user_login_sanitize ) && 'deny' !== $response['result'] ) { |
| 224 | if ( empty( $user_email ) || ! is_email( $user_email ) ) { |
| 225 | return; |
| 226 | } |
| 227 | |
| 228 | $response = $this->check_registration_api( $user_email_sanitize ); |
| 229 | } |
| 230 | |
| 231 | if ( 'deny' === $response['result'] ) { |
| 232 | // Set the marker and the error |
| 233 | $this->llar_instance->user_blocking = true; |
| 234 | $this->llar_instance->error_messages = __( 'Registration is currently disabled.', 'limit-login-attempts-reloaded' ); |
| 235 | } |
| 236 | } |
| 237 | |
| 238 | /** |
| 239 | * Correcting errors in the presence of a registration prohibition marker for WooCommerce |
| 240 | * |
| 241 | * @param WP_Error $errors Error object |
| 242 | * @param string $username Username |
| 243 | * @param string $user_email User email |
| 244 | * @return WP_Error |
| 245 | */ |
| 246 | public function wc_registration_errors_handler( $errors, $username, $user_email ) { |
| 247 | // Checking the marker |
| 248 | if ( $this->llar_instance->user_blocking ) { |
| 249 | $errors->add( 'user_blocking', $this->llar_instance->error_messages ); |
| 250 | } |
| 251 | |
| 252 | return $errors; |
| 253 | } |
| 254 | } |
| 255 |