← All changes
|
jetpack_vendor/automattic/jetpack-sync/src/modules/class-users.php
+105
-55
12.8.3
→
16.3-a.7
View file →
| @@ -6,12 +6,17 @@ | ||
| 6 | 6 | */ |
| 7 | 7 | |
| 8 | 8 | namespace Automattic\Jetpack\Sync\Modules; |
| 9 | 9 | |
| 10 | +use Automattic\Jetpack\Connection\Manager; | |
| 10 | 11 | use Automattic\Jetpack\Constants as Jetpack_Constants; |
| 11 | 12 | use Automattic\Jetpack\Password_Checker; |
| 12 | 13 | use Automattic\Jetpack\Sync\Defaults; |
| 13 | 14 | |
| 15 | +if ( ! defined( 'ABSPATH' ) ) { | |
| 16 | + exit( 0 ); | |
| 17 | +} | |
| 18 | + | |
| 14 | 19 | /** |
| 15 | 20 | * Class to handle sync for users. |
| 16 | 21 | */ |
| 17 | 22 | class Users extends Module { |
| @@ -57,19 +62,33 @@ | ||
| 57 | 62 | return 'users'; |
| 58 | 63 | } |
| 59 | 64 | |
| 60 | 65 | /** |
| 61 | - * The table in the database. | |
| 66 | + * The table name. | |
| 62 | 67 | * |
| 63 | 68 | * @access public |
| 64 | 69 | * |
| 65 | 70 | * @return string |
| 71 | + * @deprecated since 3.11.0 Use table() instead. | |
| 66 | 72 | */ |
| 67 | 73 | public function table_name() { |
| 74 | + _deprecated_function( __METHOD__, '3.11.0', 'Automattic\\Jetpack\\Sync\\Users->table' ); | |
| 68 | 75 | return 'usermeta'; |
| 69 | 76 | } |
| 70 | 77 | |
| 71 | 78 | /** |
| 79 | + * The table in the database with the prefix. | |
| 80 | + * | |
| 81 | + * @access public | |
| 82 | + * | |
| 83 | + * @return string|bool | |
| 84 | + */ | |
| 85 | + public function table() { | |
| 86 | + global $wpdb; | |
| 87 | + return $wpdb->usermeta; | |
| 88 | + } | |
| 89 | + | |
| 90 | + /** | |
| 72 | 91 | * The id field in the database. |
| 73 | 92 | * |
| 74 | 93 | * @access public |
| 75 | 94 | * |
| @@ -122,15 +141,15 @@ | ||
| 122 | 141 | add_action( 'jetpack_sync_user_locale_delete', $callable, 10, 1 ); |
| 123 | 142 | |
| 124 | 143 | add_action( 'deleted_user', array( $this, 'deleted_user_handler' ), 10, 2 ); |
| 125 | 144 | add_action( 'jetpack_deleted_user', $callable, 10, 3 ); |
| 126 | - add_action( 'remove_user_from_blog', array( $this, 'remove_user_from_blog_handler' ), 10, 2 ); | |
| 145 | + add_action( 'remove_user_from_blog', array( $this, 'remove_user_from_blog_handler' ), 10, 3 ); | |
| 127 | 146 | add_action( 'jetpack_removed_user_from_blog', $callable, 10, 2 ); |
| 128 | 147 | |
| 129 | 148 | // User roles. |
| 130 | - add_action( 'add_user_role', array( $this, 'save_user_role_handler' ), 10, 2 ); | |
| 149 | + add_action( 'add_user_role', array( $this, 'add_user_role_handler' ), 10, 2 ); | |
| 131 | 150 | add_action( 'set_user_role', array( $this, 'save_user_role_handler' ), 10, 3 ); |
| 132 | - add_action( 'remove_user_role', array( $this, 'save_user_role_handler' ), 10, 2 ); | |
| 151 | + add_action( 'remove_user_role', array( $this, 'remove_user_role_handler' ), 10, 2 ); | |
| 133 | 152 | |
| 134 | 153 | // User capabilities. |
| 135 | 154 | add_action( 'added_user_meta', array( $this, 'maybe_save_user_meta' ), 10, 4 ); |
| 136 | 155 | add_action( 'updated_user_meta', array( $this, 'maybe_save_user_meta' ), 10, 4 ); |
| @@ -179,9 +198,9 @@ | ||
| 179 | 198 | * |
| 180 | 199 | * @access private |
| 181 | 200 | * |
| 182 | 201 | * @param mixed $user User object or ID. |
| 183 | - * @return \WP_User User object, or `null` if user invalid/not found. | |
| 202 | + * @return \WP_User|null User object, or `null` if user invalid/not found. | |
| 184 | 203 | */ |
| 185 | 204 | private function get_user( $user ) { |
| 186 | 205 | if ( is_numeric( $user ) ) { |
| 187 | 206 | $user = get_user_by( 'id', $user ); |
| @@ -234,8 +253,10 @@ | ||
| 234 | 253 | if ( get_locale() !== get_user_locale( $user->ID ) ) { |
| 235 | 254 | $user->locale = get_user_locale( $user->ID ); |
| 236 | 255 | } |
| 237 | 256 | |
| 257 | + $user->is_connected = ( new Manager( 'jetpack' ) )->is_user_connected( $user->ID ); | |
| 258 | + | |
| 238 | 259 | return $user; |
| 239 | 260 | } |
| 240 | 261 | |
| 241 | 262 | /** |
| @@ -342,9 +363,13 @@ | ||
| 342 | 363 | * |
| 343 | 364 | * @param string $user_login The user login. |
| 344 | 365 | * @param \WP_User $user The user object. |
| 345 | 366 | */ |
| 346 | - public function wp_login_handler( $user_login, $user ) { | |
| 367 | + public function wp_login_handler( $user_login, $user = null ) { | |
| 368 | + if ( ! $user instanceof \WP_User || empty( $user->ID ) ) { | |
| 369 | + return; | |
| 370 | + } | |
| 371 | + | |
| 347 | 372 | /** |
| 348 | 373 | * Fires when a user is logged into a site. |
| 349 | 374 | * |
| 350 | 375 | * @since 1.6.3 |
| @@ -511,8 +536,11 @@ | ||
| 511 | 536 | foreach ( $old_user_array as $user_field => $field_value ) { |
| 512 | 537 | if ( false === $user->has_prop( $user_field ) ) { |
| 513 | 538 | continue; |
| 514 | 539 | } |
| 540 | + if ( 'ID' === $user_field ) { | |
| 541 | + continue; | |
| 542 | + } | |
| 515 | 543 | if ( $user->$user_field !== $field_value ) { |
| 516 | 544 | if ( 'user_email' === $user_field ) { |
| 517 | 545 | /** |
| 518 | 546 | * The '_new_email' user meta is deleted right after the call to wp_update_user |
| @@ -524,9 +552,9 @@ | ||
| 524 | 552 | } |
| 525 | 553 | continue; |
| 526 | 554 | } |
| 527 | 555 | |
| 528 | - $flag = isset( $this->user_fields_to_flags_mapping[ $user_field ] ) ? $this->user_fields_to_flags_mapping[ $user_field ] : 'unknown_field_changed'; | |
| 556 | + $flag = $this->user_fields_to_flags_mapping[ $user_field ] ?? 'unknown_field_changed'; | |
| 529 | 557 | |
| 530 | 558 | $this->flags[ $user_id ][ $flag ] = true; |
| 531 | 559 | } |
| 532 | 560 | } |
| @@ -547,8 +575,46 @@ | ||
| 547 | 575 | } |
| 548 | 576 | } |
| 549 | 577 | |
| 550 | 578 | /** |
| 579 | + * Handler for add user role change. | |
| 580 | + * | |
| 581 | + * @access public | |
| 582 | + * | |
| 583 | + * @param int $user_id ID of the user. | |
| 584 | + * @param string $role New user role. | |
| 585 | + */ | |
| 586 | + public function add_user_role_handler( $user_id, $role ) { | |
| 587 | + $this->add_flags( | |
| 588 | + $user_id, | |
| 589 | + array( | |
| 590 | + 'role_added' => $role, | |
| 591 | + ) | |
| 592 | + ); | |
| 593 | + | |
| 594 | + $this->save_user_role_handler( $user_id, $role ); | |
| 595 | + } | |
| 596 | + | |
| 597 | + /** | |
| 598 | + * Handler for remove user role change. | |
| 599 | + * | |
| 600 | + * @access public | |
| 601 | + * | |
| 602 | + * @param int $user_id ID of the user. | |
| 603 | + * @param string $role Removed user role. | |
| 604 | + */ | |
| 605 | + public function remove_user_role_handler( $user_id, $role ) { | |
| 606 | + $this->add_flags( | |
| 607 | + $user_id, | |
| 608 | + array( | |
| 609 | + 'role_removed' => $role, | |
| 610 | + ) | |
| 611 | + ); | |
| 612 | + | |
| 613 | + $this->save_user_role_handler( $user_id, $role ); | |
| 614 | + } | |
| 615 | + | |
| 616 | + /** | |
| 551 | 617 | * Handler for user role change. |
| 552 | 618 | * |
| 553 | 619 | * @access public |
| 554 | 620 | * |
| @@ -565,9 +631,11 @@ | ||
| 565 | 631 | ) |
| 566 | 632 | ); |
| 567 | 633 | |
| 568 | 634 | // The jetpack_sync_register_user payload is identical to jetpack_sync_save_user, don't send both. |
| 569 | - if ( $this->is_create_user() || $this->is_add_user_to_blog() ) { | |
| 635 | + if ( $this->is_function_in_backtrace( | |
| 636 | + array_merge( $this->get_create_user_functions(), $this->get_add_user_to_blog_functions() ) | |
| 637 | + ) ) { | |
| 570 | 638 | return; |
| 571 | 639 | } |
| 572 | 640 | /** |
| 573 | 641 | * This action is documented already in this file |
| @@ -636,9 +704,11 @@ | ||
| 636 | 704 | if ( isset( $user->cap_key ) && $meta_key === $user->cap_key ) { |
| 637 | 705 | $this->add_flags( $user_id, array( 'capabilities_changed' => true ) ); |
| 638 | 706 | } |
| 639 | 707 | |
| 640 | - if ( $this->is_create_user() || $this->is_add_user_to_blog() || $this->is_delete_user() ) { | |
| 708 | + if ( $this->is_function_in_backtrace( | |
| 709 | + array_merge( $this->get_create_user_functions(), $this->get_add_user_to_blog_functions(), $this->get_delete_user_functions() ) | |
| 710 | + ) ) { | |
| 641 | 711 | return; |
| 642 | 712 | } |
| 643 | 713 | |
| 644 | 714 | if ( isset( $this->flags[ $user_id ] ) ) { |
| @@ -672,9 +742,9 @@ | ||
| 672 | 742 | * |
| 673 | 743 | * @todo Refactor to prepare the SQL query before executing it. |
| 674 | 744 | * |
| 675 | 745 | * @param array $config Full sync configuration for this sync module. |
| 676 | - * @return array Number of items yet to be enqueued. | |
| 746 | + * @return int Number of items yet to be enqueued. | |
| 677 | 747 | */ |
| 678 | 748 | public function estimate_full_sync_actions( $config ) { |
| 679 | 749 | global $wpdb; |
| 680 | 750 | |
| @@ -684,10 +754,10 @@ | ||
| 684 | 754 | if ( $where_sql ) { |
| 685 | 755 | $query .= ' WHERE ' . $where_sql; |
| 686 | 756 | } |
| 687 | 757 | |
| 688 | - // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared | |
| 689 | - $count = $wpdb->get_var( $query ); | |
| 758 | + // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared,WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching | |
| 759 | + $count = (int) $wpdb->get_var( $query ); | |
| 690 | 760 | |
| 691 | 761 | return (int) ceil( $count / self::ARRAY_CHUNK_SIZE ); |
| 692 | 762 | } |
| 693 | 763 | |
| @@ -704,9 +774,9 @@ | ||
| 704 | 774 | |
| 705 | 775 | $query = "meta_key = '{$wpdb->prefix}user_level' AND meta_value > 0"; |
| 706 | 776 | |
| 707 | 777 | // The $config variable is a list of user IDs to sync. |
| 708 | - if ( is_array( $config ) ) { | |
| 778 | + if ( is_array( $config ) && ! empty( $config ) ) { | |
| 709 | 779 | $query .= ' AND user_id IN (' . implode( ',', array_map( 'intval', $config ) ) . ')'; |
| 710 | 780 | } |
| 711 | 781 | |
| 712 | 782 | return $query; |
| @@ -776,18 +846,19 @@ | ||
| 776 | 846 | * Handler for user removal from a particular blog. |
| 777 | 847 | * |
| 778 | 848 | * @access public |
| 779 | 849 | * |
| 780 | - * @param int $user_id ID of the user. | |
| 781 | - * @param int $blog_id ID of the blog. | |
| 850 | + * @param int $user_id ID of the user. | |
| 851 | + * @param int $blog_id ID of the blog. | |
| 852 | + * @param int $reassign ID of the user to whom to reassign posts. | |
| 782 | 853 | */ |
| 783 | - public function remove_user_from_blog_handler( $user_id, $blog_id ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable | |
| 854 | + public function remove_user_from_blog_handler( $user_id, $blog_id, $reassign = 0 ) { | |
| 784 | 855 | // User is removed on add, see https://github.com/WordPress/WordPress/blob/0401cee8b36df3def8e807dd766adc02b359dfaf/wp-includes/ms-functions.php#L2114. |
| 785 | 856 | if ( $this->is_add_new_user_to_blog() ) { |
| 786 | 857 | return; |
| 787 | 858 | } |
| 788 | 859 | |
| 789 | - $reassigned_user_id = $this->get_reassigned_network_user_id(); | |
| 860 | + $reassigned_user_id = $reassign; | |
| 790 | 861 | |
| 791 | 862 | // Note that we are in the context of the blog the user is removed from, see https://github.com/WordPress/WordPress/blob/473e1ba73bc5c18c72d7f288447503713d518790/wp-includes/ms-functions.php#L233. |
| 792 | 863 | /** |
| 793 | 864 | * Fires when a user is removed from a blog on a multisite installation |
| @@ -812,66 +883,45 @@ | ||
| 812 | 883 | return $this->is_function_in_backtrace( 'add_new_user_to_blog' ); |
| 813 | 884 | } |
| 814 | 885 | |
| 815 | 886 | /** |
| 816 | - * Whether we're adding an existing user to a blog in this request. | |
| 887 | + * Get the function names that indicate a user is being created. | |
| 817 | 888 | * |
| 818 | 889 | * @access protected |
| 819 | 890 | * |
| 820 | - * @return boolean | |
| 891 | + * @return array | |
| 821 | 892 | */ |
| 822 | - protected function is_add_user_to_blog() { | |
| 823 | - return $this->is_function_in_backtrace( 'add_user_to_blog' ); | |
| 893 | + protected function get_create_user_functions() { | |
| 894 | + return array( | |
| 895 | + 'add_new_user_to_blog', // Used to suppress jetpack_sync_save_user in save_user_cap_handler when user registered on multi site. | |
| 896 | + 'wp_create_user', // Used to suppress jetpack_sync_save_user in save_user_role_handler when user registered on multi site. | |
| 897 | + 'wp_insert_user', // Used to suppress jetpack_sync_save_user in save_user_cap_handler and save_user_role_handler when user registered on single site. | |
| 898 | + ); | |
| 824 | 899 | } |
| 825 | 900 | |
| 826 | 901 | /** |
| 827 | - * Whether we're removing a user from a blog in this request. | |
| 902 | + * Get the function names that indicate a user is being added to a blog. | |
| 828 | 903 | * |
| 829 | 904 | * @access protected |
| 830 | 905 | * |
| 831 | - * @return boolean | |
| 906 | + * @return array | |
| 832 | 907 | */ |
| 833 | - protected function is_delete_user() { | |
| 834 | - return $this->is_function_in_backtrace( array( 'wp_delete_user', 'remove_user_from_blog' ) ); | |
| 908 | + protected function get_add_user_to_blog_functions() { | |
| 909 | + return array( 'add_user_to_blog' ); | |
| 835 | 910 | } |
| 836 | 911 | |
| 837 | 912 | /** |
| 838 | - * Whether we're creating a user or adding a new user to a blog. | |
| 913 | + * Get the function names that indicate a user is being deleted. | |
| 839 | 914 | * |
| 840 | 915 | * @access protected |
| 841 | 916 | * |
| 842 | - * @return boolean | |
| 917 | + * @return array | |
| 843 | 918 | */ |
| 844 | - protected function is_create_user() { | |
| 845 | - $functions = array( | |
| 846 | - 'add_new_user_to_blog', // Used to suppress jetpack_sync_save_user in save_user_cap_handler when user registered on multi site. | |
| 847 | - 'wp_create_user', // Used to suppress jetpack_sync_save_user in save_user_role_handler when user registered on multi site. | |
| 848 | - 'wp_insert_user', // Used to suppress jetpack_sync_save_user in save_user_cap_handler and save_user_role_handler when user registered on single site. | |
| 849 | - ); | |
| 850 | - | |
| 851 | - return $this->is_function_in_backtrace( $functions ); | |
| 919 | + protected function get_delete_user_functions() { | |
| 920 | + return array( 'wp_delete_user', 'remove_user_from_blog' ); | |
| 852 | 921 | } |
| 853 | 922 | |
| 854 | 923 | /** |
| 855 | - * Retrieve the ID of the user the removed user's posts are reassigned to (if any). | |
| 856 | - * | |
| 857 | - * @return int ID of the user that got reassigned as the author of the posts. | |
| 858 | - */ | |
| 859 | - protected function get_reassigned_network_user_id() { | |
| 860 | - $backtrace = debug_backtrace( false ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_debug_backtrace | |
| 861 | - foreach ( $backtrace as $call ) { | |
| 862 | - if ( | |
| 863 | - 'remove_user_from_blog' === $call['function'] && | |
| 864 | - 3 === count( $call['args'] ) | |
| 865 | - ) { | |
| 866 | - return $call['args'][2]; | |
| 867 | - } | |
| 868 | - } | |
| 869 | - | |
| 870 | - return false; | |
| 871 | - } | |
| 872 | - | |
| 873 | - /** | |
| 874 | 924 | * Checks if one or more function names is in debug_backtrace. |
| 875 | 925 | * |
| 876 | 926 | * @access protected |
| 877 | 927 | * |
| @@ -878,9 +928,9 @@ | ||
| 878 | 928 | * @param array|string $names Mixed string name of function or array of string names of functions. |
| 879 | 929 | * @return bool |
| 880 | 930 | */ |
| 881 | 931 | protected function is_function_in_backtrace( $names ) { |
| 882 | - $backtrace = debug_backtrace( false ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_debug_backtrace | |
| 932 | + $backtrace = debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_debug_backtrace | |
| 883 | 933 | if ( ! is_array( $names ) ) { |
| 884 | 934 | $names = array( $names ); |
| 885 | 935 | } |
| 886 | 936 | $names_as_keys = array_flip( $names ); |