Cannot get featured image after Publish but works fine after Update - wordpress

I have a WordPress hook: add_action( 'publish_post', 'post_published_notification', 10, 2 );
When publishing I am unable to get the featured image. I have tried many different methods to no avail. After the initial publishing of an article I get '0' for the thumbnail id but after editing and clicking update I get all the correct values.
Hook looks like this:
function post_published_notification( $post_id, $post ) {
$post_status = get_post_status( $post_id ); //always returns "publish"
$title = $post->post_title; //works correctly always
$permalink = get_permalink( $post_id ); //works correctly always
$excerpt = get_the_excerpt($post); //works correctly always
//All three variables below are empty when publishing a post but assign correctly when updating an existing post
$image = get_the_post_thumbnail_url( $post_id, 'medium' );
$image2 = get_the_post_thumbnail_url($post_id, 'article-thumbnail-image');
$image3 = get_post_meta( get_post_meta( $post_id, "_thumbnail_id", true ), "_wp_attached_file", true );
$thumb_id = get_post_thumbnail_id( $post_id ); //returns 0 on publish; Correct Id on update
}

Try using the "wp_after_insert_post" hook.
add_action( 'wp_after_insert_post', 'after_insert_post', 10, 4 );
function after_insert_post( $post_id, $post, $update, $post_before ) {
if ( 'publish' !== $post->post_status||( $post_before && 'publish' === $post_before->post_status )||wp_is_post_revision( $post_id )) {
return;
}
$image_url = get_the_post_thumbnail_url($post_id);
}

Related

Wordpress media upload define default meta values

i want to add default values to metadata of images automatically while/after they are uploaded.
// add default values to custom fields upon upload
add_action( 'add_attachment', 'as_set_image_meta_upon_image_upload' );
function as_set_image_meta_upon_image_upload( $post_ID ) {
// Check if uploaded file is an image, else do nothing
if ( wp_attachment_is_image( $post_ID )) {
if (strlen(trim(get_post_meta( $post_ID, 'photographer', true))) == 0 ) {
update_post_meta( $post_ID, 'photographer', 'unknown' );
}
if (strlen(trim(get_post_meta( $post_ID, 'copyright', true))) == 0 ) {
update_post_meta( $post_ID, 'copyright', 'not defined' );
}
}
}
it works fine for the custom fields 'photographer' and 'copyright' but i also want to do it for the image caption. In another section of the code (hooked to attachment_fields_to_save) i am successfully using this statement to fill empty captions
if (strlen(trim($post['post_excerpt'])) == 0) {
$pretext = '[Attribution: ';
$pretext .= get_post_meta( $post_ID, 'photographer', true);
$pretext .= '; Copyright: ';
$pretext .= get_post_meta( $post_ID, 'copyright', true);
$pretext .= ']';
$post['post_excerpt'] = $pretext.' '.$post['post_excerpt'];
}
but i would rather move it to the 'add_attachment' hook. But when i do try to add it the image upload fails. I think because it uses the $post variable which is not used by the hook. i tried to replace $post with get_post($post_ID) to limit myself to the variables used by the hook but that didnt work either. I also tried to put
$post = get_post($post_ID)
before the if statement but then the whole site crashes, probably its some kind of global variable i shouldnt mess with by assigning it manually.
So my question is how can i fit the if statement in the 'add_attachment' hook, or, more general, how can i assign a default caption to images upon upload.
i managed to automatically fill in a default caption upon upload
add_action( 'add_attachment', 'as_set_image_meta_upon_image_upload' );
function as_set_image_meta_upon_image_upload( $post_ID ) {
// Check if uploaded file is an image, else do nothing
if ( wp_attachment_is_image( $post_ID )) {
//default photographer
if (strlen(trim(get_post_meta( $post_ID, 'photographer', true))) == 0 ) {
update_post_meta( $post_ID, 'photographer', 'unknown' );
}
//default copyright
if (strlen(trim(get_post_meta( $post_ID, 'copyright', true))) == 0 ) {
update_post_meta( $post_ID, 'copyright', 'not defined' );
}
//default caption
$my_image_meta = array(
'ID' => $post_ID,
'post_excerpt' => '[Attribution: unknown; Copyright: not defined] ',
);
wp_update_post( $my_image_meta );
}
}
when i tried to load the actual values of 'photographer' and 'copyright' they returned empty, i suppose because there are just being filled in the same hook. good enough though

How to Accept Orders on Woocommerce as per location?

