296 |
300 |
297 return $user; |
301 return $user; |
298 } |
302 } |
299 |
303 |
300 /** |
304 /** |
|
305 * Authenticates the user using an application password. |
|
306 * |
|
307 * @since 5.6.0 |
|
308 * |
|
309 * @param WP_User|WP_Error|null $input_user WP_User or WP_Error object if a previous |
|
310 * callback failed authentication. |
|
311 * @param string $username Username for authentication. |
|
312 * @param string $password Password for authentication. |
|
313 * @return WP_User|WP_Error|null WP_User on success, WP_Error on failure, null if |
|
314 * null is passed in and this isn't an API request. |
|
315 */ |
|
316 function wp_authenticate_application_password( $input_user, $username, $password ) { |
|
317 if ( $input_user instanceof WP_User ) { |
|
318 return $input_user; |
|
319 } |
|
320 |
|
321 if ( ! WP_Application_Passwords::is_in_use() ) { |
|
322 return $input_user; |
|
323 } |
|
324 |
|
325 $is_api_request = ( ( defined( 'XMLRPC_REQUEST' ) && XMLRPC_REQUEST ) || ( defined( 'REST_REQUEST' ) && REST_REQUEST ) ); |
|
326 |
|
327 /** |
|
328 * Filters whether this is an API request that Application Passwords can be used on. |
|
329 * |
|
330 * By default, Application Passwords is available for the REST API and XML-RPC. |
|
331 * |
|
332 * @since 5.6.0 |
|
333 * |
|
334 * @param bool $is_api_request If this is an acceptable API request. |
|
335 */ |
|
336 $is_api_request = apply_filters( 'application_password_is_api_request', $is_api_request ); |
|
337 |
|
338 if ( ! $is_api_request ) { |
|
339 return $input_user; |
|
340 } |
|
341 |
|
342 $error = null; |
|
343 $user = get_user_by( 'login', $username ); |
|
344 |
|
345 if ( ! $user && is_email( $username ) ) { |
|
346 $user = get_user_by( 'email', $username ); |
|
347 } |
|
348 |
|
349 // If the login name is invalid, short circuit. |
|
350 if ( ! $user ) { |
|
351 if ( is_email( $username ) ) { |
|
352 $error = new WP_Error( |
|
353 'invalid_email', |
|
354 __( '<strong>Error</strong>: Unknown email address. Check again or try your username.' ) |
|
355 ); |
|
356 } else { |
|
357 $error = new WP_Error( |
|
358 'invalid_username', |
|
359 __( '<strong>Error</strong>: Unknown username. Check again or try your email address.' ) |
|
360 ); |
|
361 } |
|
362 } elseif ( ! wp_is_application_passwords_available() ) { |
|
363 $error = new WP_Error( |
|
364 'application_passwords_disabled', |
|
365 __( 'Application passwords are not available.' ) |
|
366 ); |
|
367 } elseif ( ! wp_is_application_passwords_available_for_user( $user ) ) { |
|
368 $error = new WP_Error( |
|
369 'application_passwords_disabled_for_user', |
|
370 __( 'Application passwords are not available for your account. Please contact the site administrator for assistance.' ) |
|
371 ); |
|
372 } |
|
373 |
|
374 if ( $error ) { |
|
375 /** |
|
376 * Fires when an application password failed to authenticate the user. |
|
377 * |
|
378 * @since 5.6.0 |
|
379 * |
|
380 * @param WP_Error $error The authentication error. |
|
381 */ |
|
382 do_action( 'application_password_failed_authentication', $error ); |
|
383 |
|
384 return $error; |
|
385 } |
|
386 |
|
387 /* |
|
388 * Strip out anything non-alphanumeric. This is so passwords can be used with |
|
389 * or without spaces to indicate the groupings for readability. |
|
390 * |
|
391 * Generated application passwords are exclusively alphanumeric. |
|
392 */ |
|
393 $password = preg_replace( '/[^a-z\d]/i', '', $password ); |
|
394 |
|
395 $hashed_passwords = WP_Application_Passwords::get_user_application_passwords( $user->ID ); |
|
396 |
|
397 foreach ( $hashed_passwords as $key => $item ) { |
|
398 if ( ! wp_check_password( $password, $item['password'], $user->ID ) ) { |
|
399 continue; |
|
400 } |
|
401 |
|
402 $error = new WP_Error(); |
|
403 |
|
404 /** |
|
405 * Fires when an application password has been successfully checked as valid. |
|
406 * |
|
407 * This allows for plugins to add additional constraints to prevent an application password from being used. |
|
408 * |
|
409 * @since 5.6.0 |
|
410 * |
|
411 * @param WP_Error $error The error object. |
|
412 * @param WP_User $user The user authenticating. |
|
413 * @param array $item The details about the application password. |
|
414 * @param string $password The raw supplied password. |
|
415 */ |
|
416 do_action( 'wp_authenticate_application_password_errors', $error, $user, $item, $password ); |
|
417 |
|
418 if ( is_wp_error( $error ) && $error->has_errors() ) { |
|
419 /** This action is documented in wp-includes/user.php */ |
|
420 do_action( 'application_password_failed_authentication', $error ); |
|
421 |
|
422 return $error; |
|
423 } |
|
424 |
|
425 WP_Application_Passwords::record_application_password_usage( $user->ID, $item['uuid'] ); |
|
426 |
|
427 /** |
|
428 * Fires after an application password was used for authentication. |
|
429 * |
|
430 * @since 5.6.0 |
|
431 * |
|
432 * @param WP_User $user The user who was authenticated. |
|
433 * @param array $item The application password used. |
|
434 */ |
|
435 do_action( 'application_password_did_authenticate', $user, $item ); |
|
436 |
|
437 return $user; |
|
438 } |
|
439 |
|
440 $error = new WP_Error( |
|
441 'incorrect_password', |
|
442 __( 'The provided password is an invalid application password.' ) |
|
443 ); |
|
444 |
|
445 /** This action is documented in wp-includes/user.php */ |
|
446 do_action( 'application_password_failed_authentication', $error ); |
|
447 |
|
448 return $error; |
|
449 } |
|
450 |
|
451 /** |
|
452 * Validates the application password credentials passed via Basic Authentication. |
|
453 * |
|
454 * @since 5.6.0 |
|
455 * |
|
456 * @param int|false $input_user User ID if one has been determined, false otherwise. |
|
457 * @return int|false The authenticated user ID if successful, false otherwise. |
|
458 */ |
|
459 function wp_validate_application_password( $input_user ) { |
|
460 // Don't authenticate twice. |
|
461 if ( ! empty( $input_user ) ) { |
|
462 return $input_user; |
|
463 } |
|
464 |
|
465 if ( ! wp_is_application_passwords_available() ) { |
|
466 return $input_user; |
|
467 } |
|
468 |
|
469 // Both $_SERVER['PHP_AUTH_USER'] and $_SERVER['PHP_AUTH_PW'] must be set in order to attempt authentication. |
|
470 if ( ! isset( $_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW'] ) ) { |
|
471 return $input_user; |
|
472 } |
|
473 |
|
474 $authenticated = wp_authenticate_application_password( null, $_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW'] ); |
|
475 |
|
476 if ( $authenticated instanceof WP_User ) { |
|
477 return $authenticated->ID; |
|
478 } |
|
479 |
|
480 // If it wasn't a user what got returned, just pass on what we had received originally. |
|
481 return $input_user; |
|
482 } |
|
483 |
|
484 /** |
301 * For Multisite blogs, check if the authenticated user has been marked as a |
485 * For Multisite blogs, check if the authenticated user has been marked as a |
302 * spammer, or if the user's primary blog has been marked as spam. |
486 * spammer, or if the user's primary blog has been marked as spam. |
303 * |
487 * |
304 * @since 3.7.0 |
488 * @since 3.7.0 |
305 * |
489 * |
826 * |
1010 * |
827 * @param int $user_id User ID. |
1011 * @param int $user_id User ID. |
828 * @param string $key Optional. The meta key to retrieve. By default, |
1012 * @param string $key Optional. The meta key to retrieve. By default, |
829 * returns data for all keys. |
1013 * returns data for all keys. |
830 * @param bool $single Optional. Whether to return a single value. |
1014 * @param bool $single Optional. Whether to return a single value. |
831 * This parameter has no effect if $key is not specified. |
1015 * This parameter has no effect if `$key` is not specified. |
832 * Default false. |
1016 * Default false. |
833 * @return mixed An array if $single is false. The value of meta data field |
1017 * @return mixed An array of values if `$single` is false. |
834 * if $single is true. False for an invalid $user_id. |
1018 * The value of meta data field if `$single` is true. |
|
1019 * False for an invalid `$user_id` (non-numeric, zero, or negative value). |
|
1020 * An empty string if a valid but non-existing user ID is passed. |
835 */ |
1021 */ |
836 function get_user_meta( $user_id, $key = '', $single = false ) { |
1022 function get_user_meta( $user_id, $key = '', $single = false ) { |
837 return get_metadata( 'user', $user_id, $key, $single ); |
1023 return get_metadata( 'user', $user_id, $key, $single ); |
838 } |
1024 } |
839 |
1025 |
1409 * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/ |
1618 * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/ |
1410 * Conditional Tags} article in the Theme Developer Handbook. |
1619 * Conditional Tags} article in the Theme Developer Handbook. |
1411 * |
1620 * |
1412 * @since 2.0.0 |
1621 * @since 2.0.0 |
1413 * |
1622 * |
1414 * @param string $username Username. |
1623 * @param string $username The username to check for existence. |
1415 * @return int|false The user's ID on success, and false on failure. |
1624 * @return int|false The user ID on success, false on failure. |
1416 */ |
1625 */ |
1417 function username_exists( $username ) { |
1626 function username_exists( $username ) { |
1418 $user = get_user_by( 'login', $username ); |
1627 $user = get_user_by( 'login', $username ); |
1419 if ( $user ) { |
1628 if ( $user ) { |
1420 $user_id = $user->ID; |
1629 $user_id = $user->ID; |
1421 } else { |
1630 } else { |
1422 $user_id = false; |
1631 $user_id = false; |
1423 } |
1632 } |
1424 |
1633 |
1425 /** |
1634 /** |
1426 * Filters whether the given username exists or not. |
1635 * Filters whether the given username exists. |
1427 * |
1636 * |
1428 * @since 4.9.0 |
1637 * @since 4.9.0 |
1429 * |
1638 * |
1430 * @param int|false $user_id The user's ID on success, and false on failure. |
1639 * @param int|false $user_id The user ID associated with the username, |
1431 * @param string $username Username to check. |
1640 * or false if the username does not exist. |
|
1641 * @param string $username The username to check for existence. |
1432 */ |
1642 */ |
1433 return apply_filters( 'username_exists', $user_id, $username ); |
1643 return apply_filters( 'username_exists', $user_id, $username ); |
1434 } |
1644 } |
1435 |
1645 |
1436 /** |
1646 /** |
1440 * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/ |
1650 * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/ |
1441 * Conditional Tags} article in the Theme Developer Handbook. |
1651 * Conditional Tags} article in the Theme Developer Handbook. |
1442 * |
1652 * |
1443 * @since 2.1.0 |
1653 * @since 2.1.0 |
1444 * |
1654 * |
1445 * @param string $email Email. |
1655 * @param string $email The email to check for existence. |
1446 * @return int|false The user's ID on success, and false on failure. |
1656 * @return int|false The user ID on success, false on failure. |
1447 */ |
1657 */ |
1448 function email_exists( $email ) { |
1658 function email_exists( $email ) { |
1449 $user = get_user_by( 'email', $email ); |
1659 $user = get_user_by( 'email', $email ); |
1450 if ( $user ) { |
1660 if ( $user ) { |
1451 return $user->ID; |
1661 $user_id = $user->ID; |
1452 } |
1662 } else { |
1453 return false; |
1663 $user_id = false; |
|
1664 } |
|
1665 |
|
1666 /** |
|
1667 * Filters whether the given email exists. |
|
1668 * |
|
1669 * @since 5.6.0 |
|
1670 * |
|
1671 * @param int|false $user_id The user ID associated with the email, |
|
1672 * or false if the email does not exist. |
|
1673 * @param string $email The email to check for existence. |
|
1674 */ |
|
1675 return apply_filters( 'email_exists', $user_id, $email ); |
1454 } |
1676 } |
1455 |
1677 |
1456 /** |
1678 /** |
1457 * Checks whether a username is valid. |
1679 * Checks whether a username is valid. |
1458 * |
1680 * |
1459 * @since 2.0.1 |
1681 * @since 2.0.1 |
1460 * @since 4.4.0 Empty sanitized usernames are now considered invalid |
1682 * @since 4.4.0 Empty sanitized usernames are now considered invalid. |
1461 * |
1683 * |
1462 * @param string $username Username. |
1684 * @param string $username Username. |
1463 * @return bool Whether username given is valid |
1685 * @return bool Whether username given is valid. |
1464 */ |
1686 */ |
1465 function validate_username( $username ) { |
1687 function validate_username( $username ) { |
1466 $sanitized = sanitize_user( $username, true ); |
1688 $sanitized = sanitize_user( $username, true ); |
1467 $valid = ( $sanitized == $username && ! empty( $sanitized ) ); |
1689 $valid = ( $sanitized == $username && ! empty( $sanitized ) ); |
1468 |
1690 |
1469 /** |
1691 /** |
1470 * Filters whether the provided username is valid or not. |
1692 * Filters whether the provided username is valid. |
1471 * |
1693 * |
1472 * @since 2.0.1 |
1694 * @since 2.0.1 |
1473 * |
1695 * |
1474 * @param bool $valid Whether given username is valid. |
1696 * @param bool $valid Whether given username is valid. |
1475 * @param string $username Username to check. |
1697 * @param string $username Username to check. |
1805 * @type string $user_nicename The user's nice name. Defaults to a URL-safe version of user's login |
2028 * @type string $user_nicename The user's nice name. Defaults to a URL-safe version of user's login |
1806 * @type string $display_name The user's display name. |
2029 * @type string $display_name The user's display name. |
1807 * @type string $user_registered MySQL timestamp describing the moment when the user registered. Defaults to |
2030 * @type string $user_registered MySQL timestamp describing the moment when the user registered. Defaults to |
1808 * the current UTC timestamp. |
2031 * the current UTC timestamp. |
1809 * } |
2032 * } |
1810 * @param bool $update Whether the user is being updated rather than created. |
2033 * @param bool $update Whether the user is being updated rather than created. |
1811 * @param int|null $id ID of the user to be updated, or NULL if the user is being created. |
2034 * @param int|null $id ID of the user to be updated, or NULL if the user is being created. |
1812 */ |
2035 * @param array $userdata The raw array of data passed to wp_insert_user(). |
1813 $data = apply_filters( 'wp_pre_insert_user_data', $data, $update, $update ? (int) $ID : null ); |
2036 */ |
|
2037 $data = apply_filters( 'wp_pre_insert_user_data', $data, $update, ( $update ? (int) $ID : null ), $userdata ); |
1814 |
2038 |
1815 if ( empty( $data ) || ! is_array( $data ) ) { |
2039 if ( empty( $data ) || ! is_array( $data ) ) { |
1816 return new WP_Error( 'empty_data', __( 'Not enough data to create this user.' ) ); |
2040 return new WP_Error( 'empty_data', __( 'Not enough data to create this user.' ) ); |
1817 } |
2041 } |
1818 |
2042 |
2046 * Filters the contents of the email sent when the user's password is changed. |
2276 * Filters the contents of the email sent when the user's password is changed. |
2047 * |
2277 * |
2048 * @since 4.3.0 |
2278 * @since 4.3.0 |
2049 * |
2279 * |
2050 * @param array $pass_change_email { |
2280 * @param array $pass_change_email { |
2051 * Used to build wp_mail(). |
2281 * Used to build wp_mail(). |
2052 * |
2282 * |
2053 * @type string $to The intended recipients. Add emails in a comma separated string. |
2283 * @type string $to The intended recipients. Add emails in a comma separated string. |
2054 * @type string $subject The subject of the email. |
2284 * @type string $subject The subject of the email. |
2055 * @type string $message The content of the email. |
2285 * @type string $message The content of the email. |
2056 * The following strings have a special meaning and will get replaced dynamically: |
2286 * The following strings have a special meaning and will get replaced dynamically: |
2057 * - ###USERNAME### The current user's username. |
2287 * - ###USERNAME### The current user's username. |
2058 * - ###ADMIN_EMAIL### The admin email in case this was unexpected. |
2288 * - ###ADMIN_EMAIL### The admin email in case this was unexpected. |
2059 * - ###EMAIL### The user's email address. |
2289 * - ###EMAIL### The user's email address. |
2060 * - ###SITENAME### The name of the site. |
2290 * - ###SITENAME### The name of the site. |
2061 * - ###SITEURL### The URL to the site. |
2291 * - ###SITEURL### The URL to the site. |
2062 * @type string $headers Headers. Add headers in a newline (\r\n) separated string. |
2292 * @type string $headers Headers. Add headers in a newline (\r\n) separated string. |
2063 * } |
2293 * } |
2064 * @param array $user The original user array. |
2294 * @param array $user The original user array. |
2065 * @param array $userdata The updated user array. |
2295 * @param array $userdata The updated user array. |
2066 */ |
2296 */ |
2067 $pass_change_email = apply_filters( 'password_change_email', $pass_change_email, $user, $userdata ); |
2297 $pass_change_email = apply_filters( 'password_change_email', $pass_change_email, $user, $userdata ); |
2068 |
2298 |
2104 * Filters the contents of the email sent when the user's email is changed. |
2334 * Filters the contents of the email sent when the user's email is changed. |
2105 * |
2335 * |
2106 * @since 4.3.0 |
2336 * @since 4.3.0 |
2107 * |
2337 * |
2108 * @param array $email_change_email { |
2338 * @param array $email_change_email { |
2109 * Used to build wp_mail(). |
2339 * Used to build wp_mail(). |
2110 * |
2340 * |
2111 * @type string $to The intended recipients. |
2341 * @type string $to The intended recipients. |
2112 * @type string $subject The subject of the email. |
2342 * @type string $subject The subject of the email. |
2113 * @type string $message The content of the email. |
2343 * @type string $message The content of the email. |
2114 * The following strings have a special meaning and will get replaced dynamically: |
2344 * The following strings have a special meaning and will get replaced dynamically: |
2115 * - ###USERNAME### The current user's username. |
2345 * - ###USERNAME### The current user's username. |
2116 * - ###ADMIN_EMAIL### The admin email in case this was unexpected. |
2346 * - ###ADMIN_EMAIL### The admin email in case this was unexpected. |
2117 * - ###NEW_EMAIL### The new email address. |
2347 * - ###NEW_EMAIL### The new email address. |
2118 * - ###EMAIL### The old email address. |
2348 * - ###EMAIL### The old email address. |
2119 * - ###SITENAME### The name of the site. |
2349 * - ###SITENAME### The name of the site. |
2120 * - ###SITEURL### The URL to the site. |
2350 * - ###SITEURL### The URL to the site. |
2121 * @type string $headers Headers. |
2351 * @type string $headers Headers. |
2122 * } |
2352 * } |
2123 * @param array $user The original user array. |
2353 * @param array $user The original user array. |
2124 * @param array $userdata The updated user array. |
2354 * @param array $userdata The updated user array. |
2125 */ |
2355 */ |
2126 $email_change_email = apply_filters( 'email_change_email', $email_change_email, $user, $userdata ); |
2356 $email_change_email = apply_filters( 'email_change_email', $email_change_email, $user, $userdata ); |
2127 |
2357 |
2456 |
2686 |
2457 return new WP_Error( 'invalid_key', __( 'Invalid key.' ) ); |
2687 return new WP_Error( 'invalid_key', __( 'Invalid key.' ) ); |
2458 } |
2688 } |
2459 |
2689 |
2460 /** |
2690 /** |
|
2691 * Handles sending a password retrieval email to a user. |
|
2692 * |
|
2693 * @since 2.5.0 |
|
2694 * @since 5.7.0 Added `$user_login` parameter. |
|
2695 * |
|
2696 * @global wpdb $wpdb WordPress database abstraction object. |
|
2697 * @global PasswordHash $wp_hasher Portable PHP password hashing framework. |
|
2698 * |
|
2699 * @param string $user_login Optional. Username to send a password retrieval email for. |
|
2700 * Defaults to `$_POST['user_login']` if not set. |
|
2701 * @return true|WP_Error True when finished, WP_Error object on error. |
|
2702 */ |
|
2703 function retrieve_password( $user_login = null ) { |
|
2704 $errors = new WP_Error(); |
|
2705 $user_data = false; |
|
2706 |
|
2707 // Use the passed $user_login if available, otherwise use $_POST['user_login']. |
|
2708 if ( ! $user_login && ! empty( $_POST['user_login'] ) ) { |
|
2709 $user_login = $_POST['user_login']; |
|
2710 } |
|
2711 |
|
2712 if ( empty( $user_login ) ) { |
|
2713 $errors->add( 'empty_username', __( '<strong>Error</strong>: Please enter a username or email address.' ) ); |
|
2714 } elseif ( strpos( $user_login, '@' ) ) { |
|
2715 $user_data = get_user_by( 'email', trim( wp_unslash( $user_login ) ) ); |
|
2716 if ( empty( $user_data ) ) { |
|
2717 $errors->add( 'invalid_email', __( '<strong>Error</strong>: There is no account with that username or email address.' ) ); |
|
2718 } |
|
2719 } else { |
|
2720 $user_data = get_user_by( 'login', trim( wp_unslash( $user_login ) ) ); |
|
2721 } |
|
2722 |
|
2723 /** |
|
2724 * Filters the user data during a password reset request. |
|
2725 * |
|
2726 * Allows, for example, custom validation using data other than username or email address. |
|
2727 * |
|
2728 * @since 5.7.0 |
|
2729 * |
|
2730 * @param WP_User|false $user_data WP_User object if found, false if the user does not exist. |
|
2731 * @param WP_Error $errors A WP_Error object containing any errors generated |
|
2732 * by using invalid credentials. |
|
2733 */ |
|
2734 $user_data = apply_filters( 'lostpassword_user_data', $user_data, $errors ); |
|
2735 |
|
2736 /** |
|
2737 * Fires before errors are returned from a password reset request. |
|
2738 * |
|
2739 * @since 2.1.0 |
|
2740 * @since 4.4.0 Added the `$errors` parameter. |
|
2741 * @since 5.4.0 Added the `$user_data` parameter. |
|
2742 * |
|
2743 * @param WP_Error $errors A WP_Error object containing any errors generated |
|
2744 * by using invalid credentials. |
|
2745 * @param WP_User|false $user_data WP_User object if found, false if the user does not exist. |
|
2746 */ |
|
2747 do_action( 'lostpassword_post', $errors, $user_data ); |
|
2748 |
|
2749 /** |
|
2750 * Filters the errors encountered on a password reset request. |
|
2751 * |
|
2752 * The filtered WP_Error object may, for example, contain errors for an invalid |
|
2753 * username or email address. A WP_Error object should always be returned, |
|
2754 * but may or may not contain errors. |
|
2755 * |
|
2756 * If any errors are present in $errors, this will abort the password reset request. |
|
2757 * |
|
2758 * @since 5.5.0 |
|
2759 * |
|
2760 * @param WP_Error $errors A WP_Error object containing any errors generated |
|
2761 * by using invalid credentials. |
|
2762 * @param WP_User|false $user_data WP_User object if found, false if the user does not exist. |
|
2763 */ |
|
2764 $errors = apply_filters( 'lostpassword_errors', $errors, $user_data ); |
|
2765 |
|
2766 if ( $errors->has_errors() ) { |
|
2767 return $errors; |
|
2768 } |
|
2769 |
|
2770 if ( ! $user_data ) { |
|
2771 $errors->add( 'invalidcombo', __( '<strong>Error</strong>: There is no account with that username or email address.' ) ); |
|
2772 return $errors; |
|
2773 } |
|
2774 |
|
2775 // Redefining user_login ensures we return the right case in the email. |
|
2776 $user_login = $user_data->user_login; |
|
2777 $user_email = $user_data->user_email; |
|
2778 $key = get_password_reset_key( $user_data ); |
|
2779 |
|
2780 if ( is_wp_error( $key ) ) { |
|
2781 return $key; |
|
2782 } |
|
2783 |
|
2784 // Localize password reset message content for user. |
|
2785 $locale = get_user_locale( $user_data ); |
|
2786 |
|
2787 $switched_locale = switch_to_locale( $locale ); |
|
2788 |
|
2789 if ( is_multisite() ) { |
|
2790 $site_name = get_network()->site_name; |
|
2791 } else { |
|
2792 /* |
|
2793 * The blogname option is escaped with esc_html on the way into the database |
|
2794 * in sanitize_option. We want to reverse this for the plain text arena of emails. |
|
2795 */ |
|
2796 $site_name = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ); |
|
2797 } |
|
2798 |
|
2799 $message = __( 'Someone has requested a password reset for the following account:' ) . "\r\n\r\n"; |
|
2800 /* translators: %s: Site name. */ |
|
2801 $message .= sprintf( __( 'Site Name: %s' ), $site_name ) . "\r\n\r\n"; |
|
2802 /* translators: %s: User login. */ |
|
2803 $message .= sprintf( __( 'Username: %s' ), $user_login ) . "\r\n\r\n"; |
|
2804 $message .= __( 'If this was a mistake, ignore this email and nothing will happen.' ) . "\r\n\r\n"; |
|
2805 $message .= __( 'To reset your password, visit the following address:' ) . "\r\n\r\n"; |
|
2806 $message .= network_site_url( "wp-login.php?action=rp&key=$key&login=" . rawurlencode( $user_login ), 'login' ) . '&wp_lang=' . $locale . "\r\n\r\n"; |
|
2807 |
|
2808 if ( ! is_user_logged_in() ) { |
|
2809 $requester_ip = $_SERVER['REMOTE_ADDR']; |
|
2810 if ( $requester_ip ) { |
|
2811 $message .= sprintf( |
|
2812 /* translators: %s: IP address of password reset requester. */ |
|
2813 __( 'This password reset request originated from the IP address %s.' ), |
|
2814 $requester_ip |
|
2815 ) . "\r\n"; |
|
2816 } |
|
2817 } |
|
2818 |
|
2819 /* translators: Password reset notification email subject. %s: Site title. */ |
|
2820 $title = sprintf( __( '[%s] Password Reset' ), $site_name ); |
|
2821 |
|
2822 /** |
|
2823 * Filters the subject of the password reset email. |
|
2824 * |
|
2825 * @since 2.8.0 |
|
2826 * @since 4.4.0 Added the `$user_login` and `$user_data` parameters. |
|
2827 * |
|
2828 * @param string $title Email subject. |
|
2829 * @param string $user_login The username for the user. |
|
2830 * @param WP_User $user_data WP_User object. |
|
2831 */ |
|
2832 $title = apply_filters( 'retrieve_password_title', $title, $user_login, $user_data ); |
|
2833 |
|
2834 /** |
|
2835 * Filters the message body of the password reset mail. |
|
2836 * |
|
2837 * If the filtered message is empty, the password reset email will not be sent. |
|
2838 * |
|
2839 * @since 2.8.0 |
|
2840 * @since 4.1.0 Added `$user_login` and `$user_data` parameters. |
|
2841 * |
|
2842 * @param string $message Email message. |
|
2843 * @param string $key The activation key. |
|
2844 * @param string $user_login The username for the user. |
|
2845 * @param WP_User $user_data WP_User object. |
|
2846 */ |
|
2847 $message = apply_filters( 'retrieve_password_message', $message, $key, $user_login, $user_data ); |
|
2848 |
|
2849 if ( $switched_locale ) { |
|
2850 restore_previous_locale(); |
|
2851 } |
|
2852 |
|
2853 if ( $message && ! wp_mail( $user_email, wp_specialchars_decode( $title ), $message ) ) { |
|
2854 $errors->add( |
|
2855 'retrieve_password_email_failure', |
|
2856 sprintf( |
|
2857 /* translators: %s: Documentation URL. */ |
|
2858 __( '<strong>Error</strong>: The email could not be sent. Your site may not be correctly configured to send emails. <a href="%s">Get support for resetting your password</a>.' ), |
|
2859 esc_url( __( 'https://wordpress.org/support/article/resetting-your-password/' ) ) |
|
2860 ) |
|
2861 ); |
|
2862 return $errors; |
|
2863 } |
|
2864 |
|
2865 return true; |
|
2866 } |
|
2867 |
|
2868 /** |
2461 * Handles resetting the user's password. |
2869 * Handles resetting the user's password. |
2462 * |
2870 * |
2463 * @since 2.5.0 |
2871 * @since 2.5.0 |
2464 * |
2872 * |
2465 * @param WP_User $user The user |
2873 * @param WP_User $user The user |
3236 'sitename' => wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ), |
3644 'sitename' => wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ), |
3237 'siteurl' => home_url(), |
3645 'siteurl' => home_url(), |
3238 'admin_email' => $admin_email, |
3646 'admin_email' => $admin_email, |
3239 ); |
3647 ); |
3240 |
3648 |
3241 /* translators: Do not translate SITENAME, USER_EMAIL, DESCRIPTION, MANAGE_URL, SITEURL; those are placeholders. */ |
3649 $subject = sprintf( |
3242 $email_text = __( |
3650 /* translators: Privacy data request confirmed notification email subject. 1: Site title, 2: Name of the confirmed action. */ |
3243 'Howdy, |
3651 __( '[%1$s] Action Confirmed: %2$s' ), |
3244 |
3652 $email_data['sitename'], |
3245 A user data privacy request has been confirmed on ###SITENAME###: |
3653 $action_description |
3246 |
|
3247 User: ###USER_EMAIL### |
|
3248 Request: ###DESCRIPTION### |
|
3249 |
|
3250 You can view and manage these data privacy requests here: |
|
3251 |
|
3252 ###MANAGE_URL### |
|
3253 |
|
3254 Regards, |
|
3255 All at ###SITENAME### |
|
3256 ###SITEURL###' |
|
3257 ); |
3654 ); |
3258 |
3655 |
3259 /** |
3656 /** |
3260 * Filters the body of the user request confirmation email. |
3657 * Filters the subject of the user request confirmation email. |
3261 * |
3658 * |
3262 * The email is sent to an administrator when an user request is confirmed. |
3659 * @since 4.9.8 |
3263 * The following strings have a special meaning and will get replaced dynamically: |
3660 * |
3264 * |
3661 * @param string $subject The email subject. |
3265 * ###SITENAME### The name of the site. |
3662 * @param string $sitename The name of the site. |
3266 * ###USER_EMAIL### The user email for the request. |
|
3267 * ###DESCRIPTION### Description of the action being performed so the user knows what the email is for. |
|
3268 * ###MANAGE_URL### The URL to manage requests. |
|
3269 * ###SITEURL### The URL to the site. |
|
3270 * |
|
3271 * @since 4.9.6 |
|
3272 * |
|
3273 * @param string $email_text Text in the email. |
|
3274 * @param array $email_data { |
3663 * @param array $email_data { |
3275 * Data relating to the account action email. |
3664 * Data relating to the account action email. |
3276 * |
3665 * |
3277 * @type WP_User_Request $request User request object. |
3666 * @type WP_User_Request $request User request object. |
3278 * @type string $user_email The email address confirming a request |
3667 * @type string $user_email The email address confirming a request |
3281 * @type string $sitename The site name sending the mail. |
3670 * @type string $sitename The site name sending the mail. |
3282 * @type string $siteurl The site URL sending the mail. |
3671 * @type string $siteurl The site URL sending the mail. |
3283 * @type string $admin_email The administrator email receiving the mail. |
3672 * @type string $admin_email The administrator email receiving the mail. |
3284 * } |
3673 * } |
3285 */ |
3674 */ |
3286 $content = apply_filters( 'user_confirmed_action_email_content', $email_text, $email_data ); |
3675 $subject = apply_filters( 'user_request_confirmed_email_subject', $subject, $email_data['sitename'], $email_data ); |
3287 |
3676 |
3288 $content = str_replace( '###SITENAME###', $email_data['sitename'], $content ); |
3677 /* translators: Do not translate SITENAME, USER_EMAIL, DESCRIPTION, MANAGE_URL, SITEURL; those are placeholders. */ |
3289 $content = str_replace( '###USER_EMAIL###', $email_data['user_email'], $content ); |
3678 $content = __( |
3290 $content = str_replace( '###DESCRIPTION###', $email_data['description'], $content ); |
3679 'Howdy, |
3291 $content = str_replace( '###MANAGE_URL###', esc_url_raw( $email_data['manage_url'] ), $content ); |
3680 |
3292 $content = str_replace( '###SITEURL###', esc_url_raw( $email_data['siteurl'] ), $content ); |
3681 A user data privacy request has been confirmed on ###SITENAME###: |
3293 |
3682 |
3294 $subject = sprintf( |
3683 User: ###USER_EMAIL### |
3295 /* translators: Privacy data request confirmed notification email subject. 1: Site title, 2: Name of the confirmed action. */ |
3684 Request: ###DESCRIPTION### |
3296 __( '[%1$s] Action Confirmed: %2$s' ), |
3685 |
3297 $email_data['sitename'], |
3686 You can view and manage these data privacy requests here: |
3298 $action_description |
3687 |
|
3688 ###MANAGE_URL### |
|
3689 |
|
3690 Regards, |
|
3691 All at ###SITENAME### |
|
3692 ###SITEURL###' |
3299 ); |
3693 ); |
3300 |
3694 |
3301 /** |
3695 /** |
3302 * Filters the subject of the user request confirmation email. |
3696 * Filters the body of the user request confirmation email. |
3303 * |
3697 * |
3304 * @since 4.9.8 |
3698 * The email is sent to an administrator when a user request is confirmed. |
3305 * |
3699 * |
3306 * @param string $subject The email subject. |
3700 * The following strings have a special meaning and will get replaced dynamically: |
3307 * @param string $sitename The name of the site. |
3701 * |
|
3702 * ###SITENAME### The name of the site. |
|
3703 * ###USER_EMAIL### The user email for the request. |
|
3704 * ###DESCRIPTION### Description of the action being performed so the user knows what the email is for. |
|
3705 * ###MANAGE_URL### The URL to manage requests. |
|
3706 * ###SITEURL### The URL to the site. |
|
3707 * |
|
3708 * @since 4.9.6 |
|
3709 * @deprecated 5.8.0 Use {@see 'user_request_confirmed_email_content'} instead. |
|
3710 * For user erasure fulfillment email content |
|
3711 * use {@see 'user_erasure_fulfillment_email_content'} instead. |
|
3712 * |
|
3713 * @param string $content The email content. |
|
3714 * @param array $email_data { |
|
3715 * Data relating to the account action email. |
|
3716 * |
|
3717 * @type WP_User_Request $request User request object. |
|
3718 * @type string $user_email The email address confirming a request |
|
3719 * @type string $description Description of the action being performed |
|
3720 * so the user knows what the email is for. |
|
3721 * @type string $manage_url The link to click manage privacy requests of this type. |
|
3722 * @type string $sitename The site name sending the mail. |
|
3723 * @type string $siteurl The site URL sending the mail. |
|
3724 * @type string $admin_email The administrator email receiving the mail. |
|
3725 * } |
|
3726 */ |
|
3727 $content = apply_filters_deprecated( |
|
3728 'user_confirmed_action_email_content', |
|
3729 array( $content, $email_data ), |
|
3730 '5.8.0', |
|
3731 sprintf( |
|
3732 /* translators: 1 & 2: Deprecation replacement options. */ |
|
3733 __( '%1$s or %2$s' ), |
|
3734 'user_request_confirmed_email_content', |
|
3735 'user_erasure_fulfillment_email_content' |
|
3736 ) |
|
3737 ); |
|
3738 |
|
3739 /** |
|
3740 * Filters the body of the user request confirmation email. |
|
3741 * |
|
3742 * The email is sent to an administrator when a user request is confirmed. |
|
3743 * The following strings have a special meaning and will get replaced dynamically: |
|
3744 * |
|
3745 * ###SITENAME### The name of the site. |
|
3746 * ###USER_EMAIL### The user email for the request. |
|
3747 * ###DESCRIPTION### Description of the action being performed so the user knows what the email is for. |
|
3748 * ###MANAGE_URL### The URL to manage requests. |
|
3749 * ###SITEURL### The URL to the site. |
|
3750 * |
|
3751 * @since 5.8.0 |
|
3752 * |
|
3753 * @param string $content The email content. |
3308 * @param array $email_data { |
3754 * @param array $email_data { |
3309 * Data relating to the account action email. |
3755 * Data relating to the account action email. |
3310 * |
3756 * |
3311 * @type WP_User_Request $request User request object. |
3757 * @type WP_User_Request $request User request object. |
3312 * @type string $user_email The email address confirming a request |
3758 * @type string $user_email The email address confirming a request |
3423 * @type string $privacy_policy_url Privacy policy URL. |
3876 * @type string $privacy_policy_url Privacy policy URL. |
3424 * @type string $sitename The site name sending the mail. |
3877 * @type string $sitename The site name sending the mail. |
3425 * @type string $siteurl The site URL sending the mail. |
3878 * @type string $siteurl The site URL sending the mail. |
3426 * } |
3879 * } |
3427 */ |
3880 */ |
3428 $subject = apply_filters( 'user_erasure_complete_email_subject', $subject, $email_data['sitename'], $email_data ); |
3881 $subject = apply_filters_deprecated( |
3429 |
3882 'user_erasure_complete_email_subject', |
3430 if ( empty( $email_data['privacy_policy_url'] ) ) { |
3883 array( $subject, $email_data['sitename'], $email_data ), |
3431 /* translators: Do not translate SITENAME, SITEURL; those are placeholders. */ |
3884 '5.8.0', |
3432 $email_text = __( |
3885 'user_erasure_fulfillment_email_subject' |
3433 'Howdy, |
3886 ); |
3434 |
3887 |
3435 Your request to erase your personal data on ###SITENAME### has been completed. |
3888 /** |
3436 |
3889 * Filters the subject of the email sent when an erasure request is completed. |
3437 If you have any follow-up questions or concerns, please contact the site administrator. |
3890 * |
3438 |
3891 * @since 5.8.0 |
3439 Regards, |
3892 * |
3440 All at ###SITENAME### |
3893 * @param string $subject The email subject. |
3441 ###SITEURL###' |
3894 * @param string $sitename The name of the site. |
3442 ); |
|
3443 } else { |
|
3444 /* translators: Do not translate SITENAME, SITEURL, PRIVACY_POLICY_URL; those are placeholders. */ |
|
3445 $email_text = __( |
|
3446 'Howdy, |
|
3447 |
|
3448 Your request to erase your personal data on ###SITENAME### has been completed. |
|
3449 |
|
3450 If you have any follow-up questions or concerns, please contact the site administrator. |
|
3451 |
|
3452 For more information, you can also read our privacy policy: ###PRIVACY_POLICY_URL### |
|
3453 |
|
3454 Regards, |
|
3455 All at ###SITENAME### |
|
3456 ###SITEURL###' |
|
3457 ); |
|
3458 } |
|
3459 |
|
3460 /** |
|
3461 * Filters the body of the data erasure fulfillment notification. |
|
3462 * |
|
3463 * The email is sent to a user when a their data erasure request is fulfilled |
|
3464 * by an administrator. |
|
3465 * |
|
3466 * The following strings have a special meaning and will get replaced dynamically: |
|
3467 * |
|
3468 * ###SITENAME### The name of the site. |
|
3469 * ###PRIVACY_POLICY_URL### Privacy policy page URL. |
|
3470 * ###SITEURL### The URL to the site. |
|
3471 * |
|
3472 * @since 4.9.6 |
|
3473 * |
|
3474 * @param string $email_text Text in the email. |
|
3475 * @param array $email_data { |
3895 * @param array $email_data { |
3476 * Data relating to the account action email. |
3896 * Data relating to the account action email. |
3477 * |
3897 * |
3478 * @type WP_User_Request $request User request object. |
3898 * @type WP_User_Request $request User request object. |
3479 * @type string $message_recipient The address that the email will be sent to. Defaults |
3899 * @type string $message_recipient The address that the email will be sent to. Defaults |
3482 * @type string $privacy_policy_url Privacy policy URL. |
3902 * @type string $privacy_policy_url Privacy policy URL. |
3483 * @type string $sitename The site name sending the mail. |
3903 * @type string $sitename The site name sending the mail. |
3484 * @type string $siteurl The site URL sending the mail. |
3904 * @type string $siteurl The site URL sending the mail. |
3485 * } |
3905 * } |
3486 */ |
3906 */ |
3487 $content = apply_filters( 'user_confirmed_action_email_content', $email_text, $email_data ); |
3907 $subject = apply_filters( 'user_erasure_fulfillment_email_subject', $subject, $email_data['sitename'], $email_data ); |
3488 |
3908 |
3489 $content = str_replace( '###SITENAME###', $email_data['sitename'], $content ); |
3909 /* translators: Do not translate SITENAME, SITEURL; those are placeholders. */ |
3490 $content = str_replace( '###PRIVACY_POLICY_URL###', $email_data['privacy_policy_url'], $content ); |
3910 $content = __( |
3491 $content = str_replace( '###SITEURL###', esc_url_raw( $email_data['siteurl'] ), $content ); |
3911 'Howdy, |
3492 |
3912 |
3493 $headers = ''; |
3913 Your request to erase your personal data on ###SITENAME### has been completed. |
3494 |
3914 |
3495 /** |
3915 If you have any follow-up questions or concerns, please contact the site administrator. |
3496 * Filters the headers of the data erasure fulfillment notification. |
3916 |
3497 * |
3917 Regards, |
3498 * @since 5.4.0 |
3918 All at ###SITENAME### |
3499 * |
3919 ###SITEURL###' |
3500 * @param string|array $headers The email headers. |
3920 ); |
3501 * @param string $subject The email subject. |
3921 |
3502 * @param string $content The email content. |
3922 if ( ! empty( $email_data['privacy_policy_url'] ) ) { |
3503 * @param int $request_id The request ID. |
3923 /* translators: Do not translate SITENAME, SITEURL, PRIVACY_POLICY_URL; those are placeholders. */ |
3504 * @param array $email_data { |
3924 $content = __( |
|
3925 'Howdy, |
|
3926 |
|
3927 Your request to erase your personal data on ###SITENAME### has been completed. |
|
3928 |
|
3929 If you have any follow-up questions or concerns, please contact the site administrator. |
|
3930 |
|
3931 For more information, you can also read our privacy policy: ###PRIVACY_POLICY_URL### |
|
3932 |
|
3933 Regards, |
|
3934 All at ###SITENAME### |
|
3935 ###SITEURL###' |
|
3936 ); |
|
3937 } |
|
3938 |
|
3939 /** |
|
3940 * Filters the body of the data erasure fulfillment notification. |
|
3941 * |
|
3942 * The email is sent to a user when their data erasure request is fulfilled |
|
3943 * by an administrator. |
|
3944 * |
|
3945 * The following strings have a special meaning and will get replaced dynamically: |
|
3946 * |
|
3947 * ###SITENAME### The name of the site. |
|
3948 * ###PRIVACY_POLICY_URL### Privacy policy page URL. |
|
3949 * ###SITEURL### The URL to the site. |
|
3950 * |
|
3951 * @since 4.9.6 |
|
3952 * @deprecated 5.8.0 Use {@see 'user_erasure_fulfillment_email_content'} instead. |
|
3953 * For user request confirmation email content |
|
3954 * use {@see 'user_request_confirmed_email_content'} instead. |
|
3955 * |
|
3956 * @param string $content The email content. |
|
3957 * @param array $email_data { |
3505 * Data relating to the account action email. |
3958 * Data relating to the account action email. |
3506 * |
3959 * |
3507 * @type WP_User_Request $request User request object. |
3960 * @type WP_User_Request $request User request object. |
3508 * @type string $message_recipient The address that the email will be sent to. Defaults |
3961 * @type string $message_recipient The address that the email will be sent to. Defaults |
3509 * to the value of `$request->email`, but can be changed |
3962 * to the value of `$request->email`, but can be changed |
3511 * @type string $privacy_policy_url Privacy policy URL. |
3964 * @type string $privacy_policy_url Privacy policy URL. |
3512 * @type string $sitename The site name sending the mail. |
3965 * @type string $sitename The site name sending the mail. |
3513 * @type string $siteurl The site URL sending the mail. |
3966 * @type string $siteurl The site URL sending the mail. |
3514 * } |
3967 * } |
3515 */ |
3968 */ |
3516 $headers = apply_filters( 'user_erasure_complete_email_headers', $headers, $subject, $content, $request_id, $email_data ); |
3969 $content = apply_filters_deprecated( |
|
3970 'user_confirmed_action_email_content', |
|
3971 array( $content, $email_data ), |
|
3972 '5.8.0', |
|
3973 sprintf( |
|
3974 /* translators: 1 & 2: Deprecation replacement options. */ |
|
3975 __( '%1$s or %2$s' ), |
|
3976 'user_erasure_fulfillment_email_content', |
|
3977 'user_request_confirmed_email_content' |
|
3978 ) |
|
3979 ); |
|
3980 |
|
3981 /** |
|
3982 * Filters the body of the data erasure fulfillment notification. |
|
3983 * |
|
3984 * The email is sent to a user when their data erasure request is fulfilled |
|
3985 * by an administrator. |
|
3986 * |
|
3987 * The following strings have a special meaning and will get replaced dynamically: |
|
3988 * |
|
3989 * ###SITENAME### The name of the site. |
|
3990 * ###PRIVACY_POLICY_URL### Privacy policy page URL. |
|
3991 * ###SITEURL### The URL to the site. |
|
3992 * |
|
3993 * @since 5.8.0 |
|
3994 * |
|
3995 * @param string $content The email content. |
|
3996 * @param array $email_data { |
|
3997 * Data relating to the account action email. |
|
3998 * |
|
3999 * @type WP_User_Request $request User request object. |
|
4000 * @type string $message_recipient The address that the email will be sent to. Defaults |
|
4001 * to the value of `$request->email`, but can be changed |
|
4002 * by the `user_erasure_fulfillment_email_to` filter. |
|
4003 * @type string $privacy_policy_url Privacy policy URL. |
|
4004 * @type string $sitename The site name sending the mail. |
|
4005 * @type string $siteurl The site URL sending the mail. |
|
4006 * } |
|
4007 */ |
|
4008 $content = apply_filters( 'user_erasure_fulfillment_email_content', $content, $email_data ); |
|
4009 |
|
4010 $content = str_replace( '###SITENAME###', $email_data['sitename'], $content ); |
|
4011 $content = str_replace( '###PRIVACY_POLICY_URL###', $email_data['privacy_policy_url'], $content ); |
|
4012 $content = str_replace( '###SITEURL###', esc_url_raw( $email_data['siteurl'] ), $content ); |
|
4013 |
|
4014 $headers = ''; |
|
4015 |
|
4016 /** |
|
4017 * Filters the headers of the data erasure fulfillment notification. |
|
4018 * |
|
4019 * @since 5.4.0 |
|
4020 * @deprecated 5.8.0 Use {@see 'user_erasure_fulfillment_email_headers'} instead. |
|
4021 * |
|
4022 * @param string|array $headers The email headers. |
|
4023 * @param string $subject The email subject. |
|
4024 * @param string $content The email content. |
|
4025 * @param int $request_id The request ID. |
|
4026 * @param array $email_data { |
|
4027 * Data relating to the account action email. |
|
4028 * |
|
4029 * @type WP_User_Request $request User request object. |
|
4030 * @type string $message_recipient The address that the email will be sent to. Defaults |
|
4031 * to the value of `$request->email`, but can be changed |
|
4032 * by the `user_erasure_fulfillment_email_to` filter. |
|
4033 * @type string $privacy_policy_url Privacy policy URL. |
|
4034 * @type string $sitename The site name sending the mail. |
|
4035 * @type string $siteurl The site URL sending the mail. |
|
4036 * } |
|
4037 */ |
|
4038 $headers = apply_filters_deprecated( |
|
4039 'user_erasure_complete_email_headers', |
|
4040 array( $headers, $subject, $content, $request_id, $email_data ), |
|
4041 '5.8.0', |
|
4042 'user_erasure_fulfillment_email_headers' |
|
4043 ); |
|
4044 |
|
4045 /** |
|
4046 * Filters the headers of the data erasure fulfillment notification. |
|
4047 * |
|
4048 * @since 5.8.0 |
|
4049 * |
|
4050 * @param string|array $headers The email headers. |
|
4051 * @param string $subject The email subject. |
|
4052 * @param string $content The email content. |
|
4053 * @param int $request_id The request ID. |
|
4054 * @param array $email_data { |
|
4055 * Data relating to the account action email. |
|
4056 * |
|
4057 * @type WP_User_Request $request User request object. |
|
4058 * @type string $message_recipient The address that the email will be sent to. Defaults |
|
4059 * to the value of `$request->email`, but can be changed |
|
4060 * by the `user_erasure_fulfillment_email_to` filter. |
|
4061 * @type string $privacy_policy_url Privacy policy URL. |
|
4062 * @type string $sitename The site name sending the mail. |
|
4063 * @type string $siteurl The site URL sending the mail. |
|
4064 * } |
|
4065 */ |
|
4066 $headers = apply_filters( 'user_erasure_fulfillment_email_headers', $headers, $subject, $content, $request_id, $email_data ); |
3517 |
4067 |
3518 $email_sent = wp_mail( $user_email, $subject, $content, $headers ); |
4068 $email_sent = wp_mail( $user_email, $subject, $content, $headers ); |
3519 |
4069 |
3520 if ( $switched_locale ) { |
4070 if ( $switched_locale ) { |
3521 restore_previous_locale(); |
4071 restore_previous_locale(); |
3569 * |
4119 * |
3570 * Requests are stored inside a post type named `user_request` since they can apply to both |
4120 * Requests are stored inside a post type named `user_request` since they can apply to both |
3571 * users on the site, or guests without a user account. |
4121 * users on the site, or guests without a user account. |
3572 * |
4122 * |
3573 * @since 4.9.6 |
4123 * @since 4.9.6 |
3574 * |
4124 * @since 5.7.0 Added the `$status` parameter. |
3575 * @param string $email_address User email address. This can be the address of a registered or non-registered user. |
4125 * |
3576 * @param string $action_name Name of the action that is being confirmed. Required. |
4126 * @param string $email_address User email address. This can be the address of a registered |
3577 * @param array $request_data Misc data you want to send with the verification request and pass to the actions once the request is confirmed. |
4127 * or non-registered user. |
3578 * @return int|WP_Error Returns the request ID if successful, or a WP_Error object on failure. |
4128 * @param string $action_name Name of the action that is being confirmed. Required. |
3579 */ |
4129 * @param array $request_data Misc data you want to send with the verification request and pass |
3580 function wp_create_user_request( $email_address = '', $action_name = '', $request_data = array() ) { |
4130 * to the actions once the request is confirmed. |
|
4131 * @param string $status Optional request status (pending or confirmed). Default 'pending'. |
|
4132 * @return int|WP_Error Returns the request ID if successful, or a WP_Error object on failure. |
|
4133 */ |
|
4134 function wp_create_user_request( $email_address = '', $action_name = '', $request_data = array(), $status = 'pending' ) { |
3581 $email_address = sanitize_email( $email_address ); |
4135 $email_address = sanitize_email( $email_address ); |
3582 $action_name = sanitize_key( $action_name ); |
4136 $action_name = sanitize_key( $action_name ); |
3583 |
4137 |
3584 if ( ! is_email( $email_address ) ) { |
4138 if ( ! is_email( $email_address ) ) { |
3585 return new WP_Error( 'invalid_email', __( 'Invalid email address.' ) ); |
4139 return new WP_Error( 'invalid_email', __( 'Invalid email address.' ) ); |
3586 } |
4140 } |
3587 |
4141 |
3588 if ( ! $action_name ) { |
4142 if ( ! in_array( $action_name, _wp_privacy_action_request_types(), true ) ) { |
3589 return new WP_Error( 'invalid_action', __( 'Invalid action name.' ) ); |
4143 return new WP_Error( 'invalid_action', __( 'Invalid action name.' ) ); |
|
4144 } |
|
4145 |
|
4146 if ( ! in_array( $status, array( 'pending', 'confirmed' ), true ) ) { |
|
4147 return new WP_Error( 'invalid_status', __( 'Invalid request status.' ) ); |
3590 } |
4148 } |
3591 |
4149 |
3592 $user = get_user_by( 'email', $email_address ); |
4150 $user = get_user_by( 'email', $email_address ); |
3593 $user_id = $user && ! is_wp_error( $user ) ? $user->ID : 0; |
4151 $user_id = $user && ! is_wp_error( $user ) ? $user->ID : 0; |
3594 |
4152 |
3605 'fields' => 'ids', |
4163 'fields' => 'ids', |
3606 ) |
4164 ) |
3607 ); |
4165 ); |
3608 |
4166 |
3609 if ( $requests_query->found_posts ) { |
4167 if ( $requests_query->found_posts ) { |
3610 return new WP_Error( 'duplicate_request', __( 'An incomplete request for this email address already exists.' ) ); |
4168 return new WP_Error( 'duplicate_request', __( 'An incomplete personal data request for this email address already exists.' ) ); |
3611 } |
4169 } |
3612 |
4170 |
3613 $request_id = wp_insert_post( |
4171 $request_id = wp_insert_post( |
3614 array( |
4172 array( |
3615 'post_author' => $user_id, |
4173 'post_author' => $user_id, |
3616 'post_name' => $action_name, |
4174 'post_name' => $action_name, |
3617 'post_title' => $email_address, |
4175 'post_title' => $email_address, |
3618 'post_content' => wp_json_encode( $request_data ), |
4176 'post_content' => wp_json_encode( $request_data ), |
3619 'post_status' => 'request-pending', |
4177 'post_status' => 'request-' . $status, |
3620 'post_type' => 'user_request', |
4178 'post_type' => 'user_request', |
3621 'post_date' => current_time( 'mysql', false ), |
4179 'post_date' => current_time( 'mysql', false ), |
3622 'post_date_gmt' => current_time( 'mysql', true ), |
4180 'post_date_gmt' => current_time( 'mysql', true ), |
3623 ), |
4181 ), |
3624 true |
4182 true |
3701 ), |
4259 ), |
3702 'sitename' => wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ), |
4260 'sitename' => wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ), |
3703 'siteurl' => home_url(), |
4261 'siteurl' => home_url(), |
3704 ); |
4262 ); |
3705 |
4263 |
3706 /* translators: Do not translate DESCRIPTION, CONFIRM_URL, SITENAME, SITEURL: those are placeholders. */ |
4264 /* translators: Confirm privacy data request notification email subject. 1: Site title, 2: Name of the action. */ |
3707 $email_text = __( |
4265 $subject = sprintf( __( '[%1$s] Confirm Action: %2$s' ), $email_data['sitename'], $email_data['description'] ); |
3708 'Howdy, |
4266 |
3709 |
4267 /** |
3710 A request has been made to perform the following action on your account: |
4268 * Filters the subject of the email sent when an account action is attempted. |
3711 |
|
3712 ###DESCRIPTION### |
|
3713 |
|
3714 To confirm this, please click on the following link: |
|
3715 ###CONFIRM_URL### |
|
3716 |
|
3717 You can safely ignore and delete this email if you do not want to |
|
3718 take this action. |
|
3719 |
|
3720 Regards, |
|
3721 All at ###SITENAME### |
|
3722 ###SITEURL###' |
|
3723 ); |
|
3724 |
|
3725 /** |
|
3726 * Filters the text of the email sent when an account action is attempted. |
|
3727 * |
|
3728 * The following strings have a special meaning and will get replaced dynamically: |
|
3729 * |
|
3730 * ###DESCRIPTION### Description of the action being performed so the user knows what the email is for. |
|
3731 * ###CONFIRM_URL### The link to click on to confirm the account action. |
|
3732 * ###SITENAME### The name of the site. |
|
3733 * ###SITEURL### The URL to the site. |
|
3734 * |
4269 * |
3735 * @since 4.9.6 |
4270 * @since 4.9.6 |
3736 * |
4271 * |
3737 * @param string $email_text Text in the email. |
4272 * @param string $subject The email subject. |
|
4273 * @param string $sitename The name of the site. |
3738 * @param array $email_data { |
4274 * @param array $email_data { |
3739 * Data relating to the account action email. |
4275 * Data relating to the account action email. |
3740 * |
4276 * |
3741 * @type WP_User_Request $request User request object. |
4277 * @type WP_User_Request $request User request object. |
3742 * @type string $email The email address this is being sent to. |
4278 * @type string $email The email address this is being sent to. |
3744 * @type string $confirm_url The link to click on to confirm the account action. |
4280 * @type string $confirm_url The link to click on to confirm the account action. |
3745 * @type string $sitename The site name sending the mail. |
4281 * @type string $sitename The site name sending the mail. |
3746 * @type string $siteurl The site URL sending the mail. |
4282 * @type string $siteurl The site URL sending the mail. |
3747 * } |
4283 * } |
3748 */ |
4284 */ |
3749 $content = apply_filters( 'user_request_action_email_content', $email_text, $email_data ); |
4285 $subject = apply_filters( 'user_request_action_email_subject', $subject, $email_data['sitename'], $email_data ); |
3750 |
4286 |
3751 $content = str_replace( '###DESCRIPTION###', $email_data['description'], $content ); |
4287 /* translators: Do not translate DESCRIPTION, CONFIRM_URL, SITENAME, SITEURL: those are placeholders. */ |
3752 $content = str_replace( '###CONFIRM_URL###', esc_url_raw( $email_data['confirm_url'] ), $content ); |
4288 $content = __( |
3753 $content = str_replace( '###EMAIL###', $email_data['email'], $content ); |
4289 'Howdy, |
3754 $content = str_replace( '###SITENAME###', $email_data['sitename'], $content ); |
4290 |
3755 $content = str_replace( '###SITEURL###', esc_url_raw( $email_data['siteurl'] ), $content ); |
4291 A request has been made to perform the following action on your account: |
3756 |
4292 |
3757 /* translators: Confirm privacy data request notification email subject. 1: Site title, 2: Name of the action. */ |
4293 ###DESCRIPTION### |
3758 $subject = sprintf( __( '[%1$s] Confirm Action: %2$s' ), $email_data['sitename'], $email_data['description'] ); |
4294 |
3759 |
4295 To confirm this, please click on the following link: |
3760 /** |
4296 ###CONFIRM_URL### |
3761 * Filters the subject of the email sent when an account action is attempted. |
4297 |
|
4298 You can safely ignore and delete this email if you do not want to |
|
4299 take this action. |
|
4300 |
|
4301 Regards, |
|
4302 All at ###SITENAME### |
|
4303 ###SITEURL###' |
|
4304 ); |
|
4305 |
|
4306 /** |
|
4307 * Filters the text of the email sent when an account action is attempted. |
|
4308 * |
|
4309 * The following strings have a special meaning and will get replaced dynamically: |
|
4310 * |
|
4311 * ###DESCRIPTION### Description of the action being performed so the user knows what the email is for. |
|
4312 * ###CONFIRM_URL### The link to click on to confirm the account action. |
|
4313 * ###SITENAME### The name of the site. |
|
4314 * ###SITEURL### The URL to the site. |
3762 * |
4315 * |
3763 * @since 4.9.6 |
4316 * @since 4.9.6 |
3764 * |
4317 * |
3765 * @param string $subject The email subject. |
4318 * @param string $content Text in the email. |
3766 * @param string $sitename The name of the site. |
|
3767 * @param array $email_data { |
4319 * @param array $email_data { |
3768 * Data relating to the account action email. |
4320 * Data relating to the account action email. |
3769 * |
4321 * |
3770 * @type WP_User_Request $request User request object. |
4322 * @type WP_User_Request $request User request object. |
3771 * @type string $email The email address this is being sent to. |
4323 * @type string $email The email address this is being sent to. |
3850 * |
4408 * |
3851 * @since 4.9.6 |
4409 * @since 4.9.6 |
3852 * |
4410 * |
3853 * @param string $request_id ID of the request being confirmed. |
4411 * @param string $request_id ID of the request being confirmed. |
3854 * @param string $key Provided key to validate. |
4412 * @param string $key Provided key to validate. |
3855 * @return bool|WP_Error True on success, WP_Error on failure. |
4413 * @return true|WP_Error True on success, WP_Error on failure. |
3856 */ |
4414 */ |
3857 function wp_validate_user_request_key( $request_id, $key ) { |
4415 function wp_validate_user_request_key( $request_id, $key ) { |
3858 global $wp_hasher; |
4416 global $wp_hasher; |
3859 |
4417 |
3860 $request_id = absint( $request_id ); |
4418 $request_id = absint( $request_id ); |
3861 $request = wp_get_user_request( $request_id ); |
4419 $request = wp_get_user_request( $request_id ); |
3862 |
4420 $saved_key = $request->confirm_key; |
3863 if ( ! $request ) { |
4421 $key_request_time = $request->modified_timestamp; |
3864 return new WP_Error( 'invalid_request', __( 'Invalid request.' ) ); |
4422 |
|
4423 if ( ! $request || ! $saved_key || ! $key_request_time ) { |
|
4424 return new WP_Error( 'invalid_request', __( 'Invalid personal data request.' ) ); |
3865 } |
4425 } |
3866 |
4426 |
3867 if ( ! in_array( $request->status, array( 'request-pending', 'request-failed' ), true ) ) { |
4427 if ( ! in_array( $request->status, array( 'request-pending', 'request-failed' ), true ) ) { |
3868 return new WP_Error( 'expired_link', __( 'This link has expired.' ) ); |
4428 return new WP_Error( 'expired_request', __( 'This personal data request has expired.' ) ); |
3869 } |
4429 } |
3870 |
4430 |
3871 if ( empty( $key ) ) { |
4431 if ( empty( $key ) ) { |
3872 return new WP_Error( 'missing_key', __( 'Missing confirm key.' ) ); |
4432 return new WP_Error( 'missing_key', __( 'The confirmation key is missing from this personal data request.' ) ); |
3873 } |
4433 } |
3874 |
4434 |
3875 if ( empty( $wp_hasher ) ) { |
4435 if ( empty( $wp_hasher ) ) { |
3876 require_once ABSPATH . WPINC . '/class-phpass.php'; |
4436 require_once ABSPATH . WPINC . '/class-phpass.php'; |
3877 $wp_hasher = new PasswordHash( 8, true ); |
4437 $wp_hasher = new PasswordHash( 8, true ); |
3878 } |
4438 } |
3879 |
4439 |
3880 $key_request_time = $request->modified_timestamp; |
|
3881 $saved_key = $request->confirm_key; |
|
3882 |
|
3883 if ( ! $saved_key ) { |
|
3884 return new WP_Error( 'invalid_key', __( 'Invalid key.' ) ); |
|
3885 } |
|
3886 |
|
3887 if ( ! $key_request_time ) { |
|
3888 return new WP_Error( 'invalid_key', __( 'Invalid action.' ) ); |
|
3889 } |
|
3890 |
|
3891 /** |
4440 /** |
3892 * Filters the expiration time of confirm keys. |
4441 * Filters the expiration time of confirm keys. |
3893 * |
4442 * |
3894 * @since 4.9.6 |
4443 * @since 4.9.6 |
3895 * |
4444 * |
3925 return false; |
4474 return false; |
3926 } |
4475 } |
3927 |
4476 |
3928 return new WP_User_Request( $post ); |
4477 return new WP_User_Request( $post ); |
3929 } |
4478 } |
|
4479 |
|
4480 /** |
|
4481 * Checks if Application Passwords is globally available. |
|
4482 * |
|
4483 * By default, Application Passwords is available to all sites using SSL or to local environments. |
|
4484 * Use {@see 'wp_is_application_passwords_available'} to adjust its availability. |
|
4485 * |
|
4486 * @since 5.6.0 |
|
4487 * |
|
4488 * @return bool |
|
4489 */ |
|
4490 function wp_is_application_passwords_available() { |
|
4491 $available = is_ssl() || 'local' === wp_get_environment_type(); |
|
4492 |
|
4493 /** |
|
4494 * Filters whether Application Passwords is available. |
|
4495 * |
|
4496 * @since 5.6.0 |
|
4497 * |
|
4498 * @param bool $available True if available, false otherwise. |
|
4499 */ |
|
4500 return apply_filters( 'wp_is_application_passwords_available', $available ); |
|
4501 } |
|
4502 |
|
4503 /** |
|
4504 * Checks if Application Passwords is available for a specific user. |
|
4505 * |
|
4506 * By default all users can use Application Passwords. Use {@see 'wp_is_application_passwords_available_for_user'} |
|
4507 * to restrict availability to certain users. |
|
4508 * |
|
4509 * @since 5.6.0 |
|
4510 * |
|
4511 * @param int|WP_User $user The user to check. |
|
4512 * @return bool |
|
4513 */ |
|
4514 function wp_is_application_passwords_available_for_user( $user ) { |
|
4515 if ( ! wp_is_application_passwords_available() ) { |
|
4516 return false; |
|
4517 } |
|
4518 |
|
4519 if ( ! is_object( $user ) ) { |
|
4520 $user = get_userdata( $user ); |
|
4521 } |
|
4522 |
|
4523 if ( ! $user || ! $user->exists() ) { |
|
4524 return false; |
|
4525 } |
|
4526 |
|
4527 /** |
|
4528 * Filters whether Application Passwords is available for a specific user. |
|
4529 * |
|
4530 * @since 5.6.0 |
|
4531 * |
|
4532 * @param bool $available True if available, false otherwise. |
|
4533 * @param WP_User $user The user to check. |
|
4534 */ |
|
4535 return apply_filters( 'wp_is_application_passwords_available_for_user', true, $user ); |
|
4536 } |