I want to Upload Image from front-end with Advanced custom field - php

I have a lot of advanced custom fields. There are three image types between them. I have added ACF text fields with add_post_meta. But I can't add the images.
Here is my code sample
if( 'POST' == $_SERVER['REQUEST_METHOD'] && !empty( $_POST['new_post'] )) {
$title="New Property for Sale";
$custom_tags = $_POST['tax_input']; //load thread tags (custom tax) into array
$post = array(
'post_title'=>$title,
'post_content' => $_POST['property_description'],
'tax_input' => $custom_tags,
'post_status' => 'pending',
'post_type' => 'property'
);
$post_id = wp_insert_post($post);
//send our post, save the resulting ID
if($post_id){
add_post_meta($post_id, 'type', $_POST['acf']['field_60338ebdd3ca4'], true);
add_post_meta($post_id, 'locality', $_POST['acf']['field_603374e8f8d62'],true);
add_post_meta($post_id, 'address', $_POST['acf']['field_6034ed6a0cd29'], true);
add_post_meta($post_id, 'facing', $_POST['acf']['field_6034eda30cd2b'],true);
add_post_meta($post_id, 'bed_number', $_POST['acf']['field_60337452f8d5f'], true);
add_post_meta($post_id, 'balconies', $_POST['acf']['field_6034f2180cd2c'], true);
//send the user along to their newly created post
}
}
I have added the featured image of the post.
if ( $_FILES['image']['name']!="" ) {
$upload = wp_upload_bits($_FILES["image"]["name"], null, file_get_contents($_FILES["image"]["tmp_name"]));
// $post_id = $post_id; //set post id to which you need to set featured image
$filename = $upload['file'];
$wp_filetype = wp_check_filetype($filename, null);
$attachment = array(
'post_mime_type' => $wp_filetype['type'],
'post_title' => sanitize_file_name($filename),
'post_content' => '',
'post_status' => 'inherit'
);
$attachment_id = wp_insert_attachment( $attachment, $filename, $post_id );
if ( ! is_wp_error( $attachment_id ) ) {
require_once(ABSPATH . 'wp-admin/includes/image.php');
$attachment_data = wp_generate_attachment_metadata( $attachment_id, $filename );
wp_update_attachment_metadata( $attachment_id, $attachment_data );
set_post_thumbnail( $post_id, $attachment_id );
}
}
I have to add more two images with ACF. Please Help me.

This is the most straight away full code on WP codex to upload to Media:
https://developer.wordpress.org/reference/functions/media_handle_upload/
So, try creating this file inside a wordpress page template and after attaching you will have to set the ID on your ACF metadata
<?php
if (
isset( $_POST['my_image_upload_nonce'], $_POST['post_id'] )
&& wp_verify_nonce( $_POST['my_image_upload_nonce'], 'my_image_upload' )
&& current_user_can( 'edit_post', $_POST['post_id'] )
) {
// The nonce was valid and the user has the capabilities, it is safe to continue.
// These files need to be included as dependencies when on the front end.
require_once( ABSPATH . 'wp-admin/includes/image.php' );
require_once( ABSPATH . 'wp-admin/includes/file.php' );
require_once( ABSPATH . 'wp-admin/includes/media.php' );
// Let WordPress handle the upload.
// Remember, 'my_image_upload' is the name of our file input in our form above.
$attachment_id = media_handle_upload( 'my_image_upload', $_POST['post_id'] );
if ( is_wp_error( $attachment_id ) ) {
// There was an error uploading the image.
echo "ERROR";
} else {
// The image was uploaded successfully!
echo "Image ID is: " . $attachment_id;
//Now set your image ACF field to the $attachment_id
// My case because its a user metadata update:
//update_user_meta( $userID, 'YOUR_IMAGE_NAME_ACF_FIELD_HERE!!', $attachment_id );
// update post meta of your ACF field with the new attachment id
update_post_meta ( $_POST['post_id'], 'YOUR_IMAGE_NAME_ACF_FIELD_HERE!!' , $attachment_id );
}
} else {
// The security check failed, maybe show the user an error.
}
?>
<!-- HTML code for uploading this single file -->
<form id="featured_upload" method="post" action="#" enctype="multipart/form-data">
<input type="file" name="my_image_upload" id="my_image_upload" multiple="false" />
<input type="hidden" name="post_id" id="post_id" value="55" />
<?php wp_nonce_field( 'my_image_upload', 'my_image_upload_nonce' ); ?>
<input id="submit_my_image_upload" name="submit_my_image_upload" type="submit" value="Upload" />
</form>