I have a woocommerce website hosted on domain https://www.micropediaglobal.com.
I have one requirement that my different branch managers located at different locations should see the orders as per the locators and process their orders only.
Can someone please guide here ?
The Website Development Company website does not seems to be on wordpress, however you can bifurcate or process woocommerce orders location wise as below:
add_action( 'woocommerce_checkout_update_order_meta', 'my_custom_checkout_field_update_order_meta' );
function my_custom_checkout_field_update_order_meta( $order_id ) {
if ( ! empty( $_POST['xerox_shop_name'] ) ) {
update_post_meta( $order_id, 'xeroxshopmeta', sanitize_text_field( $_POST['xerox_shop_name'] ) );
}
}
add_action( 'woocommerce_admin_order_data_after_billing_address', 'my_custom_checkout_field_display_admin_order_meta', 10, 1 );
function my_custom_checkout_field_display_admin_order_meta($order){
echo '<p><strong>'.__('Xerox Center Name').':</strong> ' . get_post_meta( $order->id, 'xeroxshopmeta', true ) . '</p>';
}
//add custom field column
add_filter( 'manage_edit-shop_order_columns', 'MY_COLUMNS_FUNCTION' );
function MY_COLUMNS_FUNCTION( $columns ) {
$new_columns = ( is_array( $columns ) ) ? $columns : array();
unset( $new_columns[ 'order_actions' ] );
//edit this for your column(s)
//all of your columns will be added before the actions column
$new_columns['xeroxColumn'] = 'Xerox Center Name';
//stop editing
$new_columns[ 'order_actions' ] = $columns[ 'order_actions' ];
return $new_columns;
}
add_filter( "manage_edit-shop_order_sortable_columns", 'MY_COLUMNS_SORT_FUNCTION' );
function MY_COLUMNS_SORT_FUNCTION( $columns )
{
$custom = array(
'xeroxColumn' => 'xeroxshopmeta',
);
return wp_parse_args( $custom, $columns );
}
add_action( 'manage_shop_order_posts_custom_column', 'MY_COLUMNS_VALUES_FUNCTION', 2 );
function MY_COLUMNS_VALUES_FUNCTION( $column ) {
global $post;
$data = get_post_meta( $post->ID );
//start editing, I was saving my fields for the orders as custom post meta
//if you did the same, follow this code
if ( $column == 'xeroxColumn' ) {
echo get_post_meta( $post->ID, 'xeroxshopmeta', true );
}
}

Custom Field created in add_meta_boxes reappearing itself again in the default Custom Metabox

I succeed in creating a metabox with custom field inside, and I restrict it to appear in a custom post type.
//define metabox
function product_info_en() {
add_meta_box( 'english_info', 'English Info', 'english_product_name_callback', array('product'), 'normal', 'high' );
}
//add to hook
add_action( 'add_meta_boxes', 'product_info_en' );
The code to display it in the product page:
// display in add product admin page
function english_product_name_callback( $post ) {
//ob_start();
$content = esc_attr( get_post_meta( get_the_ID(), 'product_desc_en', true ) );
//here goes the custom field
echo '<fieldset><div><label><b>English Product Name:</b></label><br/>';
echo '<input id="product_name_en" type="text" name="product_name_en" style="width:100%; margin:10px 0px"';
echo ' value="';
echo esc_attr( get_post_meta( get_the_ID(), 'product_desc_en', true ) );
echo '"></div></fieldset>';
//here goes the wp_editor
echo '<fieldset><div><label><b>English Product Content Info:</b></label><div><br/>';
echo '<div>';
wp_editor($content, 'product_desc_en', array(
'wpautop' => true,
'media_buttons' => true,
'textarea_rows' => 10
)
);
echo '</div></fieldset>';
}
Here goes the code that do the saving job:
//save
function enginfo_save_meta_box( $post_id ) {
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return;
if ( $parent_id = wp_is_post_revision( $post_id ) ) {
$post_id = $parent_id;
}
$fields = [
'product_name_en',
];
foreach ( $fields as $field ) {
if ( array_key_exists( $field, $_POST ) ) {
update_post_meta( $post_id, $field, sanitize_text_field( $_POST[$field] ) );
}
}
update_post_meta( $post_id,'product_desc_en', wp_kses_post( $_POST['product_desc_en'] ) );
}
add_action( 'save_post', 'enginfo_save_meta_box' );
However, the custom created field that supposed to be going only into the newly created metabox, will always show up in the default "custom field". And this happens to all post type.
As shown below, What could possibly be the issue here?
To hide and not show your custom fields there in default box, please prefix your custom fields with underscore _ , so product_desc_en will become _product_des_en
I mean the names of your custom fields should be prefixed with underscore and WordPress default custom metabox will ignore them and not show in WordPress default GUI, but you can use and display them in your own custom metaboxes by calling with there new Underscore prefixed names.

How to remove Author Tag from being visible in Discord's previews?

