#39223 closed enhancement (fixed)
Add a filter to edit $meta array in wpmu_signup_user
Reported by: | Mista-Flo | Owned by: | Mista-Flo |
---|---|---|---|
Milestone: | 4.8 | Priority: | normal |
Severity: | normal | Version: | 3.0 |
Component: | Users | Keywords: | has-patch |
Focuses: | multisite | Cc: |
Description (last modified by )
Hello,
Here's the situation.
In a multisite context, on a new user form in a site of the network, it creates a new signup entry in the signups database table with user informations, and a meta array containing by default 'add_to_blog' => $wpdb->blogid, 'new_role' => $_REQUEST['role']
, so when the user is finnaly activated (with email confirmation or not) the wpmu_activate_user
function is called and use this $meta array.
Imagine you want to extend this behavior and for example, add some user meta in signup to use it for activation. you have the good hook in wpmu_activate_user wpmu_activate_user
where you can use the meta array to do what you want, but you can't filter the $meta array in wpmu_signup_user
to add some usefull data.
For example, for my plugin Multiple Roles : https://wordpress.org/plugins/multiple-roles/ which allow admins to add multiple roles for a given user. In order to handle the multisite behavior, I need to edit this $meta array to pass it my multiple roles array.
So according to me, the best approach will be to add a filter for $meta array in wpmu_signup_user
function just before the database insert like this :
<?php $meta = apply_filters( 'signup_user_meta', $meta, $user, $user_email, $key );
With this given filter, In my plugin, I just have to add those lines, so here a real use of case :
<?php add_filter( 'signup_user_meta', 'mu_add_roles_in_signup', 10, 4 ); // Handle Multisite add_action( 'wpmu_activate_user', 'mu_add_roles_after_activation', 10, 3 ); // Handle Multisite /** * Add multiple roles in meta array on multisite signups database table * * @param $meta * @param $user * @param $user_email * @param $key * * @return mixed */ function mu_add_roles_in_signup( $meta, $user, $user_email, $key ) { $new_roles = ( isset( $_POST['md_multiple_roles'] ) && is_array( $_POST['md_multiple_roles'] ) ) ? $_POST['md_multiple_roles'] : array(); if ( ! empty( $new_roles ) ) { $meta['md_roles'] = $new_roles; } return $meta; } /** * Add multiple roles after user activation * * @param $user_id * @param $password * @param $meta */ function mu_add_roles_after_activation( $user_id, $password, $meta ) { if ( ! empty( $meta['md_roles'] ) ) { $this->model->update_roles( $user_id, $meta['md_roles'] ); } }
By the way, if you're okay with my following patch, I would benefit from this other ticket : #38781 which avoid $meta array to be serialized when passed to hooks, in fact, I'm using its patch to make mine.
Attachments (4)
Change History (17)
#2
@
8 years ago
This seems fine to me.
Since the meta data couldn't be accessed previously, I don't see harm in serializing it now either.
#3
@
8 years ago
Without this patch merged in the core, in my plugin, I should do this (code from my last plugin release 24 december) :
<?php add_action( 'after_signup_user', 'mu_add_roles_in_signup_meta', 10, 4 ); public function mu_add_roles_in_signup_meta( $user, $user_email, $key, $meta ) { if ( isset( $_POST['md_multiple_roles_nonce'] ) && ! wp_verify_nonce( $_POST['md_multiple_roles_nonce'], 'update-md-multiple-roles' ) ) { return; } if ( ! $this->model->can_update_roles() ) { return; } $new_roles = ( isset( $_POST['md_multiple_roles'] ) && is_array( $_POST['md_multiple_roles'] ) ) ? $_POST['md_multiple_roles'] : array(); if ( empty( $new_roles ) ) { return; } global $wpdb; // Get user signup // Suppress errors in case the table doesn't exist $suppress = $wpdb->suppress_errors(); $signup = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->signups} WHERE user_email = %s", $user_email ) ); $wpdb->suppress_errors( $suppress ); if ( empty( $signup ) || is_wp_error( $signup ) ) { return new WP_Error( 'md_get_user_signups_failed' ); } // Add multiple roles to a new array in meta var $meta = maybe_unserialize( $meta ); $meta['md_roles'] = $new_roles; $meta = maybe_serialize( $meta ); // Update user signup with good meta $where = array( 'signup_id' => (int) $signup->signup_id ); $where_format = array( '%d' ); $formats = array( '%s' ); $fields = array( 'meta' => $meta ); $result = $wpdb->update( $wpdb->signups, $fields, $where, $formats, $where_format ); // Check for errors if ( empty( $result ) && ! empty( $wpdb->last_error ) ) { return new WP_Error( 'md_update_user_signups_failed' ); } }
That means, get the signup from the database, update the meta array with the data I want to add, update the signup in the database, so it's painfull and not sure (bugs are possible), btw, the code is inspired by the WP signup plugin of @johnjamesjacoby
This ticket was mentioned in Slack in #core-multisite by florian-tiar. View the logs.
8 years ago
#5
@
8 years ago
- Milestone changed from Awaiting Review to 4.8
- Owner set to Mista-Flo
- Status changed from new to assigned
This looks like a useful enhancement to me as well.
The patch looks good except for a few documentation issues:
- The filter description should be in 3rd person singular.
- The filter description should describe what is being filtered and thus should start with "Filters ...", for example "Filters the metadata for a user signup.".
- The description for the
$meta
parameter should rather say "Default empty array." instead of a full sentence in the end. - The description for the
$key
parameter is missing a dot. - Since the data is serialized, an additional line could possibly included as extended description to indicate this to developers, maybe something like "The metadata will be serialized prior to storing it in the database.".
All kind of nitpicking, but would you update the patch @Mista-Flo? :)
The last thing we might think about is whether signup_user_meta
is the best name for the filter. I'm not opposed to it, but just to throw something in the room, user_signup_meta
or wpmu_signup_user_meta
(the latter would give parity with the function although I don't like the wpmu prefix) would be alternatives. What do you think?
#6
@
8 years ago
Thanks for your review :)
Totaly agree with your recommendations, I have updated the PHPdoc.
Concerning the filter name, I'm not sure about the best name, I tried to be consistent with the other hook of the function named "after_signup_user" but it's not the best too maybe. I also like the wpmu_signup_user_meta name. Is there any recent multisite hook added that we can compare ?
#9
follow-up:
↓ 10
@
8 years ago
- Keywords needs-refresh removed
I have refreshed the patch. And I have chosen a new name for the filter, tell me if it's good : "user_signup_meta"
#10
in reply to:
↑ 9
@
8 years ago
Replying to Mista-Flo:
And I have chosen a new name for the filter, tell me if it's good : "user_signup_meta"
I think signup_user_meta
is more consistent with other filters like after_signup_user
or wpmu_signup_user_notification
.
While we're at it, let's also add signup_site_meta
to wpmu_signup_blog()
for consistency between two functions, like after_signup_site
mirrors after_signup_user
in [34112].
@
8 years ago
add signup_site_meta filter to wpmu_signup_blog() and keep consistency with filter names
Add signup_user_meta filter to edit meta array in wp_signup_user function