issue in new post submission with ACF on front end - php

I am using Advanced Custom field for a custom post type to allow user to add post from front end. My update code is working fine. Inserting new post is not working fine. Its just adding a post, but no data is saved.
I have tried following code.
function my_acf_save_post( $post_id ) {
if( $post_id != 'new_post' ) {
// Get the selected post status
$value = get_field('post_status_field', $post_id);
// Update current post
$post = array(
'ID' => $post_id,
'post_status' => $value,
'post_title' => $_POST['acf']['_post_title'],
);
// Remove the action to avoid infinite loop
remove_action('acf/save_post', 'my_acf_save_post', 20);
// Update the post into the database
$post_id = wp_update_post( $post );
// Add the action back
do_action('acf/save_post', $post_id, 20);
}else{
// Get the selected post status
$value = get_field('post_status_field', $post_id);
// Update current post
$post = array(
'ID' => $post_id,
'post_status' => $value,
'post_title' => $_POST['acf']['_post_title'],
);
// Remove the action to avoid infinite loop
remove_action('acf/save_post', 'my_acf_save_post', 20);
// Update the post into the database
$post_id = wp_insert_post( $post );
// Add the action back
do_action('acf/save_post', $post_id, 20);
}
return $post_id;
}
// run after ACF saves the $_POST['acf'] data
add_action('acf/save_post', 'my_acf_save_post', 20);
I am not able to figure out, where I am getting wrong. I want when a post is submitted, all data is submitted and when updated, all data must update.

Funny thing, I solved that yesterday.
When you hooking on 'acf/save_post' you running function, while custom field has old value, you sending new values with $_POST, but with get_field() you getting old values :D
So instead
$value = get_field('post_status_field', $post_id);
You need to use, in both situations, else you need press update button twice
$value = $_POST['acf']['FIELD_KEY'];
to get FIELD_KEY do
var_dump( $_POST['acf']); die();

Related

Update custom meta data for Orders in Woocommerce

I'm trying to update the Woocommerce Orders with a custom meta data field
On Woocommerce order complete (status change) I have a Invoicing plugin that automatically generates customer invoice documents, this plugin has its own hooks/filters such as:
apply_filters('moloni_after_insert_document', $this);
After it inserts (generates) the invoice, I use their API to return a value ( the invoice code ) that I want to save on that order meta data.
This is the code that I use:
add_action('moloni_after_insert_document', 'save_codigo_at', 10, 4 );
function save_codigo_at( $order_id ) {
// On Order complete > access Moloni API > GETPDFLINK > Sanitize string and get Hash > Get document ID from order >
// Retrieve from the Database table moloni_api the access token from column main_token
global $wpdb;
$table_name = "wp_moloni_api";
$retrieve_data = $wpdb->get_results( "SELECT * FROM $table_name WHERE id = 1" );
foreach ($retrieve_data as $retrieved_data) {
$maintoken = $retrieved_data->main_token;
}
// Get document ID from the order
$documentid = get_post_meta($order->id, '_moloni_sent', true);
// Connect to moloni API and getpdflink
$url = "https://api.moloni.pt/v1/documents/getOne/?access_token=$maintoken";
$postData = array(
'company_id' => '11111',
'document_id' => $documentid );
$arguments = array(
'method' => 'POST',
'headers' => array(
'Content-type: application/x-www-form-urlencoded'
),
'body' => $postData,
);
$response = wp_remote_post( $url, $arguments );
if ( is_wp_error( $response ) ) {
$error_message = $response->get_error_message();
return "Something went wrong: $error_message";
} else {
echo '<pre>';
var_dump( wp_remote_retrieve_body( $response ) );
echo '</pre>';
// jsondecode the string received by the API to remove weird backslashes, get and parse the URL and extract the HASH key
$response2 = wp_remote_retrieve_body($response);
parse_str(parse_url(json_decode($response2, true)['url'], PHP_URL_QUERY), $result);
$hash = $result['h'];
//CONVERT JSON array to PHP array
$response3 = json_decode($response2);
$invoicecode = $response3->transport_code; //GET INVOICE CODE from the PHP ARRAY
echo $invoicecode;
$order = wc_get_order( $order_id );
$order->update_meta_data( '_codigo_at', $invoicecode );
$order->save();
}
}
Now I am successfully able to get the code from their response.
However I can't save it because I always get the following PHP fatal error:
PHP Fatal error: Uncaught Error: Call to a member function update_meta_data() on bool in
From what I understood so far, this would likely be because $order is not defined as an object on this filter moloni_after_insert_document
Because when I try just to save a test random meta value but instead using a filter like woocommerce_order_status_completed then $order seems to work for updating meta data, the problem is that I must only run this action after the moloni_after_insert_document filter, because it is only then that the Invoice Code is generated and available
How could I properly define the $order inside of this code?
I am not sure how to handle/proceed in this situation
Thank you in advance for the attention and advice
It is necessary to add
global $woocommerce, $post;
to the code, as adding this global has fixed the problem because it allowed to define the $order object.
I don't know if this is the most efficient way of doing so, but it has managed to make the code work.

