[WP] Fully Customized User Management with ACF & Gravity Forms
The core idea of any interactive website is to respond to the user’s actions, which is performed with several steps: collecting inputs, processing then visualizing. Unfortunately, this could not be fully controlled/customized only with WordPress core.
ACF makes it much easier to expand WordPress functionalities, allows us to take full control of not only posts but users (and more…). GForms provides a security & convenient layer to collect user’s info.
By using hooks, you can build fully customized site’s functions like User Management* (login, register, logs,… – totally Front-End), Shopping Cart (easy implemented with cookies), User Thread New Post like Forums, … in a secured & comfortable way, without having to use a bunch of additional plugins for each feature.
Motivation
User Management is always a big disadvantage of using WordPress. This article will give you the solution to some key features such as Register Page, User Post Submit (both front-end), discussing issues about security and other ideas.
Front-End Login Form
If you are looking for a Front-End Login Page, WP provides:
$args = array(
'redirect' => home_url(),
'form_id' => 'loginform-custom',
'label_username' => __( 'Username' ),
'label_password' => __( 'Password' ),
'label_remember' => __( 'Remember Me' ),
'label_log_in' => __( 'Log in' ),
'remember' => true
);
wp_login_form( $args );
Or more: https://codex.wordpress.org/Function_Reference/wp_login_form
Now we can totally disable /wp-admin/ for those who are not admins (disable user’s back-end). I picked up this code somewhere, forgive me not mentioning the source (I don’t remember): these lines use ‘admin_init‘ hook.
function wpse66093_no_admin_access()
{
$redirect = isset( $_SERVER['HTTP_REFERER'] ) ? $_SERVER['HTTP_REFERER'] : home_url( '/' );
if ( !current_user_can( 'delete_users' ) )
exit( wp_redirect( $redirect ) );
}
add_action( 'admin_init', 'wpse66093_no_admin_access', 100 );
For authorized /wp-admin/
access (for us), we use the login form to log in, then go /wp-admin/
.
Custom Fields & Registration Form
Create Custom Fields
With ACF you can easily create User’s extra fields. Let’s say you created 2 more fields: ‘address‘, ‘phone_number‘ (You should choose “Rule” equal to “All” when creating new Field Group). These values are stored in user’s meta data table.
Create a Register Form
Create the form using GForms, remember required fields like ‘user_login‘ (username), ‘user_pass‘ & our 2 custom fields. Below I used: (Created with GForms)
- username
- password
- retype
- address
- phone_number Respectively.
Reg Form Validation?
Now we face the problem to make sure that the chosen username, email are not used, and if you are careful enough to have created a “Retype Password” input in your reg form then this will be a problem.
We solve this by using GF hook ‘gform_validation‘, this is how we validate username. My Reg Form Id is 2, so the hook name will be ‘gform_validation_2‘:
add_filter( 'gform_validation_2', 'validate_reg');
function validate_reg( $validation_result ) {
$form = $validation_result['form'];
$user_name = rgpost( "input_1" );
if (username_exists($user_name)) {
$form['fields']['1']['failed_validation'] = true;
$form['fields']['1']['validation_message'] = 'Username invalid!';
$validation_result['is_valid'] = false;
}
$validation_result['form'] = $form;
return $validation_result;
}
We use ‘gform_after_submission‘ hook. This is called after a successful submission.
add_action( 'gform_after_submission', 'gform_after_submit', 10, 2 );
function gform_after_submit( $entry, $form ) {
if ($form['id'] == 2) { // that way, u can implement 'id' == 3, 4, ... below without anothor add_action
$userdata = array(
'user_login' => $entry['1'],
'user_email' => $entry['2'],
'user_pass' => $entry['3'],
'last_name' => $entry['5']
);
$user_id = wp_insert_user( $userdata ); // DONE
if( !is_wp_error($user_id) ) {
// Update meta for custom values
update_user_meta($user_id, 'address', $entry['6'] );
update_user_meta($user_id, 'phone_number', $entry['7'] );
}
}
}
It’s that easy!
Notice: Now you can (and should) DISABLE New User Registration in WordPress General Options. Our Reg Form will stay fine(due to our wp_insert_user() function)! Then put the reg form a Captcha or Recaptcha Field to prevent spamming.
Password Change Form
Same way with Registration Page. This time we change it directly when validating form. Normally, I created 3 inputs (old one, new one and retype), my Form ID is 4, change ‘gform_validation_4‘ so it fit yours.
add_filter( 'gform_validation_4', 'validate_change_pwd');
function validate_change_pwd( $validation_result ) {
$form = $validation_result['form'];
$user_pwd = rgpost( "input_1" );
$field_value1 = rgpost( "input_2" );
$field_value2 = rgpost( "input_3" );
if (!is_user_logged_in()) {
return $validation_result;
}
global $current_user;
get_currentuserinfo();
$user = get_user_by( 'login', $current_user->user_login );
if (!$user || !wp_check_password( $user_pwd, $user->data->user_pass, $user->ID)) {
$form['fields']['1']['failed_validation'] = true;
$form['fields']['1']['validation_message'] = 'Password Incorrect!';
$validation_result['is_valid'] = false;
}
}
if ($field_value1!=$field_value2) {
$form['fields']['2']['failed_validation'] = true;
$form['fields']['2']['validation_message'] = 'Password mismatched!';
$form['fields']['3']['failed_validation'] = true;
$form['fields']['3']['validation_message'] = 'Password mismatched!';
$validation_result['is_valid'] = false;
}
}
if ($validation_result['is_valid'] == true) {
wp_set_password($field_value1, $user->ID);
}
$validation_result['form'] = $form;
return $validation_result;
}
I believe with these ideas, we could get most of the site’s functions to work as we wish. I’ll be glad if you let me know what you’ve done.