Related

Exclude email attachments from specific email notifications in Woocommerce

I would like to exclude added email attachments for customer reset password and customer new account emails, or limit adding some of attachment to Woocommerce order emails only (and exclude attachments for emails send to admin). Is it possible?
add_filter( 'woocommerce_email_attachments', 'doc_to_email', 10, 3);
function doc_to_email ( $attachments , $id, $object ) {
$attachments = array();
array_push($attachments, get_home_path() . '/doc/Zasady_ochrany_osobnich_udaju.pdf' );
if( !$id == array( 'customer_reset_password', 'customer_new_account') ) {
array_push($attachments, get_home_path() . '/doc/VOP.pdf' );
array_push($attachments, get_home_path() . '/doc/Reklamacni_rad.pdf' );
array_push($attachments, get_home_path() . '/doc/Reklamacni_protokol.pdf' );
array_push($attachments, get_home_path() . '/doc/Formular_pro_odstoupeni_od_smlouvy.pdf' );
}
return $attachments;
}
Thanks you
The following code will exclude email attachements from all admin email notifications and some attachements from specific email notifications:
add_filter( 'woocommerce_email_attachments', 'custom_email_attachments', 20, 3 );
function custom_email_attachments ( $attachments = [] , $email_id, $order ) {
// HERE define customer and admin excluded email Ids
$excluded_customer_email_ids = array( 'customer_reset_password', 'customer_new_account' );
$excluded_admin_email_ids = array( 'new_order', 'cancelled_order', 'failed_order' );
// Excluding attachements from admin email notifications
if( in_array( $email_id, $excluded_admin_email_ids ) )
return [];
$file_path = get_home_path() . '/doc/';
$attachments[] = $file_path . 'Zasady_ochrany_osobnich_udaju.pdf';
// Excluding some customer email notifications
if( ! in_array( $email_id, $excluded_customer_email_ids ) ) {
$attachments[] = $file_path . 'VOP.pdf';
$attachments[] = $file_path . 'Reklamacni_rad.pdf';
$attachments[] = $file_path . 'Reklamacni_protokol.pdf';
$attachments[] = $file_path . 'Formular_pro_odstoupeni_od_smlouvy.pdf';
}
return $attachments;
}
Code goes in function.php file of your active child theme (or active theme). It should works.

Post parent as current id not working

