I have a registeration form with some custom fields and need to register users with Wordpress REST api,
$('#user_register_form').submit(function(e){
e.preventDefault();
var form = $(this),
rest = new DwREST();
rest.registerUser({
first_name: '',
last_name: '',
username: 'amin',
name : 'amin',
email : 'aaaa#amin.ev',
password: '11111',
// passwrod2: '11111' -confirm password field
// custom_field1: ''
// ....
}, function( res ){
console.log( res );
});
});
The user registeration works fine but the problem is i can't confirm wether password repeat matches or not, i searched a lot and didn't find an action to modify to /users/ validation
the second question is is it possible to automatically login user created with REST api after registeration?
i appreciate any help.
I searched in rest-api source codes, sadly i didn't find any proper hook to do what i needed, there's just a rest_pre_insert_user hook which getting it to do what i intend to do is a bit tricky, but here's the work around, in case some one has the same problem:
add_filter('rest_pre_insert_user', function( $user, $request ){
$params = $request->get_params();
if( $params['password'] !== $params['password2'] ) {
$error = new WP_Error( 'rest_no_matching_passwords', __( 'Passwords don\'t match' ), array( 'status' => 400 ) );
foreach( $error->error_data as $data ) {
http_response_code( $data['status'] );
}
header('Content-Type: application/json; charset=utf-8;');
foreach( $error->errors as $key => $val ){
$json = json_encode([
'code' => $key,
'type' => 'error',
'message' => $val[0]
]);
}
die( $json );
}
return $user;
}, 10, 2 );
Reference
Related
I am using elementor submissions to collect data from users and I need to show users a reference ID (DB ID of their submission) on Thank You page.
I have set up https://developers.elementor.com/forms-api/#Form_New_Record_Action and have access Form_Record class instance but there isn't any method to directly access DB ID. The documentation doesn't provide much detail and I am not even sure if this even provide access to DB ID.
New Record action
add_action( 'elementor_pro/forms/new_record', function( $record, $handler ) {
//make sure its our form
$form_name = $record->get_form_settings( 'form_name' );
// Replace MY_FORM_NAME with the name you gave your form
if ( 'New Form' !== $form_name ) {
return;
}
$raw_fields = $record->get( 'fields' );
$fields = [];
foreach ( $raw_fields as $id => $field ) {
$fields[ $id ] = $field['value'];
}
$handler->add_response_data( true, $raw_fields );
}, 10, 2 );
On Submit success event
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
jQuery( document ).ready(function( $ ){
jQuery( document ).on('submit_success', function(event, response){
console.log(response.data);
});
});
</script>
I made a plugin to allow wordpress login with external api.
Everything works, now what I have to do is that when a user logs in for the first time, the plugin checks to see if it is already present on wp, and where it was not already present, it creates a new user by taking behind username, email and password.
The new user is created but I would like it to bring with it also the id field from the external api saving it in an ACF field.
This is the code created so far:
function au_auth($user, $username, $password)
{
$options = get_option('au_options');
$endpoint = $options['au_apiurl'];
$user_email_key = 'email';
$password_key = 'password';
// Makes sure there is an endpoint set as well as username and password
if (!$endpoint || $user !== null || (empty($username) && empty($password))) {
return false;
}
// Check user exists locally
$user_exists = wp_authenticate_username_password(null, $username, $password);
if ($user_exists && $user_exists instanceof WP_User) {
$user = new WP_User($user_exists);
return $user;
}
// Build the POST request
$login_data = array(
$user_email_key => $username,
$password_key => $password
);
$auth_args = array(
'method' => 'POST',
'headers' => array(
'Content-type: application/x-www-form-urlencoded'
),
'sslverify' => false,
'body' => $login_data
);
$response = wp_remote_post($endpoint, $auth_args);
// Token if success; Not used right now
$response_token = json_decode($response['response']['token'], true);
$response_code = $response['response']['code'];
if ($response_code == 400) {
// User does not exist, send back an error message
$user = new WP_Error('denied', __("<strong>Error</strong>: Your username or password are incorrect."));
} else if ($response_code == 200) {
// External user exists, try to load the user info from the WordPress user table
$userobj = new WP_User();
// Does not return a WP_User object but a raw user object
$user = $userobj->get_data_by('email', $username);
if ($user && $user->ID) {
// Attempt to load the user with that ID
$user = new WP_User($user->ID);
}
} else {
// The user does not currently exist in the WordPress user table.
// Setup the minimum required user information
$userdata = array(
'user_email' => $username,
'user_login' => $username,
'user_pass' => $password
);
// A new user has been created
$new_user_id = wp_insert_user($userdata);
// Assign editor role to the new user (so he can access protected articles)
wp_update_user(
array(
'ID' => $new_user_id,
'role' => 'editor'
)
);
// Load the new user info
$user = new WP_User ($new_user_id);
}
}
// Useful for times when the external service is offline
remove_action('authenticate', 'wp_authenticate_username_password', 20);
return $user;
}
Anyone have any way how to help me?
Resolved! I hope this will help those who have found themselves in the same situation as me:
add_filter('authenticate', 'au_auth', 10, 3);
add_filter('register_new_user', 'au_registration', 10, 3);
// add_filter('profile_update', 'au_profile_update', 10, 3);
// add_filter('edit_user_profile_update', 'au_profile_edit', 10, 3);
function au_auth($user, $username, $password)
{
$options = get_option('au_options');
$endpoint = $options['au_apiurl'];
// Makes sure there is an endpoint set as well as username and password
if (!$endpoint || $user !== null || (empty($username) && empty($password))) {
return false;
}
$auth_args = [
'method' => 'POST',
'headers' => [
'Content-type: application/x-www-form-urlencoded',
],
'sslverify' => false,
'body' => [
'email' => $username,
'password' => $password,
],
];
$response = wp_remote_post($endpoint, $auth_args);
// Token if success; Not used right now
$response_token = json_decode($response['response']['token'], true);
$body = json_decode($response['body'], true);
$response_status_code = $response['response']['code'];
$success = $body !== 'KO';
if (!$success) {
// User does not exist, send back an error message
$user = new WP_Error('denied', __('<strong>Error</strong>: Your username
or password are incorrect.'));
} elseif ($success) {
$idExternal = $body['Id'];
$nome = $body['Name'];
$cognome = $body['Surname'];
$email = $body['Email'];
$userobj = new WP_User();
$user = $userobj->get_data_by('email', $email);
if ($user && $user->ID) {
$user = new WP_User($user->ID);
} else {
$userdata = [
'user_email' => $email,
'user_login' => join(' ', [$name, $surname]),
'user_pass' => '----',
];
$new_user_id = wp_insert_user($userdata);
$new_user_composite_id = 'user_' . $new_user_id;
update_field('field_60084ad3970a8', $idExternal, $new_user_composite_id);
update_field('field_5f22ca201c7b0', $name, $new_user_composite_id);
update_field('field_5f22ccd498f40', $surname, $new_user_composite_id);
update_field('field_5f22ce7b7c1db', $email, $new_user_composite_id);
$user = new WP_User($new_user_id);
}
}
remove_action('authenticate', 'wp_authenticate_username_password', 20);
return $user;
}
hey i just creat a rest api in wordpress for login its work on old user but when i creat a new user its show invalid user name 400 error
my code is its work on old user but error in new user like this
{"code":400,"msg":"Invalid username"}
and in register api how to convert user password to wordpress hash password
add_action( 'rest_api_init', 'register_api_hooks' );
function register_api_hooks() {
register_rest_route(
'custom-plugin', '/login/',
array(
'methods' => 'GET',
'callback' => 'login',
)
);
}
function login($request){
$creds = array();
$creds['user_login'] = $request["username"];
$creds['user_password'] = md5($request["password"]);
$creds['remember'] = true;
$user = wp_signon( $creds, false );
if ( is_wp_error($user) )
{
$user->get_error_message();
return $myArray = ['code'=>400, 'msg'=>'Invalid username'];
}
else
{
$token = wp_get_session_token();
return $myArray = ['code'=>200, 'msg'=>'Success', 'user'=> $user ,'token'=> $token];
}
}
add_action( 'after_setup_theme', 'custom_login' );
I would like register_rest_field to return a certain field for a user only when a specific user is being requested (i.e. the request is /user/$user_id) -- not when /users or other endpoints are used.
One way I can think of to sort of do this would be to check the API request URL in the register_rest_field function and conditionally change the return value depending on the endpoint, but I don't know how to access that URL.
What would be the best way to do this?
You can use $request->get_url_params(); to check if request has $user_id or not.
Ref:
https://developer.wordpress.org/rest-api/extending-the-rest-api/adding-custom-endpoints/#arguments
<?php
add_filter( 'rest_prepare_user', 'mo_user_json', 10, 3);
function mo_user_json( $data, $user, $request ) {
$response_data = $data->get_data();
// for remove fields
unset($response_data['avatar_urls']);
unset($response_data['url']);
unset($response_data['description']);
// array user meta
$usermetas = [];
$metas = [
'field1',
'field2',
'field3',
'field4',
'field5',
'field6',
];
foreach ($metas as $meta) {
if(!empty(get_user_meta( $user->ID, $meta))){
$info = get_user_meta( $user->ID, $meta);
$usermetas[$meta] = $info[0];
}
}
// format json
$nodes = [
'field1' => $usermetas['field1']
'field2' => $usermetas['field2']
'field3' => $usermetas['field3'],
'field4' => [
'field4' => $usermetas['field4']
'field5' => $usermetas['field5']
'field6' => $usermetas['field6']
]
];
foreach ($nodes as $key => $node) {
$response_data['meta'][$key] = $node;
}
// add fields formated in json
$data->set_data( $response_data );
return $data;
}
this is my following code for custom payment gateway.
when i am trying to place order at check out page it shows connecting to server exception that was created by me. when we check parameters in firebug, it only shows checkout and response is failure.
I am try to send request parameters to gateway URL but not getting success.
Please tell me where i was done the mistake?
Thanks In Advance..
public function process_payment( $order_id ) {
global $woocommerce;
// Get this Order's information so that we know
// who to charge and how much
$customer_order = new WC_Order( $order_id );
// Are we testing right now or is it a real transaction
$environment = ( $this->environment == "yes" ) ? 'TRUE' : 'FALSE';
// Decide which URL to post to
$environment_url = ( "FALSE" == $environment )
? 'https://www.qpayindia.com/wwws/Payment/PaymentDetails.aspx'
: 'https://www.qpayindia.com/wwws/Payment/PaymentDetails.aspx';
$QPayID = $this->QPayID.'`'.$this->order_total;
// This is where the fun stuff begins
$payload = array(
// Authorize.net Credentials and API Info
"QPayID" => $this->QPayID.'`'.$this->order_total,
"QPayPWD" => $this->QPayPWD,
"CaseNumber" => $this->CaseNumber,
"Currency" => $this->Currency,
"TransactionType" => $this->TransactionType,
"ResponseURL" => $this->ResponseURL,
"Mode" => $environment,
"Amount" => $customer_order->order_total,
"OrderID" => $customer_order->get_order
);
// Send this payload to Authorize.net for processing
$response = wp_remote_post( $environment_url, array(
'method' => 'POST',
'body' => http_build_query( $payload ),
'timeout' => 90,
'sslverify' => false,
) );
if ( is_wp_error( $response ) )
throw new Exception( __( 'We are currently experiencing problems trying to connect to this payment gateway. Sorry for the inconvenience.', 'spyr-authorizenet-aim' ) );
else
{
throw new Exception( __( 'Connecting to server.', 'spyr-authorizenet-aim' ) );
}
if ( empty( $response['body'] ) )
throw new Exception( __( 'Authorize.net\'s Response was empty.', 'spyr-authorizenet-aim' ) );
// Retrieve the body's resopnse if no errors found
$response_body = wp_remote_retrieve_body( $response );
// Parse the response into something we can read
foreach ( preg_split( "/\r?\n/", $response_body ) as $line ) {
$resp = explode( "|", $line );
}
// Get the values we need
$r['ResponseCode'] = $resp[0];
$r['Message'] = $resp[1];
//$r['response_reason_code'] = $resp[2];
//$r['Message'] = $resp[3];
// Test the code to know if the transaction went through or not.
// 1 or 4 means the transaction was a success
if ( ( $r['ResponseCode'] == 100 ) ) {
// Payment has been successful
$customer_order->add_order_note( __( 'Authorize.net payment completed.', 'spyr-authorizenet-aim' ) );
// Mark order as Paid
$customer_order->payment_complete();
// Empty the cart (Very important step)
$woocommerce->cart->empty_cart();
// Redirect to thank you page
return array(
'result' => 'success',
'redirect' => $this->get_return_url( $customer_order ),
);
} else {
// Transaction was not succesful
// Add notice to the cart
wc_add_notice( $r['Message'], 'error' );
// Add note to the order for your reference
$customer_order->add_order_note( 'Error: '. $r['Message'] );
}
}
// Validate fields
public function validate_fields() {
return true;
}
I think you've confused the logic here:
if ( is_wp_error( $response ) )
throw new Exception(....);
else
{
throw new Exception(....);
}
So you throw an Exception regardless of the reponse, and this way you never reach the code further down. An Exception always breaks the current flow, and unless caught with "try...catch", it breaks out of the program. For a quick test, try this (mind the curly brackets by the way):
if ( is_wp_error( $response ) ) {
throw new Exception( __( 'We are currently experiencing problems trying to connect to this payment gateway. Sorry for the inconvenience.', 'spyr-authorizenet-aim' ) );
} else if ( empty( $response['body'] ) ) {
throw new Exception( __( 'Authorize.net\'s Response was empty.', 'spyr-authorizenet-aim' ) );
}
// Retrieve the body's resopnse if no errors found
// ...