When sharing a post to Discord, the preview Discord generates shows the author name and URL. We removed all information about the author but it didn't stop the author tag from showing.
That’s done via oEmbed. Add below code in your functions.php file
add_filter( 'oembed_response_data', 'disable_embeds_filter_oembed_response_data_' );
function disable_embeds_filter_oembed_response_data_( $data ) {
unset($data['author_url']);
unset($data['author_name']);
return $data;
}
**disorc may have stored the response in cache so create new post or page and test that **
#hrak has the right idea but his answer lacks context for those of us not used to dealing with PHP.
What I ended up doing was check if there was already a filter for 'oembed_response_data' in /wp-includes/default-filters.php. Mine looked like this:
add_filter( 'oembed_response_data', 'get_oembed_response_data_rich', 10, 4 );
Add the previous line to the specified file if, for whatever reason, it isn't there already.
Afterward, I checked in wp-includes/embed.php for the get_oembed_response_data_rich function, which looked like this:
function get_oembed_response_data_rich( $data, $post, $width, $height ) {
$data['width'] = absint( $width );
$data['height'] = absint( $height );
$data['type'] = 'rich';
$data['html'] = get_post_embed_html( $width, $height, $post );
// Add post thumbnail to response if available.
$thumbnail_id = false;
if ( has_post_thumbnail( $post->ID ) ) {
$thumbnail_id = get_post_thumbnail_id( $post->ID );
}
if ( 'attachment' === get_post_type( $post ) ) {
if ( wp_attachment_is_image( $post ) ) {
$thumbnail_id = $post->ID;
} elseif ( wp_attachment_is( 'video', $post ) ) {
$thumbnail_id = get_post_thumbnail_id( $post );
$data['type'] = 'video';
}
}
if ( $thumbnail_id ) {
list( $thumbnail_url, $thumbnail_width, $thumbnail_height ) = wp_get_attachment_image_src( $thumbnail_id, array( $width, 99999 ) );
$data['thumbnail_url'] = $thumbnail_url;
$data['thumbnail_width'] = $thumbnail_width;
$data['thumbnail_height'] = $thumbnail_height;
}
return $data;
}
I just added the two lines of code that #hrak introduced in his answer to remove the author tag (name and URL) from $data before it was returned:
function get_oembed_response_data_rich( $data, $post, $width, $height ) {
(...)
if ( $thumbnail_id ) {
list( $thumbnail_url, $thumbnail_width, $thumbnail_height ) = wp_get_attachment_image_src( $thumbnail_id, array( $width, 99999 ) );
$data['thumbnail_url'] = $thumbnail_url;
$data['thumbnail_width'] = $thumbnail_width;
$data['thumbnail_height'] = $thumbnail_height;
}
unset($data['author_url']);
unset($data['author_name']);
return $data;
}
As before, add the get_oembed_response_data_rich function if it does not already exist. After about 5-10 minutes, Discord link embeds stopped showing the author tag.
Source:
http://hookr.io/filters/oembed_response_data/
https://developer.wordpress.org/reference/functions/get_oembed_response_data_rich/
I've done this by emptying the posted_by function like this article shows, in the "Use Code to Remove the Author Name" section
https://wpdatatables.com/how-to-hide-the-author-in-wordpress/
basically find the posted_by function and empty it
function twentynineteen_posted_by() {
}
endif;

Wordpress update button works but not publish button

I asked the programmer to have the title of every post automatically be the date selected and the place selected (to allow users to save some time). When I click 'publish' the title of the post is the date twice (ie; 03-26-15 03-26-15). Then the 'publish' button turns into an 'update' button. And then when I click 'update' the title will be correct (ie; 03-26-15 London). I'm trying to figure out how to get it this way after clicking 'publish' the first time. The programmer disappeared and I can't figure it out. Any help would be great.
function post_updated( $post_id ) {
global $post_type;
if ($post_type == 'place') {
if ( !wp_is_post_revision( $post_id ) && !(defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE) ) {
$postTitle.=get_the_date( 'm/d/Y', $post_id );
$postTitle.=" ".get_the_title(get_post_meta($post_id, 'place_locale', true) ) ;
$post['ID'] = $post_id;
$post['post_title'] = $postTitle;
remove_action( 'save_post', 'post_updated' );
wp_update_post($post);
add_action( 'save_post', 'post_updated' );
}
}
}
add_action( 'save_post', 'post_updated' );
The .= operator appends, therefor your titles are being duplicated.
Simply change it to = and you should be fine.
Are you sure this is the only function? It seems to only have "update post" code.
Post creation is handled with wp_insert_post something like:
$my_post = array(
'post_title' => $title,
'post_content' => "",
'post_status' => "pending",
'post_author' => wp_get_current_user()->ID
);
$post_id = wp_insert_post( $my_post );
Old question, but this may help who got into this question:
There are some problems with the code:
global $post_type is not defined.
As mentioned by #dojs, you should use = operator instead of .= to define the variable first.
get_the_title() function only accepts post_id or post object as the param.
Since you're dealing with a custom post type of place, it's better to use a post type specific hook instead of the general and crowded save_post hook.
After these modifications, the final code could be something like this:
function tst_post_updated( $post_id )
{
if ( !wp_is_post_revision( $post_id ) && !(defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE) ) {
$post_title = get_the_date( 'm/d/Y', $post_id );
$post_title .= " " . get_post_meta($post_id, 'place_locale', true);
$post_title = sanitize_title($post_title);
$post['ID'] = $post_id;
$post['post_title'] = $post_title;
remove_action( 'save_post_place', 'tst_post_updated' );
wp_update_post($post);
add_action( 'save_post_place', 'tst_post_updated' );
}
}
add_action( 'save_post_place', 'tst_post_updated' );

Resources