Run function on custom post type array only

I would like to run following code only on a given custom post types. now its running only on one specific custom type 'file' .
I tried to add the function in an array but i am quiet sure it wasn't the right thing
// For deleting attachments when Deleting POSTS
add_action( 'before_delete_post', 'mtp_delete_attached_thumbnail_for_trashed_product', 20, 1 );
function mtp_delete_attached_thumbnail_for_trashed_product( $post_id ) {
// gets ID of post being trashed
$post_type = get_post_type( $post_id );
// does not run on other post types
if ( $post_type != 'file' ) {
return true;
}
// get ID of featured image
$post_thumbnail_id = get_post_thumbnail_id( $post_id );
// delete featured image
wp_delete_attachment( $post_thumbnail_id, true );
}
for example only if the custom post type is 'file' or 'share' or 'folder' then the featured image will be deleted when deleting the post.
You can use the in_array() to simplify this.
// For deleting attachments when Deleting POSTS
add_action( 'before_delete_post', 'mtp_delete_attached_thumbnail_for_trashed_product', 20, 1 );
function mtp_delete_attached_thumbnail_for_trashed_product( $post_id ) {
// List of post types.
$post_types = array(
'file',
'share',
'folder',
);
// gets ID of post being trashed
$post_type = get_post_type( $post_id );
// does not run on other post types
if ( ! in_array( $post_type, $post_types, true) ) {
return true;
}
// get ID of featured image
$post_thumbnail_id = get_post_thumbnail_id( $post_id );
// delete featured image
wp_delete_attachment( $post_thumbnail_id, true );
}
https://www.w3schools.com/php/func_array_in_array.asp

Wordpress Plugin development for Contact Form

I am developing a simple WordPress plugin for contact form. But I don't know how to save the information in database? Could you gives some references?
The answer by Haninder has a great start but doesn't store the data in a database as per the OP.
This is where it starts getting tricky, as there are many options.
You can easily store the data in various places, but none are semantically correct, or maintainable over a long period of time.
In a single option in the options table
function save_request( $data ){
$opts = get_option( 'contact_requests' );
if( ! $opts || ! is_array( $opts ) ){
$opts = array();
}
$opts[] = $data;
update_option( 'contact_requests', $opts );
}
This would mean a slow request to save and defeats the point of a database in the first place, after several hundred contact requests, also diaplying and sorting the data would get tricky.
The best way would really to have a custom database table but there is a lot to consider when going down this path.
https://code.tutsplus.com/tutorials/custom-database-tables-creating-the-table--wp-28124
Custom Post Type
This is how I would approach this problem.
perhaps you could create a custom post type, say "contact_requests" and create a post with some post meta to represent a contact request.
This way you already get a neat list in admin, and can sort and access the data quickly and easily as required. This would be stable and fast through hundreds of thousands of entries.
function save_request( $data ){
$content = '';
foreach( $data as $key => $name ){
$content .= sprintf( '%s - %s' . PHP_EOL, $key, $name );
}
$post_data = array(
'post_title' => 'Contact Request ' . esc_html( $data['name'] ),
'post_content' => $content,
'post_type' => 'contact_requests'
);
$post_id = wp_insert_post( $post_data );
//Add Post Meta Here
add_post_meta( $post_id, 'contact_name', esc_html( $data['name'] ) );
add_post_meta( $post_id, 'contact_email', esc_html( $data['email'] ) );
add_post_meta( $post_id, 'contact_message', esc_html( $data['message'] ) );
return $post_id;
}

Create a downloadable product with audio file in woocommerce

