-
Notifications
You must be signed in to change notification settings - Fork 177
Delete user meta on plugin uninstall #637
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
423bb2d
9119613
8ea9cd3
129cbfb
369ead9
638f6d1
f5f75d2
6f50ece
5d3b529
9297b60
8d1972f
f4d463d
72ee3e0
86bc007
077c220
c152d19
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -132,13 +132,67 @@ public static function add_hooks( $compat ) { | |||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||
| * For each provider, include it and then instantiate it. | ||||||||||||||||||||||||||
| * Delete all plugin data on uninstall. | ||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||
| * @since 0.1-dev | ||||||||||||||||||||||||||
| * @return void | ||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||
| public static function uninstall() { | ||||||||||||||||||||||||||
| // Keep this updated as user meta keys are added or removed. | ||||||||||||||||||||||||||
| $user_meta_keys = array( | ||||||||||||||||||||||||||
| self::PROVIDER_USER_META_KEY, | ||||||||||||||||||||||||||
| self::ENABLED_PROVIDERS_USER_META_KEY, | ||||||||||||||||||||||||||
| self::USER_META_NONCE_KEY, | ||||||||||||||||||||||||||
| self::USER_RATE_LIMIT_KEY, | ||||||||||||||||||||||||||
| self::USER_FAILED_LOGIN_ATTEMPTS_KEY, | ||||||||||||||||||||||||||
| self::USER_PASSWORD_WAS_RESET_KEY, | ||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| $option_keys = array(); | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| foreach ( self::get_providers_classes() as $provider_class ) { | ||||||||||||||||||||||||||
| // Merge with provider-specific user meta keys. | ||||||||||||||||||||||||||
| if ( method_exists( $provider_class, 'uninstall_user_meta_keys' ) ) { | ||||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||||
| $user_meta_keys = array_merge( | ||||||||||||||||||||||||||
| $user_meta_keys, | ||||||||||||||||||||||||||
| call_user_func( array( $provider_class, 'uninstall_user_meta_keys' ) ) | ||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||
| } catch ( Exception $e ) { | ||||||||||||||||||||||||||
| // Do nothing. | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| // Merge with provider-specific option keys. | ||||||||||||||||||||||||||
| if ( method_exists( $provider_class, 'uninstall_options' ) ) { | ||||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||||
| $option_keys = array_merge( | ||||||||||||||||||||||||||
| $option_keys, | ||||||||||||||||||||||||||
| call_user_func( array( $provider_class, 'uninstall_options' ) ) | ||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||
| } catch ( Exception $e ) { | ||||||||||||||||||||||||||
| // Do nothing. | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| // Delete options first since that is faster. | ||||||||||||||||||||||||||
| if ( ! empty( $option_keys ) ) { | ||||||||||||||||||||||||||
| foreach ( $option_keys as $option_key ) { | ||||||||||||||||||||||||||
| delete_option( $option_key ); | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| foreach ( $user_meta_keys as $meta_key ) { | ||||||||||||||||||||||||||
| delete_metadata( 'user', null, $meta_key, null, true ); | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||
| * Get the registered providers of which some might not be enabled. | ||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||
| * @return array | ||||||||||||||||||||||||||
| * @return array List of provider keys and paths to class files. | ||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||
| public static function get_providers() { | ||||||||||||||||||||||||||
| public static function get_providers_registered() { | ||||||||||||||||||||||||||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Introducing dedicated methods for retrieving:
|
||||||||||||||||||||||||||
| $providers = array( | ||||||||||||||||||||||||||
| 'Two_Factor_Email' => TWO_FACTOR_DIR . 'providers/class-two-factor-email.php', | ||||||||||||||||||||||||||
| 'Two_Factor_Totp' => TWO_FACTOR_DIR . 'providers/class-two-factor-totp.php', | ||||||||||||||||||||||||||
|
|
@@ -150,29 +204,29 @@ public static function get_providers() { | |||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||
| * Filter the supplied providers. | ||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||
| * This lets third-parties either remove providers (such as Email), or | ||||||||||||||||||||||||||
| * add their own providers (such as text message or Clef). | ||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||
| * @param array $providers A key-value array where the key is the class name, and | ||||||||||||||||||||||||||
| * the value is the path to the file containing the class. | ||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||
| $providers = apply_filters( 'two_factor_providers', $providers ); | ||||||||||||||||||||||||||
| $additional_providers = apply_filters( 'two_factor_providers', $providers ); | ||||||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @kasparsd Using the same existing filter seems wrong here. Shouldn't this be a new filter so you only get the additional providers? two-factor/class-two-factor-core.php Lines 264 to 275 in 6a95e7f
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @kasparsd This still seems wrong to me and is now released. Why running the filter twice?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @ocean90 Sorry for missing your comment here. I'll create a patch to address this.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here is a pull request that removes the duplicate #651. |
||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| // FIDO U2F is PHP 5.3+ only. | ||||||||||||||||||||||||||
| if ( isset( $providers['Two_Factor_FIDO_U2F'] ) && version_compare( PHP_VERSION, '5.3.0', '<' ) ) { | ||||||||||||||||||||||||||
| unset( $providers['Two_Factor_FIDO_U2F'] ); | ||||||||||||||||||||||||||
| trigger_error( // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_trigger_error | ||||||||||||||||||||||||||
| sprintf( | ||||||||||||||||||||||||||
| /* translators: %s: version number */ | ||||||||||||||||||||||||||
| __( 'FIDO U2F is not available because you are using PHP %s. (Requires 5.3 or greater)', 'two-factor' ), // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped | ||||||||||||||||||||||||||
| PHP_VERSION | ||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||
| // Merge them with the default providers. | ||||||||||||||||||||||||||
| if ( ! empty( $additional_providers ) ) { | ||||||||||||||||||||||||||
| return array_merge( $providers, $additional_providers ); | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||
| * For each filtered provider, | ||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||
| return $providers; | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||
| * Get the classnames for all registered providers. | ||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||
| * Note some of these providers might not be enabled. | ||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||
| * @return array List of provider keys and classnames. | ||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||
| private static function get_providers_classes() { | ||||||||||||||||||||||||||
| $providers = self::get_providers_registered(); | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| foreach ( $providers as $provider_key => $path ) { | ||||||||||||||||||||||||||
| require_once $path; | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
|
|
@@ -189,9 +243,56 @@ public static function get_providers() { | |||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||
| * Confirm that it's been successfully included before instantiating. | ||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||
| if ( class_exists( $class ) ) { | ||||||||||||||||||||||||||
| if ( method_exists( $class, 'get_instance' ) ) { | ||||||||||||||||||||||||||
| $providers[ $provider_key ] = $class; | ||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||
| unset( $providers[ $provider_key ] ); | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| return $providers; | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||
| * Get all enabled two-factor providers. | ||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||
| * @since 0.1-dev | ||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||
| * @return array | ||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||
| public static function get_providers() { | ||||||||||||||||||||||||||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is now much shorter as it can now get the class names for all enabled providers from the helpers. |
||||||||||||||||||||||||||
| $providers = self::get_providers_registered(); | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||
| * Filter the supplied providers. | ||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||
| * This lets third-parties either remove providers (such as Email), or | ||||||||||||||||||||||||||
| * add their own providers (such as text message or Clef). | ||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||
| * @param array $providers A key-value array where the key is the class name, and | ||||||||||||||||||||||||||
| * the value is the path to the file containing the class. | ||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||
| $providers = apply_filters( 'two_factor_providers', $providers ); | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| // FIDO U2F is PHP 5.3+ only. | ||||||||||||||||||||||||||
| if ( isset( $providers['Two_Factor_FIDO_U2F'] ) && version_compare( PHP_VERSION, '5.3.0', '<' ) ) { | ||||||||||||||||||||||||||
| unset( $providers['Two_Factor_FIDO_U2F'] ); | ||||||||||||||||||||||||||
| trigger_error( // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_trigger_error | ||||||||||||||||||||||||||
| sprintf( | ||||||||||||||||||||||||||
| /* translators: %s: version number */ | ||||||||||||||||||||||||||
| __( 'FIDO U2F is not available because you are using PHP %s. (Requires 5.3 or greater)', 'two-factor' ), // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped | ||||||||||||||||||||||||||
| PHP_VERSION | ||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| // Map provider keys to classes so that we can instantiate them. | ||||||||||||||||||||||||||
| $providers = array_intersect_key( self::get_providers_classes(), $providers ); | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| foreach ( $providers as $provider_key => $provider_class ) { | ||||||||||||||||||||||||||
| if ( method_exists( $provider_class, 'get_instance' ) ) { | ||||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||||
| $providers[ $provider_key ] = call_user_func( array( $class, 'get_instance' ) ); | ||||||||||||||||||||||||||
| $providers[ $provider_key ] = call_user_func( array( $provider_class, 'get_instance' ) ); | ||||||||||||||||||||||||||
| } catch ( Exception $e ) { | ||||||||||||||||||||||||||
| unset( $providers[ $provider_key ] ); | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -165,4 +165,24 @@ public static function sanitize_code_from_request( $field, $length = 0 ) { | |
|
|
||
| return (string) $code; | ||
| } | ||
|
|
||
| /** | ||
| * Return the user meta keys that need to be deletated on plugin uninstall. | ||
| * | ||
| * @return array | ||
| */ | ||
| public static function uninstall_user_meta_keys() { | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These are the two methods that providers can report their user meta key usage. |
||
| return array(); | ||
| } | ||
|
|
||
| /** | ||
| * Return the option keys that need to be deleted on plugin uninstall. | ||
| * | ||
| * Note: this method doesn't have access to the instantiated provider object. | ||
| * | ||
| * @return array | ||
| */ | ||
| public static function uninstall_options() { | ||
| return array(); | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
WP core uses this for deleting all post meta
delete_post_meta_by_key()by key so we can re-use it as well.