Get Elementor Submission DB ID - wordpress

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>

Related

Custom Redirect to Page With URL Parameters Using Elementor

I'm trying to redirect to another page with url parameters using Elementor form redirect action.
add_action( 'elementor_pro/forms/new_record', function( $record, $ajax_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 ( 'test_form' !== $form_name ) {
return;
}
$raw_fields = $record->get( 'fields' );
$fields = [];
foreach ( $raw_fields as $id => $field ) {
$fields[ $id ] = $field['value'];
}
global $wpdb, $post;
// Get Current Url Slug
$post_slug = $post->post_name;
//redirect URL to be setup
$redirect_url = '/test2/'.$post_slug.'?f_name='.$fields['f_name'];
//add to record the redirect URL
$redirect_to = $record->replace_setting_shortcodes( $redirect_url );
// Set redirect action to handler
$handler->add_response_data( 'redirect_url', $redirect_to );
}, 10, 2);
It when trying to submit the form it shows an error message of "error" and in the debug log it shows "PHP Fatal error: Uncaught Error: Call to a member function add_response_data() on null"
I tried this code
add_action( 'elementor_pro/forms/new_record', function( $record, $ajax_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 ( 'test_form' !== $form_name ) {
return;
}
$raw_fields = $record->get( 'fields' );
$fields = [];
foreach ( $raw_fields as $id => $field ) {
$fields[ $id ] = $field['value'];
}
global $wpdb, $post;
// Get Current Url Slug
$post_slug = $post->post_name;
//redirect URL to be setup
$redirect_url = '/test2/'.$post_slug.'?f_name='.$fields['f_name'];
//add to record the redirect URL
$redirect_to = $record->replace_setting_shortcodes( $redirect_url );
// Set redirect action to handler
$handler->add_response_data( 'redirect_url', $redirect_to );
}, 10, 2);
And I was expecting after the submission of the form to be redirected to http://example.com/test2/post-slug?f_name=test

WooCommerce, disable shipping methods based on email [duplicate]