trust your day has been fulfilling. I need to create a downloadable woocommerce product from the front end. I have been able to create link to post the product and add the audio file as attachment but I need to make this attachment downloadable after payment just like you have when you post a downloadable woocommerce product from the dashboard. I can see my product in the dashboard already but I have to manually check downloadable and add file from the dashboard. Please I need help on how I can make the product posted from front-end downloadable automatically.
Thank you people for always.
Below is my code snippet .
// ADD THE FORM INPUT TO $new_post ARRAY
$new_post = array(
'post_title' => $title,
'post_content' => $description,
'post_category' => array($_POST['cat']),
'tags_input' => array($tags),
'post_status' => 'draft',
'post_type' => 'product', //'post',page' or use a custom post type if you want to
'rating' => $myrating
);
//SAVE THE POST
$pid = wp_insert_post($new_post);
//KEEPS OUR COMMA SEPARATED TAGS AS INDIVIDUAL
wp_set_post_tags($pid, $_POST['post_tags']);
//REDIRECT TO THE NEW POST ON SAVE
$link = get_permalink( $pid );
wp_redirect( $link );
//ADD OUR CUSTOM FIELDS
add_post_meta($pid, 'rating', $myrating, true);
//INSERT OUR MEDIA ATTACHMENTS
if ($_FILES) {
foreach ($_FILES as $file => $array) {
$newupload = insert_attachment($file,$pid);
// $newupload returns the attachment id of the file that
}
} // END THE IF STATEMENT FOR FILES
What you should do is, in your functions.php add this code.
function user_downloads($order_id) {
// Variables to change
$download_file_id = CUSTOM_ID_OR_ATTACHMENT_ID_OF_FILE;
$user_id = USER_ID;
$product_id = PRODUCT_ID;
$order = new WC_Order( $order_id );
if($order['product_id'] == $product_id ){
$user_downloads = get_user_meta($user_id, 'user_downloads', TRUE);
if(!empty($user_downloads)){
$user_downloads = $user_downloads.','.$download_file_id;
update_user_meta($user_id, 'user_downloads', $user_downloads );
}else{
update_user_meta($user_id, 'user_downloads', $user_downloads );
}
}
}
add_action( 'woocommerce_order_status_completed', 'user_downloads' );
This code will hook into woocommerce and when ever an order is completed it will create a new user meta data. So every user who will make a payment for the specified product will have a new meta item called 'user_downloads'. The value of this item will be the comma separated values of attachment id or some encrypted id. Now all you have to do in the template page is
$user_downloads = get_user_meta($user_id, 'user_downloads', TRUE);
$user_downloads = explode(',',$user_downloads);
foreach($user_downloads as $user_download){
echo 'Downloadable File';
}
This way they can buy as many products as they want and all these items will get stacked in their user profile from where they can download them.

WordPress Uploading Thumbnail for Custom Post Meta

I have set up a custom post meta field for Thumbnail on each of my posts. This function is being called correctly, and everything works up until the very last line of update_post_meta
What's interesting is that I can echo out $imageURL and get the correct address, and the file uploads fine. I can even update_post_meta with any other value whether it be a string, or another variable within the function but as soon as I try to use $imageURL or $uploaded_file['url'] it just sets the post meta to a blank string.
I've used this snippet on projects that were developed with WordPress earlier than 3.1, but this one is 3.1. Could that have something to do with it? I kind of doubt it, since this seems to be one of those super weird bugs.
function tcr_save_thumbnail($post_id, $post) {
if ( !wp_verify_nonce( $_POST['eventmeta_noncename'], plugin_basename(__FILE__) )) {
return $post->ID;
}
if ( !current_user_can( 'edit_post', $post->ID ))
return $post->ID;
if(!empty($_FILES['tcr_thumbnail_meta']['name'])) { //New upload
require_once( ABSPATH . 'wp-admin/includes/file.php' );
$override['action'] = 'editpost';
$uploaded_file = wp_handle_upload($_FILES['tcr_thumbnail_meta'], $override);
$post_id = $post->ID;
$attachment = array(
'post_title' => $_FILES['tcr_thumbnail_meta']['name'],
'post_content' => '',
'post_type' => 'attachment',
'post_parent' => $post_id,
'post_mime_type' => $_FILES['tcr_thumbnail_meta']['type'],
'guid' => $uploaded_file['url']
);
// Save the data
$id = wp_insert_attachment( $attachment,$_FILES['tcr_thumbnail_meta'][ 'file' ], $post_id );
wp_update_attachment_metadata( $id, wp_generate_attachment_metadata( $id, $_FILES['tcr_thumbnail_meta']['file'] ) );
$imageURL = $uploaded_file['url'];
update_post_meta($post->ID, "tcr_thumbnail_meta", $imageURL);
}
}
This is a functionality that has already been implemented in a plugin. try it http://wordpress.org/extend/plugins/taxonomy-images/ It is so complete!

Categories