I'm using the wp dropzone plugin trying to tweak things a little to create a a front end image uploader that sets the current post as the attachments parent.
The plugin as is works really well but by default no matter where I locate the uploader any attachments are marked as un attached in my media library.
I can't for the life of me work out why this isn't working as I've tried all standard calls to get the current post id and set this as the parent.
The full php plugin file is quite extensive so I've included the core section which operates the attachment insertion. See my progress what I have below.
Importantly if I set the post parent as the actual id number; '240' for example it attaches to the called post. I'm looking to attach this to the current post.
/**
* Handle ajax file upload to media library.
*
* #since 1.0.0
*/
function wpday_dz_ajax_upload_handle() {
if (!empty($_FILES) && wp_verify_nonce($_REQUEST['wpday_dz_nonce'], 'wpday_dz_protect')) {
// Including file library if not exist
if (!function_exists('wp_handle_upload')) {
require_once ABSPATH . 'wp-admin/includes/file.php';
}
// Uploading file to server
$movefile = wp_handle_upload($_FILES['file'], ['test_form' => false]);
// If uploading success & No error
if ($movefile && !isset($movefile['error'])) {
$filename = $movefile['file'];
$filetype = wp_check_filetype(basename($filename), null);
$wp_upload_dir = wp_upload_dir();
$attachment = array(
'guid' => $wp_upload_dir['url'] . '/' . basename($filename),
'post_mime_type' => $filetype['type'],
'post_parent' => $post->ID,
'post_title' => preg_replace('/\.[^.]+$/', '', basename($filename)),
'post_content' => '',
'post_status' => 'inherit',
);
// Adding file to media
$attachment_id = wp_insert_attachment($attachment, $filename);
// If attachment success
if ($attach_id) {
require_once ABSPATH . 'wp-admin/includes/image.php';
// Updating attachment metadata
$attach_data = wp_generate_attachment_metadata($attach_id, $filename);
wp_update_attachment_metadata($attach_id, $attach_data);
}
$message['error'] = 'false';
$message['data'] = wp_get_attachment_url($attach_id);
} else {
$message['error'] = 'true';
$message['data'] = $movefile['error'];
}
wp_send_json($message);
}
}
add_action('wp_ajax_wpday_dz', 'wpday_dz_ajax_upload_handle');
add_action('wp_ajax_nopriv_wpday_dz', 'wpday_dz_ajax_upload_handle');
EDIT:
Have tried:
$id = get_the_ID();
// If uploading success & No error
if ($movefile && !isset($movefile['error'])) {
$filename = $movefile['file'];
$filetype = wp_check_filetype(basename($filename), null);
$wp_upload_dir = wp_upload_dir();
$attachment = array(
'guid' => $wp_upload_dir['url'] . '/' . basename($filename),
'post_mime_type' => $filetype['type'],
'post_parent' => $id,
'post_title' => preg_replace('/\.[^.]+$/', '', basename($filename)),
'post_content' => '',
'post_status' => 'inherit',
);
Still returns unattached
I downloaded WP Dropzone and had a look at the code. AFAICT the function you are working on is called via AJAX, once a file is dropped/uploaded. In that case, there is no "post" in the current request - you're in an AJAX file unrelated to any post.
So the question becomes how to get the ID of the post that called the current AJAX request. I found this SO answer which answers that:
$url = wp_get_referer();
$post_id = url_to_postid( $url );

Change file name in custom upload form

i want change file upload name and add the name of user that upload it.
This my function.php
if ( ! function_exists( 'upload_user_file' ) ) :
function upload_user_file( $file = array(), $title = false ) {
require_once ABSPATH.'wp-admin/includes/admin.php';
$file_return = wp_handle_upload($file, array('test_form' => false));
if(isset($file_return['error']) || isset($file_return['upload_error_handler'])){
return false;
}else{
$user = wp_get_current_user();
$username = $user->display_lastname;
$filename = $username . $file_return['file'];
return $filename;
$attachment = array(
'post_mime_type' => $file_return['type'],
'post_content' => '',
'post_type' => 'attachment',
'post_status' => 'inherit',
'guid' => $file_return['url']
);
if($title){
$attachment['post_title'] = $title;
}
$attachment_id = wp_insert_attachment( $attachment, $filename );
require_once(ABSPATH . 'wp-admin/includes/image.php');
$attachment_data = wp_generate_attachment_metadata( $attachment_id, $filename );
wp_update_attachment_metadata( $attachment_id, $attachment_data );
if( 0 < intval( $attachment_id ) ) {
return $attachment_id;
}
}
return false;
}
endif;
i try with $filename = $username . $file_return['file']; but don't work.
wp_handle_upload accepts an array of overrides, and one of the arguments is unique_filename_callback where you can specify a custom function to rename the file.
Try something like this:
1: Add a function to functions.php to rename the file as you want it, e.g.
function my_custom_filename($dir, $name, $ext){
$user = wp_get_current_user();
/* You wanted to add display_lastname, but its not required by WP so might not exist.
If it doesn't use their username instead: */
$username = $user->display_lastname;
if (!$username) $username = $user->user_login;
$newfilename = $username ."_". $name; /* prepend username to filename */
/* any other code you need to do, e.g. ensure the filename is unique, remove spaces from username etc */
return $newfilename;
}
2: Then in your upload_user_file(), specify your custom callback function in the wp_handle_upload overrides, e.g.
$overrides = array(
'test_form' => false, /* this was in your existing override array */
'unique_filename_callback' => 'my_custom_filename'
);
/* pass your overrides array into wp_handle_upload */
$file_return = wp_handle_upload($file,$overrides);
UPDATE:
To get the new filename in the upload_user_file function, you can get it from the "url" in the $file_return array that's returned by wp_handle_upload:
$newfilename = basename($file_return["url"]);

How safe is wp_remote_get and writing to filesystem?

I am creating a plugin which makes an API call to a book keeping service and I am integrating it with WooCommerce.
After the order is created I am using woocommerce_email_order_details hook to execute my API call using $response = wp_remote_post( $post_url );, where $post_url is modified so that it all works with the API.
Within this response is also a pdf which I am saving to a folder in the uploads folder using WP_Filesystem() API. This part looks like this:
$response = wp_remote_post( $post_url );
if ( is_wp_error( $response ) ) {
$error_code = wp_remote_retrieve_response_code( $response );
$error_message = wp_remote_retrieve_response_message( $response );
return new WP_Error( $error_code, $error_message );
}
$body = json_decode( $response['body'] );
$pdf_link = esc_url( $body->order->pdf );
$pdf_name = esc_html( $body->order->order_number );
$pdf_get = wp_remote_get( $pdf_link );
if ( is_wp_error( $pdf_get ) ) {
$error_code = wp_remote_retrieve_response_code( $pdf_get );
$error_message = wp_remote_retrieve_response_message( $pdf_get );
return new WP_Error( $error_code, $error_message );
}
$pdf_contents = $pdf_get['body'];
$pdf_name = 'order-' . $pdf_name . '.pdf';
$upload_dir = wp_upload_dir();
$new_dir = $upload_dir['basedir'] . '/orders/' . date( 'Y' ) . '/' . date( 'm' );
if ( ! file_exists( $new_dir ) ) {
wp_mkdir_p( $new_dir );
}
global $wp_filesystem;
if ( empty( $wp_filesystem ) ) {
require_once( ABSPATH . '/wp-admin/includes/file.php' );
WP_Filesystem();
}
$wp_filesystem->put_contents(
$new_dir . '/' . $pdf_name,
$pdf_contents,
FS_CHMOD_FILE // predefined mode settings for WP files.
);
I've tested this with a live link on my local server and it all works.
One thing I don't think I can do is escape the contents of a pdf before saving it because that would break it. Even though this is something that the API of the book keeping service sends me, I don't want to assume anything and take it for granted.
What I am most interested in is: is this safe? Are there any possible vectors of attack here, because I wouldn't want to put my client at a risk.

Get customer data just before order-received in WooCommerce

In WooCommerce, I have a script that I am running when my webshop get a new order. This script sends an SMS to me but I would like to send it to the customer as well.
The script is running using a custom function script, just before the Order-received page with information about the order.
How do I get automatic information from the order about the name and phone number the user used?
Reading this: How to get WooCommerce order details post, does not help me, I can get the information I need and the order page fails when I try...
my code today is like this:
add_action( 'template_redirect', 'wc_custom_redirect_after_purchase' );
function wc_custom_redirect_after_purchase() {
global $wp;
if ( is_checkout() && ! empty( $wp->query_vars['order-received'] ) ) {
// Query args
$query21 = http_build_query(array(
'token' => 'My-Token',
'sender' => 'medexit',
'message' => 'NEW ORDER',
'recipients.0.msisdn' => 4511111111,
));
// Send it
$result21 = file_get_contents('https://gatewayapi.com/rest/mtsms?' . $query21);
// exit;
}
}
What do I need is to get the firstname included in the message.
I would like something like:
$firstname = $order_billing_first_name = $order_data['billing']['first_name'];
$phone = $order_billing_phone = $order_data['billing']['phone'];
But nothing seems to works for me.
Instead you could try to use a custom function hooked in woocommerce_thankyou action hook:
add_action( 'woocommerce_thankyou', 'wc_custom_sending_sms_after_purchase', 20, 1 );
function wc_custom_sending_sms_after_purchase( $order_id ) {
if ( ! $order_id ) return;
// Avoid SMS to be sent twice
$sms_new_order_sent = get_post_meta( $order_id, '_sms_new_order_sent', true );
if( 'yes' == $sms_new_order_sent ) return;
// Get the user complete name and billing phone
$user_complete_name = get_post_meta( $order_id, '_billing_first_name', true ) . ' ';
$user_complete_name .= get_post_meta( $order_id, '_billing_last_name', true );
$user_phone = get_post_meta( $order_id, '_billing_phone', true );
// 1st Query args (to the admin)
$query1 = http_build_query( array(
'token' => 'My-Token',
'sender' => 'medexit',
'message' => 'NEW ORDER',
'recipients.0.msisdn' => 4511111111
) );
// 2nd Query args (to the customer)
$query2 = http_build_query( array(
'token' => 'My-Token',
'sender' => 'medexit',
'message' => "Hello $user_complete_name. This is your new order confirmation",
'recipients.0.msisdn' => intval($user_phone)
) );
// Send both SMS
file_get_contents('https://gatewayapi.com/rest/mtsms?' . $query1);
file_get_contents('https://gatewayapi.com/rest/mtsms?' . $query2);
// Update (avoiding SMS to be sent twice)
update_post_meta( $order_id, '_sms_new_order_sent', 'yes' );
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
Tested on WooCommerce 3+…
Related SMS answer:
Sending an SMS for specific email notifications and order statuses

Categories