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

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;

Related

Cannot get featured image after Publish but works fine after Update

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

Woocommerce: append atribute value to order-notes

I'm trying to append the atribute value of pa-lager to delieverynotes and invoices. I'm working from this answer.
This is what I have:
function lager_placering( $product ) {
if( isset( $product->id ) ) {
$lager = $product->get_attribute('pa_lager');
//echo $lager;
}
}
add_action( 'wcdn_order_item_after', 'lager_placering' );
It does not work. at all.
This works like a charm
function lager_placering( $product ) {
$lager = $product->get_attribute('pa_lager');
echo $lager;
}
add_action( 'wcdn_order_item_after', 'lager_placering' );

Get Post ID of post you're currently editing in WordPress

I'm attempting to get the ID of the post I am editing in functions.php for the purpose of dynamically rewriting a custom post type slug.
This is what I'm working with so far.
function change_post_type_slug( $args, $post_type ) {
if ( 'custom_post' == $post_type ) {
global $post;
$location = get_field('custom_field', $post->ID);
$args['rewrite']['slug'] = $location;
}
return $args;
}
add_filter( 'register_post_type_args', 'change_post_type_slug', 10, 2 );
I am not sure if the hook register_post_type_args is firing before I am able to get the ID, or if this is even the best way to go about what I am trying to accomplish. Can't find much out there on the subject.
I was able to get it to work with the following:
function change_post_type_slug( $args, $post_type ) {
if ( 'lead_page' == $post_type ) {
$post_id = $_GET['post'];
$location = get_field('leadpage_location', $post_id);
$args['rewrite']['slug'] = $location->post_name;
}
return $args;
}
add_filter( 'register_post_type_args', 'change_post_type_slug', 10, 2 );
However it resulted in a notice on the front-end:
Notice: Undefined index: post in /path/to/wordpress/functions.php on line 623
Line 623 is $post_id = $_GET['post'];
You should use the updated_postmeta hook for this, as its run every time you update your custom fields.
Then you can update your post data with wp_update_post() function.
add_action( 'updated_postmeta', function( $meta_id, $object_id, $meta_key, $meta_value ) {
if ( 'location' === $meta_key ) {
wp_update_post([
'ID' => $object_id,
'post_name' => $meta_value,
]);
}
}, 10, 4 );
Update:
Try this:
function change_post_types_slug( $args, $post_type ) {
if ( 'your-custom_post' === $post_type ) {
// Check and get the custom post ID
$id = isset($_GET[ 'post' ]) ? $_GET[ 'post' ] : '' ;
// $location = get_field('leadpage_location', $id);
$args['rewrite']['slug'] = 'new-slug-here';
}
return $args;
}
add_filter( 'register_post_type_args', 'change_post_types_slug', 10, 2 );
Try this out:
function change_post_type_slug( $args, $post_type ) {
if ( 'lead_page' === $post_type && is_admin() && $_GET['action'] === 'edit' ) {
$post_id = $_GET['post'];
$location = get_field('leadpage_location', $post_id);
$args['rewrite']['slug'] = $location->post_name;
}
return $args;
}
add_filter( 'register_post_type_args', 'change_post_type_slug', 10, 2 );
It adds two more conditionals, to check if you're on the admin screen and to check of there is a GET parameter of edit. Probably overkill to do is_admin() as well, but now you're super safe.

WooCommerce: how to add multiple products to cart at once?

