How to get custom post meta in wp media js - wordpress

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 );
});

Related

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

Remove Selected Checkout Fields with Woocommerce Depending on Shipping Method Redux

In reference to this Remove selected checkout fields with woocommerce depending on shipping method
How can I adapt the codes in order remove different fields based on different shipping methods selected?
I've tried modifying the beginnging part to below, but it just stops working...
add_filter( 'woocommerce_checkout_fields', 'xa_remove_billing_checkout_fields' );
function xa_remove_billing_checkout_fields( $fields ) {
$chosen_methods = WC()->session->get( 'chosen_shipping_methods' );
// uncomment below line and reload checkout page to check current $chosen_methods
// print_r($chosen_methods);
$chosen_shipping = $chosen_methods[0];
if ($chosen_shipping == 'flat_rate:13') {
$shipping_method = 'flat_rate:13';
$hide_fields = array( 'billing_address_2', 'billing_city', 'billing_state', 'billing_postcode' );
}
if ($chosen_shipping =='flat_rate:7') {
$shipping_method = 'flat_rate:7';
$hide_fields = array( 'billing_city', 'billing_state', 'billing_postcode' );
}
foreach($hide_fields as $field ) {
if ($chosen_shipping == $shipping_method) {
$fields['billing'][$field]['required'] = false;
$fields['billing'][$field]['class'][] = 'hide';
}
$fields['billing'][$field]['class'][] = 'billing-dynamic';
}
return $fields;
}
The other part looks like this, which I copied and modified from another answer
add_action( 'wp_footer', 'cart_update_script', 999 );
function cart_update_script() {
if (is_checkout()) :
?>
<style>
.hide {display: none!important;}
</style>
<script>
jQuery( function( $ ) {
// woocommerce_params is required to continue, ensure the object exists
if ( typeof woocommerce_params === 'undefined' ) {
return false;
}
var show = ['flar_rate:7', 'flat_rate:13'];
$(document).on( 'change', '#shipping_method input[type="radio"]', function() {
// console.log($.inArray($(this).val(), show));
if ($.inArray($(this).val(), show) > -1) { // >-1 if found in array
$('.billing-dynamic').removeClass('hide');
// console.log('show');
} else {
$('.billing-dynamic').addClass('hide');
// console.log('hide');
}
});
});
</script>
<?php
endif;
}
Also, if I change the country, which changes also the shipping zone, the fields ain't reverted until I select the shipping method again.
Thanks in advance.

Get Elementor Submission DB ID

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>

Create Post with Meta Field – WP REST API

I have just started with REST API and using it for creating posts from frontend. I managed to publish post with Title, Excerpt, Content.
I want to add a Custom Meta Field value aswell, any example or help is much appreciated.
This is my Ajax Code, all other fields working fine except meta value is not being added in post
jQuery( document ).ready( function ( $ ) {
$( '#post-submission-form' ).on( 'submit', function(e) {
e.preventDefault();
var title = $( '#post-submission-title' ).val();
var excerpt = $( '#post-submission-excerpt' ).val();
var content = $( '#post-submission-content' ).val();
var status = 'draft';
var data = {
title: title,
excerpt: excerpt,
content: content,
status: status,
meta: {
'video_url_url' : 'abc',
}
};
$.ajax({
method: "POST",
url: POST_SUBMITTER.root + 'wp/v2/posts',
data: data,
beforeSend: function ( xhr ) {
xhr.setRequestHeader( 'X-WP-Nonce', POST_SUBMITTER.nonce );
},
success : function( response ) {
console.log( response );
alert( POST_SUBMITTER.success );
},
fail : function( response ) {
console.log( response );
alert( POST_SUBMITTER.failure );
}
});
});
} );
Add this to your functions.php :
/**
* Add the meta fields to REST API responses for posts read and write
* Read and write a post meta fields in post responses
*/
function mg_register_meta_api() {
//Meta Fields that should be added to the API
$meta_fields = array(
'video_url_url',
'another_meta_key'
);
//Iterate through all fields and add register each of them to the API
foreach ($meta_fields as $field) {
register_rest_field( 'ring',
$field,
array(
'get_callback' => array( $this, 'mg_fw_get_meta'),
'update_callback' => array( $this, 'mg_fw_update_meta'),
'schema' => null,
)
);
}
}
add_action( 'rest_api_init', 'mg_register_meta_api' );
/**
* Handler for getting custom field data.
*
* #since 0.1.0
*
* #param array $object The object from the response
* #param string $field_name Name of field
*
* #return mixed
*/
function mg_get_meta( $object, $field_name ) {
return get_post_meta( $object[ 'id' ], $field_name );
}
/**
* Handler for updating custom field data.
*
* #since 0.1.0
* #link http://manual.unyson.io/en/latest/helpers/php.html#database
* #param mixed $value The value of the field
* #param object $object The object from the response
* #param string $field_name Name of field
*
* #return bool|int
*/
function mg_update_meta( $value, $object, $field_name ) {
if ( ! $value || ! is_string( $value ) ) {
return;
}
return update_post_meta( $object->ID, $field_name, maybe_serialize( strip_tags( $value ) ) );
}
Now you should be able to read and write for meta 'video_url_url' using the api.
I was playing around with this today and came up with the following solution that works well and adds multiple fields.
Hope this helps anyone who may be stuck on this.
add_action( 'rest_api_init', 'foo_register_meta_api' );
function foo_register_meta_api() {
// Meta Fields to add to the API
$meta_fields = array(
'field_1',
'foo_bar',
'foobar',
'another_field'
);
// Loop all fields and register each of them to the API
foreach ($meta_fields as $field) {
register_rest_field( 'my-post-type',
$field,
array(
'get_callback' => function ($params) use ($field) {
return \get_post_meta($params['id'], $field);
},
'update_callback' => function ($value, $object, $fieldName){
return \update_post_meta($object->ID, $fieldName, $value);
},
'schema' => null
)
);
}
}
I am trying to save phy_marks in post type candidates. What I've got is creating the post but not saving phy_marks.
My JSON data:
{ "title": "Why not working finally","content": "Test", "status": "publish" ,"post_type": "candidates", "meta": {
"phy_marks": 66 } }
My Code:
add_action( 'rest_api_init', 'foo_register_meta_api' );
function foo_register_meta_api() {
// Meta Fields to add to the API
$meta_fields = array(
'phy_marks'
);
// Loop all fields and register each of them to the API
foreach ($meta_fields as $field) {
register_rest_field( 'candidates',
$field,
array(
'get_callback' => function ($params) use ($field) {
return \get_post_meta($params['id'], $field);
},
'update_callback' => function ($value, $object, $fieldName){
return \update_post_meta($object->ID, $fieldName, $value);
},
'schema' => null
)
);
}
}