In WooCommerce, I have set different shipping methods, but one in particular must be exclusive for companies.
For this I am using the following code:
add_filter( 'woocommerce_package_rates', array( $this, 'package_rates' ), 10, 2 );
public function package_rates( $rates, $package ) {
$company_rate_id = 'flat_rate:7';
if(!empty(WC()->customer->get_billing_company())){
$company_rates = $rates[ $company_rate_id ];
$rates = array( $company_rate_id => $company_rates );
}else{
unset( $rates[ $company_rate_id ] );
}
return $rates;
}
The solution works, but only if the billing company already exist and is saved in the database. So if a customer updates this information on the checkout page, it doesn't work.
A possible solution would be to save this field live (billing_company).
I tried the following function:
add_filter( 'woocommerce_checkout_fields' , 'trigger_update_checkout_on_change' );
function trigger_update_checkout_on_change( $fields ) {
$fields['billing']['billing_company']['class'][] = 'update_totals_on_change';
return $fields;
}
This updates the shipping method, the problem is that again, the field is not saved in the database and the package_rates() function can not find it live.
This is a bit more complicated than that… jQuery and Ajax code are required to allow showing/hiding shipping methods based on a checkout field user input.
The following code will enable show/hide pre defined shipping methods based on checkout billing company field:
// Conditionally show/hide shipping methods
add_filter( 'woocommerce_package_rates', 'shipping_package_rates_filter_callback', 100, 2 );
function shipping_package_rates_filter_callback( $rates, $package ) {
// The defined rate id
$company_rate_id = 'flat_rate:7';
if( WC()->session->get('company' ) === '1' ) {
$rates = array( $company_rate_id => $rates[ $company_rate_id ] );
} else {
unset( $rates[ $company_rate_id ] );
}
return $rates;
}
// function that gets the Ajax data
add_action( 'wp_ajax_get_customer_company', 'wc_get_customer_company' );
add_action( 'wp_ajax_nopriv_get_customer_company', 'wc_get_customer_company' );
function wc_get_customer_company() {
if ( isset($_POST['company']) && ! empty($_POST['company']) ){
WC()->session->set('company', '1' );
} else {
WC()->session->set('company', '0' );
}
die(); // (required)
}
// The Jquery Ajax script
add_action( 'wp_footer', 'custom_checkout_script' );
function custom_checkout_script() {
if( WC()->session->__isset('company') )
WC()->session->__unset('company');
// Only on checkout when billing company is not defined
if( is_checkout() && ! is_wc_endpoint_url() ):
?>
<script type="text/javascript">
jQuery( function($){
if (typeof wc_checkout_params === 'undefined')
return false;
var fieldId = 'input#billing_company';
function companyTriggerAjax( company ){
$.ajax({
type: 'POST',
url: wc_checkout_params.ajax_url,
data: {
'action': 'get_customer_company',
'company': company,
},
success: function (result) {
// Trigger refresh checkout
$('body').trigger('update_checkout');
}
});
}
// On start
if( $(fieldId).val() != '' ) {
companyTriggerAjax( $(fieldId).val() );
}
// On change
$(fieldId).change( function () {
companyTriggerAjax( $(this).val() );
});
});
</script>
<?php
endif;
}
// Enabling, disabling and refreshing session shipping methods data
add_action( 'woocommerce_checkout_update_order_review', 'refresh_shipping_methods', 10, 1 );
function refresh_shipping_methods( $post_data ){
$bool = true;
if ( WC()->session->get('company' ) === '1' )
$bool = false;
// Mandatory to make it work with shipping methods
foreach ( WC()->cart->get_shipping_packages() as $package_key => $package ){
WC()->session->set( 'shipping_for_package_' . $package_key, $bool );
}
WC()->cart->calculate_shipping();
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
Related: Remove shipping cost if custom checkbox is checked in WooCommerce Checkout

Rest API to store products in cart based on the user id in woocommerce

Only related reference for the same I found with accepted by few people is the below mentioned code but there is no session stored in options table with the following key '_wc_session_'.$user_id
function add_products_programmatically($user_id) {
// Get the current session data and saved cart
$wc_session_data = get_option('_wc_session_'.$user_id);
// Get the persistent cart
$full_user_meta = get_user_meta($user_id,'_woocommerce_persistent_cart', true);
// Create a new WC_Cart instance and add products programmatically
$cart = get_new_cart_with_products();
// If there is a current session cart, overwrite it with the new cart
if($wc_session_data) {
$wc_session_data['cart'] = serialize($cart->cart_contents);
update_option('_wc_session_'.$user_id, $wc_session_data);
}
// Overwrite the persistent cart with the new cart data
$full_user_meta['cart'] = $cart->cart_contents;
update_user_meta($user_id, '_woocommerce_persistent_cart', $full_user_meta);
}
After a lot of research to the way woo-commerce uses persistent cart I have created a working solution.
function woocomm_add_to_cart($param) {
global $wpdb;
$user_id = $param['user_id'];
$objProduct = new WC_Session_Handler();
$wc_session_data = $objProduct->get_session($user_id);
// Get the persistent cart may be _woocommerce_persistent_cart can be in your case check in user_meta table
$full_user_meta = get_user_meta($user_id,'_woocommerce_persistent_cart_1',true);
// create new Cart Object
$cartObj = new WC_Cart();
// Add old cart data to newly created cart object
if($full_user_meta['cart']) {
foreach($full_user_meta['cart'] as $sinle_user_meta) {
$cartObj->add_to_cart( $sinle_user_meta['product_id'], $sinle_user_meta['quantity'] );
}
}
// Add product and quantities coming in request to the new cart object
if($param['products']){
foreach($param['products'] as $prod) {
$cartObj->add_to_cart( $prod['product_id'], $prod['quantity'] );
}
}
$updatedCart = [];
foreach($cartObj->cart_contents as $key => $val) {
unset($val['data']);
$updatedCart[$key] = $val;
}
// If there is a current session cart, overwrite it with the new cart
if($wc_session_data) {
$wc_session_data['cart'] = serialize($updatedCart);
$serializedObj = maybe_serialize($wc_session_data);
$table_name = 'wp_woocommerce_sessions';
// Update the wp_session table with updated cart data
$sql ="UPDATE $table_name SET 'session_value'= '".$serializedObj."', WHERE 'session_key' = '".$user_id."'";
// Execute the query
$rez = $wpdb->query($sql);
}
// Overwrite the persistent cart with the new cart data
$full_user_meta['cart'] = $updatedCart;
update_user_meta($user_id, '_woocommerce_persistent_cart_1', $full_user_meta);
$response = [
'status' => true,
'message' => 'Products successfully added to cart'
];
return rest_ensure_response($response);
}
Here is the Request json data for the Rest API:
{"user_id": 15, "products" : [{"product_id":"81","quantity":"0.5"},{"product_id":"1817","quantity":"0.5"}]}
I have done some changes in previous code as this code is not working with me independently.
I have created Rest API for my Vue.js application.
Create route and make function and paste this code use as add to
cart
This can also update the session of user on web side when you add
from mobile end
if (checkloggedinuser()) {
include_once WC_ABSPATH . 'includes/wc-cart-functions.php';
include_once WC_ABSPATH . 'includes/wc-notice-functions.php';
include_once WC_ABSPATH . 'includes/wc-template-hooks.php';
global $wpdb;
$user_id = get_current_user_id();
WC()->session = new WC_Session_Handler();
WC()->session->init();
$wc_session_data = WC()->session->get_session($user_id);
// Get the persistent cart may be _woocommerce_persistent_cart can be in your case check in user_meta table
$full_user_meta = get_user_meta($user_id,'_woocommerce_persistent_cart_1',true);
WC()->customer = new WC_Customer( get_current_user_id(), true );
// create new Cart Object
WC()->cart = new WC_Cart();
// return $full_user_meta;
// Add old cart data to newly created cart object
if($full_user_meta['cart']) {
foreach($full_user_meta['cart'] as $sinle_user_meta) {
WC()->cart->add_to_cart( $sinle_user_meta['product_id'], $sinle_user_meta['quantity'] );
}
}
WC()->cart->add_to_cart( $request['product_id'], $request['quantity'] );
$updatedCart = [];
foreach(WC()->cart->cart_contents as $key => $val) {
unset($val['data']);
$updatedCart[$key] = $val;
$updatedCart[$key]['file'] = "hello file herer";
}
// If there is a current session cart, overwrite it with the new cart
if($wc_session_data) {
$wc_session_data['cart'] = serialize($updatedCart);
$serializedObj = maybe_serialize($wc_session_data);
$table_name = 'wp_woocommerce_sessions';
// Update the wp_session table with updated cart data
$sql ="UPDATE $table_name SET 'session_value'= '".$serializedObj."', WHERE 'session_key' = '".$user_id."'";
// Execute the query
$rez = $wpdb->query($sql);
}
// Overwrite the persistent cart with the new cart data
$full_user_meta['cart'] = $updatedCart;
update_user_meta($user_id, '_woocommerce_persistent_cart_1', $full_user_meta);
return array(
'success' => false,
'responsecode' => 403,
"message" => "Products successfully added to cart",
"data" => [],
);
}else{
return array(
'success' => false,
'responsecode' => 403,
"message" => "Please Logged In to get Data",
"data" => [],
);
}
this is the simplest solution:
if ( defined( 'WC_ABSPATH' ) ) {
// WC 3.6+ - Cart and other frontend functions are not included for REST requests.
include_once WC_ABSPATH . 'includes/wc-cart-functions.php';
include_once WC_ABSPATH . 'includes/wc-notice-functions.php';
include_once WC_ABSPATH . 'includes/wc-template-hooks.php';
}
if ( null === WC()->session ) {
$session_class = apply_filters( 'woocommerce_session_handler', 'WC_Session_Handler' );
WC()->session = new $session_class();
WC()->session->init();
}
if ( null === WC()->customer ) {
WC()->customer = new WC_Customer( get_current_user_id(), true );
}
if ( null === WC()->cart ) {
WC()->cart = new WC_Cart();
// We need to force a refresh of the cart contents from session here (cart contents are normally refreshed on wp_loaded, which has already happened by this point).
WC()->cart->get_cart();
}
WC()->cart->add_to_cart($prod['product_id'], $prod['quantity']);
reference from the link:
https://barn2.com/managing-cart-rest-api-woocommerce-3-6/

How to get custom post meta in wp media js

I have a custom post type and on the admin edit post screen I'm using wp.media to attach the track to the post. And I'm attaching some post meta to that track also.
Is there easy way to force wp.media JS returns track with meta data?
trackMediaUploader = wp.media.frames.file_frame = wp.media( { ... } );
trackMediaUploader.on( 'select', () => {
const attachment = trackMediaUploader.state().get( 'selection' ).first().toJSON();
// want to get post meta of this attachment
console.log( attachment );
});
I've tried to use wp_get_attachment_metadata filter, but it's wont works with wp.media js:
function add_attachment_metadata( $data, $id ) {
$lyrics = get_post_meta( $id, '_track_lyrics', true );
if( $lyrics ) {
$data[ 'track-lyrics' ] = $lyrics;
}
return $data;
}
You can use wp_prepare_attachment_for_js hook:
add_filter( 'wp_prepare_attachment_for_js', 'prepare_attachment_for_js', 10, 3 );
function prepare_attachment_for_js( $response, $attachment, $meta ) {
$response[ 'trackLyrics' ] = get_post_meta( $attachment->ID, '_track_lyrics', true );
return $response;
}
// in admin js:
trackMediaUploader = wp.media.frames.file_frame = wp.media( { ... } );
trackMediaUploader.on( 'select', () => {
const attachment = trackMediaUploader.state().get( 'selection' ).first().toJSON();
console.log( attachment.trackLyrics );
});

Validate wordpress password repeat with REST api

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

Resources