I need a "get products A, B and C for $xxx" special offer, products A, B and C must be available on their own, and the bundle is a special offer accessible through a coupon code.
On a marketing page hosting outside my site, I would like a button leading to my site that carries a query string like ?add-to-cart=244,249,200 so that once on my site, all bundle products are already added to the cart (instead of adding them one by one which sounds unacceptably tedious).
If not possible, then at least I'd like a landing page on my site with a single button adding all bundle products to cart at once.
I couldn't find working solutions googling around (here's one example). Any suggestion?
After some research I found that DsgnWrks wrote a hook that does exactly this. For your convenience, and in case the blog goes offline, I bluntly copied his code to this answer:
function woocommerce_maybe_add_multiple_products_to_cart( $url = false ) {
// Make sure WC is installed, and add-to-cart qauery arg exists, and contains at least one comma.
if ( ! class_exists( 'WC_Form_Handler' ) || empty( $_REQUEST['add-to-cart'] ) || false === strpos( $_REQUEST['add-to-cart'], ',' ) ) {
return;
}
// Remove WooCommerce's hook, as it's useless (doesn't handle multiple products).
remove_action( 'wp_loaded', array( 'WC_Form_Handler', 'add_to_cart_action' ), 20 );
$product_ids = explode( ',', $_REQUEST['add-to-cart'] );
$count = count( $product_ids );
$number = 0;
foreach ( $product_ids as $id_and_quantity ) {
// Check for quantities defined in curie notation (<product_id>:<product_quantity>)
// https://dsgnwrks.pro/snippets/woocommerce-allow-adding-multiple-products-to-the-cart-via-the-add-to-cart-query-string/#comment-12236
$id_and_quantity = explode( ':', $id_and_quantity );
$product_id = $id_and_quantity[0];
$_REQUEST['quantity'] = ! empty( $id_and_quantity[1] ) ? absint( $id_and_quantity[1] ) : 1;
if ( ++$number === $count ) {
// Ok, final item, let's send it back to woocommerce's add_to_cart_action method for handling.
$_REQUEST['add-to-cart'] = $product_id;
return WC_Form_Handler::add_to_cart_action( $url );
}
$product_id = apply_filters( 'woocommerce_add_to_cart_product_id', absint( $product_id ) );
$was_added_to_cart = false;
$adding_to_cart = wc_get_product( $product_id );
if ( ! $adding_to_cart ) {
continue;
}
$add_to_cart_handler = apply_filters( 'woocommerce_add_to_cart_handler', $adding_to_cart->get_type(), $adding_to_cart );
// Variable product handling
if ( 'variable' === $add_to_cart_handler ) {
woo_hack_invoke_private_method( 'WC_Form_Handler', 'add_to_cart_handler_variable', $product_id );
// Grouped Products
} elseif ( 'grouped' === $add_to_cart_handler ) {
woo_hack_invoke_private_method( 'WC_Form_Handler', 'add_to_cart_handler_grouped', $product_id );
// Custom Handler
} elseif ( has_action( 'woocommerce_add_to_cart_handler_' . $add_to_cart_handler ) ){
do_action( 'woocommerce_add_to_cart_handler_' . $add_to_cart_handler, $url );
// Simple Products
} else {
woo_hack_invoke_private_method( 'WC_Form_Handler', 'add_to_cart_handler_simple', $product_id );
}
}
}
// Fire before the WC_Form_Handler::add_to_cart_action callback.
add_action( 'wp_loaded', 'woocommerce_maybe_add_multiple_products_to_cart', 15 );
/**
* Invoke class private method
*
* #since 0.1.0
*
* #param string $class_name
* #param string $methodName
*
* #return mixed
*/
function woo_hack_invoke_private_method( $class_name, $methodName ) {
if ( version_compare( phpversion(), '5.3', '<' ) ) {
throw new Exception( 'PHP version does not support ReflectionClass::setAccessible()', __LINE__ );
}
$args = func_get_args();
unset( $args[0], $args[1] );
$reflection = new ReflectionClass( $class_name );
$method = $reflection->getMethod( $methodName );
$method->setAccessible( true );
$args = array_merge( array( $class_name ), $args );
return call_user_func_array( array( $method, 'invoke' ), $args );
}
It works just like you'd expect, by providing a comma separated list of products. It even works with quantities using ?add-to-cart=63833:2,221916:4
I was, and am still looking for a 'pure' solution that allows to add multiple products to the cart without having to install a plugin or add custom actions. But for many, the above might be an appropriate solution

Move custom column admin links from below "post title"