AJAX success response is not working but it's saving my changes

I'm a beginner in jQuery-Ajax so please bear with me. My Ajax response does not seem to load but my changes are being saved. but gives me this error on admin-ajax.php "call_user_func() expects parameter 1 to be a valid callback, function '_update_post_ter_count' not found or invalid function name".
Here is my function, could you point what i'm doing wrong?
add_action( 'wp_ajax_nopriv_save_sort', 'ccmanz_save_reorder' );
add_action('wp_ajax_save_sort','ccmanz_save_reorder');
function ccmanz_save_reorder() { //checking
//verify user intent
check_ajax_referer( 'wp-job-order', 'security' ); // this comes from wp_localize_script() in hrm-jobs.php
//capability check to ensure use caps
if ( ! current_user_can( 'manage_options' ) ) {
wp_die( __( 'You do not have permission to access this page.' ) );
}
$order = explode( ',', $_POST['order'] );
$counter = 0;
foreach ( $order as $item_id ) {
$post = array(
'ID' => (int) $item_id,
'menu_order' => $counter,
);
wp_update_post( $post );
$counter ++;
}
wp_send_json_success('POST SAVED');
}
My Ajax Call
jQuery(document).ready(function($) {
sortList = $( 'ul#custom-type-list' ); //store
var animation = $ ( '#loading-animation' );
var pageTitle = $ ( 'div h2');
sortList.sortable({
update: function ( event, ui) {
animation.show();
$.ajax({
url: ajaxurl, // ajaxurl is defined by WordPress and points to /wp-admin/admin-ajax.php
type: 'POST',
async: true,
cache: false,
dataType: 'json',
data:{
action: 'save_sort', // Tell WordPress how to handle this ajax request
order: sortList.sortable( 'toArray' ).toString(), // Passes ID's of list items in 1,3,2 format
security: WP_JOB_LISTING.security
},
success: function( response ) {
animation.hide();
$('div.updated').remove();
if( true === response.success ) {
console.log(sortList.sortable( 'toArray' ));
pageTitle.after(
'<div id="messsage" class="updated"><p>' + WP_JOB_LISTING.success + '</p></div>'
);
} else {
$('div.error').remove();
pageTitle.after( '<div id="messsage" class="error"><p>' + WP_JOB_LISTING.failure + '</div>' );
}
},
error: function ( error ) {
$( 'div.error' ).remove();
animation.hide();
//pageTitle.after( '<div id="messsage" class="error"><p>' + WP_JOB_LISTING.failure + '</div>' );
}
});
}//update
}); //sortable
});//jquery

Resources