It seems I can't figure out how to add the edit, remove, view, etc... to one of my custom columns in the backend of wordpress. The idea is to get the links that are attached to title when one hovers over the title, to be attached to a different column.
This is what the below code outputs.
This is what I want the link in the authors column have when mouse is hovered over the authors, just like when you hover over the title in this screenshot; all the edit links.
This is what I have so far:
add_filter( 'manage_edit-testimonial-quotes_columns', 'view_columns' ) ;
function view_columns( $columns ) {
$columns = array(
'cb' => '',
'date' => __( 'Date' ),
'tq_author' => __( 'Author' ),
'tq_quote' => __( 'Testimonial' ),
);
return $columns;
}
add_action('manage_testimonial-quotes_posts_custom_column', 'custom_view_columns', 10, 2);
function custom_view_columns($column, $post_id){
global $post;
switch ($column){
case 'tq_author':
echo '<a href="post.php?post=' . $post->ID . '&action=edit">';
$column_content = the_field('tq_author');
echo $column_content;
echo '</a>';
break;
case 'tq_quote':
$column_content = the_field('tq_quote');
echo $column_content;
break;
default:
break;
}
}
The best way of doing this since WP 4.3.0 is using
add_filter( 'list_table_primary_column', [ $this, 'list_table_primary_column' ], 10, 2 );
public function list_table_primary_column( $default, $screen ) {
if ( 'edit-yourpostype' === $screen ) {
$default = 'yourcolumn';
}
return $default;
}
I really doubt that there's a hook to deal with that. So, I'll not even check the core and go straight to the dirty solution:
add_action( 'admin_head-edit.php', 'so_13418722_move_quick_edit_links' );
function so_13418722_move_quick_edit_links()
{
global $current_screen;
if( 'post' != $current_screen->post_type )
return;
if( current_user_can( 'delete_plugins' ) )
{
?>
<script type="text/javascript">
function so_13418722_doMove()
{
jQuery('td.post-title.page-title.column-title div.row-actions').each(function() {
var $list = jQuery(this);
var $firstChecked = $list.parent().parent().find('td.author.column-author');
if ( !$firstChecked.html() )
return;
$list.appendTo($firstChecked);
});
}
jQuery(document).ready(function ($){
so_13418722_doMove();
});
</script>
<?php
}
}
Result:
Notes:
adjust your post_type: 'post' != $current_screen->post_type
adjust your column classes: find('td.author.column-author')
Bug and solution:
You'll note that, after updating, the quick-edit menu goes back to its original position. The following AJAX interception deals with it. Refer to this WordPress Developers answer for more details.
add_action( 'wp_ajax_inline-save', 'so_13418722_ajax_inline_save' , 0 );
/**
Copy of the function wp_ajax_inline_save()
http://core.trac.wordpress.org/browser/tags/3.4.2/wp-admin/includes/ajax-actions.php#L1315
Only Modification marked at the end of the function with INTERCEPT
*/
function so_13418722_ajax_inline_save()
{
global $wp_list_table;
check_ajax_referer( 'inlineeditnonce', '_inline_edit' );
if ( ! isset($_POST['post_ID']) || ! ( $post_ID = (int) $_POST['post_ID'] ) )
wp_die();
if ( 'page' == $_POST['post_type'] ) {
if ( ! current_user_can( 'edit_page', $post_ID ) )
wp_die( __( 'You are not allowed to edit this page.' ) );
} else {
if ( ! current_user_can( 'edit_post', $post_ID ) )
wp_die( __( 'You are not allowed to edit this post.' ) );
}
set_current_screen( $_POST['screen'] );
if ( $last = wp_check_post_lock( $post_ID ) ) {
$last_user = get_userdata( $last );
$last_user_name = $last_user ? $last_user->display_name : __( 'Someone' );
printf( $_POST['post_type'] == 'page' ? __( 'Saving is disabled: %s is currently editing this page.' ) : __( 'Saving is disabled: %s is currently editing this post.' ), esc_html( $last_user_name ) );
wp_die();
}
$data = &$_POST;
$post = get_post( $post_ID, ARRAY_A );
$post = add_magic_quotes($post); //since it is from db
$data['content'] = $post['post_content'];
$data['excerpt'] = $post['post_excerpt'];
// rename
$data['user_ID'] = $GLOBALS['user_ID'];
if ( isset($data['post_parent']) )
$data['parent_id'] = $data['post_parent'];
// status
if ( isset($data['keep_private']) && 'private' == $data['keep_private'] )
$data['post_status'] = 'private';
else
$data['post_status'] = $data['_status'];
if ( empty($data['comment_status']) )
$data['comment_status'] = 'closed';
if ( empty($data['ping_status']) )
$data['ping_status'] = 'closed';
// update the post
edit_post();
$wp_list_table = _get_list_table('WP_Posts_List_Table');
$mode = $_POST['post_view'];
$wp_list_table->display_rows( array( get_post( $_POST['post_ID'] ) ) );
// INTERCEPT: Check if it is our post_type, if not, do nothing
if( 'post' == $_POST['post_type'] )
{
?>
<script type="text/javascript">so_13418722_doMove();</script>
<?php
}
// end INTERCEPT
wp_die();
}
I had the same need.
Nicola's solution worked for me except I was getting an "Undefined variable" notice/error. Then I realized that the parameter has to be without the "[$this ... ]" part.
I guess that was a copy/paste from the documentation.
So this worked:
add_filter( 'list_table_primary_column', 'list_table_primary_column', 10, 2 );
function list_table_primary_column( $default, $screen ) {
if ( 'edit-your_post_type' === $screen ) {
// Set default columns to Minutes Spent.
$default = 'your_column';
}
return $default;
}
If you don't know what your_column is, just inspect the title of that column and get the ID.
You can't move the actions per se without resorting to JS, as the accepted answer does. However, you can very easily build your own version of the actions popup with php and inbuilt Wordpress functions. This version will work even if the user has JS turned off.
Presuming you use a switch to populate your custom columns, do something likes this, if not adapt to your own function:
switch ( $column ) {
case 'your_column_name':
echo "Your custom content here";
my_custom_column_actions($post_id);
break;
}
Then have a separate function that recreates the actions popup.
function my_custom_column_actions($post_id) {
if($_GET['post_status']!='trash') :
$bare_url = "/wp-admin/post.php?post=$post_id&action=trash";
$nonce_url = wp_nonce_url( $bare_url, 'trash-post_'.$post_id );
echo " <div class='row-actions'>
<span class='edit'>
<a href='/wp-admin/post.php?post=$post_id&action=edit'>Edit</a> |
</span>
<span class='trash'>
<a href='$nonce_url' class='submitdelete'>Trash</a>
</span>
<span class='edit'>
<a href='".get_the_permalink($post_id)."'>View</a> |
</span>
</div>";
else:
$bare_url = "/wp-admin/post.php?post=$post_id&action=untrash";
$nonce_url = wp_nonce_url( $bare_url, 'untrash-post_'.$post_id );
$delete_url = "/wp-admin/post.php?post=$post_id&action=delete";
$nonce_delete_url = wp_nonce_url( $delete_url, 'delete-post_'.$post_id );
echo " <div class='row-actions'>
<span class='untrash'>
<a href='$nonce_url' class='untrash'>Restore</a> |
</span>
<span class='delete'>
<a href='$nonce_delete_url' class='submitdelete'>Delete Permanently</a>
</span>
</div>";
endif;
}
All the business with nonce_urls is important for trashing, restoring or deleting; these actions won't work without it.
If you want to include this on a column that would normally appear, e.g. author or date published, you'll need to not include the standard column when you're declaring your custom columns and instead include a custom column that gets the same data (plus a call to the function above).
The same goes for if you want to include the title but not have the actions appear under it - otherwise they'll appear twice. Don't include the title column and instead include your own custom column that grabs the title but not the new function.
You can also very easily add your own actions by just editing the content that the function echoes.

Resources