function when_a_review_gets_submitted ($review, $post_id) {
// Do something
}
add_action('rwp_after_saving_review', 'when_a_review_gets_submitted', 11, 2);
I have this WP_Query and loop to update a custom field of every childpage of the parentpage were somebody has left a review.
// Set up the objects needed
$hosting_provider_query = new WP_Query();
global $post;
$hosting_pagina_titel = $post->post_title;
$search_all_pages = $hosting_provider_query->query(array(
'post_type' => 'page',
'post_status' => 'publish',
//Only get pages where custom field 'name_hosting_provider' equals Page title
'meta_query' => array(
'relation' => 'AND',
array(
'key' => 'naam_hosting_provivder',
'value' => $hosting_pagina_titel,
'compare' => '='
),
),
));
// Loop through all pages and find Page's children
$loop_through_all_child_pages = get_page_children( get_the_ID(), $search_all_pages );
// Loop through everything we got back
if(!empty($loop_through_all_child_pages)){
foreach($loop_through_all_child_pages as $child_page){
// get the ID of each childpage
$get_child_page_ID = $child_page->ID;
// get the ID of each parent page of the child pages
$get_parent_page_ID = get_queried_object_id();
// Get the average score from post_meta of the parent page
$get_average_score = get_post_meta( $get_parent_page_ID, 'rwp_user_score', true );
// update each custom field of the childs with the average score data from the post meta of parent page
update_field('gemiddelde_score_hosting_provider', $get_average_score, $get_child_page_ID);
}
}
How can I correctly execute this code within the above function?
EDIT
Ok I figured this out, the function is working properly when I remove the parameters $review and $post_id. And when I remove the add action:
add_action('rwp_after_saving_review', 'when_a_review_gets_submitted', 11, 2);
and replace it with:
add_action( 'template_redirect', 'when_a_review_gets_submitted' );
but I think this is a bit overkill for what I am trying to achieve. If I understand template_redirect it executes the function everytime a page is visited with that template? Am I correct?
So when I have 900 child pages it updates every custom field "gemiddelde_score_hosting_provider" when a page with that template is visited? So 900 times every single time a page with that template is visited? Am I correct in this one?
Is there a way to only update the custom field of the childs from the parent page where the review is submitted?
Related
I'm trying to hide products in Woocommerce according to the user ID who published them.
I have created the following code but it doesn't work well.
function Products_for_vendor() {
$args = array( 'post_type' => 'product', 'post_author' => '2' );
$products = get_posts( $args );
foreach ($products as $product->ID) {
$post_id = $product->ID
$terms = array( 'exclude-from-catalog', 'exclude-from-search' );
wp_set_object_terms( $post_id, $terms, 'product_visibility', false );
}
}
add_action( 'init', 'Products_for_vendor' );
to hide the post I extracted the code mentioned in this query: Change product visibility via PHP on Woocommerce 3+
Any help or comment is well received.
Thanks in advance.
You shouldn't be changing things like this directly - WooCommerce has special functions to ensure future compatibility with any database structural changes, and to ensure that product data is properly synchronised within its internal caches.
Instead, inside of your foreach loop, use this:
// Get an instance of the product
$theproduct = wc_get_product($product->ID);
// Change the product visibility (options are: 'hidden', 'visible', 'search' and 'catalog'.
$theproduct->set_catalog_visibility('hidden');
// Finally, save and sync the product changes
$theproduct->save();
I'm writing what I thought was a simple series of functions to assign a "deletion date" to media, then auto-delete those expired media when the site is visited.
The post_meta for deletion date is set for the images via an online form when the images are uploaded (using formidable pro forms and the "after_create_entry" hook. I can confirm that the meta field is created successfully, and the deletion date is assigned properly (called 'mtp_deletiondate'. To test, I did a wp_query on a custom page and each image has a properly set deletion date.
Next, I wanted to run a function that checked for expired images (set to be 21 days after date of upload), and if they are expired, to delete them. I want to trigger this function whenever I access the admin, because I figure I get in there at least once a month to run updates, and it's a good time to clean out the old images. For this situation, I decided not to do a cron job since I can reliably visit the site once a month anyway.
The issue is the function doesn't seem to be triggering, and I don't know if it's because the function is broken or because I'm using the wrong action, or both. Some research tells me to use the admin_init, but I've also tried "wp", and "wp-footer". It might be that I'm just misunderstanding the process. My function (in my theme's functions.php):
function drick_delete_expired_uploads() {
// WP_Query arguments
$args = array (
'post_status' => 'any',
'post_type' => array( 'Attachment' ),
'posts_per_page' => -1,
'meta_query' => array(
array(
'key' => 'mtp_deletiondate',
),
),
);
// The Query
$mediaquery = new WP_Query( $args );
// The Loop
if ( $mediaquery->have_posts() ) {
while ( $mediaquery->have_posts() ) {
$mediaquery->the_post();
date_default_timezone_set('America/Denver');
$CurrentDate = date('Y-m-d h:i');
$CurrentDateStr = strtotime($CurrentDate);
$DeletionDate = get_post_meta( $post->ID, 'mtp_deletiondate', true );
$DeletionDateStr = strtotime($DeletionDate);
if ( isset($DeletionDateStr) ) {
if ( $DeletionDateStr < $CurrentDateStr ) {
wp_delete_attachment( $post->ID, true );
}
}
}
} else {
// no posts found
} // IF HAVE POSTS
// Restore original Post Data
wp_reset_postdata();
}
add_action('admin_init', 'drick_delete_expired_uploads');
If I save my functions.php, then reload the Wordpress dashboard, then check my media, the expired images are still there. HOWEVER, if I add this function to an actual page then visit the page, it does work. So I believe the function is doing what it's supposed to, it's just not getting triggered properly? I also added a quick wp_mail() to the function in my functions.php, and when I visited the admin it did trigger the email, so I guess the function is firing.
I would appreciate any insight, thank you!
So I think I figured it out, but I don't know that I have an explanation as to why it works. Essentially it looks like wp_delete_attachment wasn't working, but wp_delete_post DOES work. I've tested and confirmed with three additional images that the function auto delete is triggered when accessing the admin dashboard. I also changed the way the query arguments are structured by only querying the expired images, rather than querying ALL images that have a mtp_deletiondate meta then running a conditional statement within the query. Don't know if that's related or not. The final working function:
function drick_delete_expired_uploads() {
// WP_Query arguments
date_default_timezone_set('America/Denver');
$CurrentDate = date('Y-m-d h:i');
$args = array (
'post_status' => 'any',
'post_type' => array( 'Attachment' ),
'posts_per_page' => -1,
'meta_query' => array(
array(
'key' => 'mtp_deletiondate',
'value' => $CurrentDate,
'compare' => '<',
'type' => 'DATE',
),
),
);
// The Query
$mediaquery = new WP_Query( $args );
// The Loop
if ( $mediaquery->have_posts() ) {
while ( $mediaquery->have_posts() ) {
$mediaquery->the_post();
wp_delete_post(get_the_ID());
}
} else {
// no posts found
} // IF HAVE POSTS
// Restore original Post Data
wp_reset_postdata();
}
add_action('admin_init', 'drick_delete_expired_uploads');
Still look forward to any feedback from someone in the know that can tell me why the previous version wasn't working (looking to learn here). Thanks!
I have following structure
Services
-Page_1
-Page_2
--Page_3
--Page_4
I use Wp-query to get pages. This is my args:
<?php $args = array(
'post_type' => 'page',
'post_parent' => '45'
); ?>
45 is ID of Services page.
But I only get first level Page_1 and Page_2. How do I get all pages? I'm using Advanced Custom Fields plugin so using get_pages() is not a good option, is it?
As mentioned in your comments, the easiest solutions is to actually use get_pages(). You can still grab meta data of posts if you are able to get the the ID of the page (which you can with get_pages()) so you should still be able to ACF's custom fields.
Here's an example of get_pages():
$args = array(
'child_of' => 45,
'post_type' => 'page',
);
$pages = get_pages($args);
The main difference between get_pages() and WP_Query that we want to focus on here is the 'child-of'=>45 paramater vs the 'post_parent'=>45.
The child-of argument will grab ALL children throughout the hierarchy, i.e. children and children's children etc.
In contrast, the post-parent argument of WP_Query will only grab direct children of the page.
Using in conjunction with ACF
If you need to grab custom fields from ACF, you will still be able to use get_post_meta().
If your custom field includes an array of values, you will need to unserialize it first and then loop through the values like this:
$meta = get_post_meta( $post->ID, 'acf_meta_key', true ); //grab the post meta using WordPress core function
$array = unserialize( $meta ); //unserialize the field into an array
foreach ( $array as $value ) { //loop through the array
echo $value .'<br>';
}
I am building a plugin to update all posts from a custom type at once.
I have over 20K listings of events and 1000 venues. A venue is selected in the listing post when created and some info is copied into the listing, but if you modify the venue after that, the listing have to be refreshed manually. (I did not create that system but trying to improve.)
In the new admin page I created, you click a button, it refreshes and runs a PHP function on GET. That part works, the function is triggered. But apparently the get_posts function I'm using is causing the function to crash.
function ac_update_listings() {
global $post;
$my_posts = get_posts( array(
'post_type' => 'listing',
'post_status' => 'any',
'numberposts' => -1
) );
foreach ( $my_posts as $my_post ):
$post_id = $my_post['ID'];
echo $post_id;
//Get Venue ID
$thevenue = get_post_meta($post_id, 'thevenue', true);
//Get Venue info
$block = get_post_meta($thevenue, 'block', true);
$street = get_post_meta($thevenue, 'street', true);
$number = get_post_meta($thevenue, 'number', true);
// Update Data
update_post_meta($post_id, 'block', $block);
update_post_meta($post_id, 'street', $street);
update_post_meta($post_id, 'number', $number);
endforeach;
echo "Listings are now updated.";
}
Firstly, you have numberposts, this should be posts_per_page. Since get_posts uses WP_Query parameters for query.
And I think the query will run faster if you set it to 999 instead of -1. -1 takes all the posts, and if you have 1000+ posts this takes time and resources. You could limit the query by querying only the latest posts, or if your venues have expiration date or something like that if you are pushing the ones that expired to the draft, you could probably query only published posts, which will then be < 999 posts (a guess).
All this will improve the performance of the query, and it could prevent any crashing.
i have a custom post type and would like to change the number of posts per page. i use the following code to show/limit the posts:
$args = array(
'post_type' => 'movie',
'posts_per_page' => 3,
'tax_query' => array(
array(
'taxonomy' => $wp_query->queried_object->taxonomy,
'field' => 'slug',
'terms' => $wp_query->queried_object->slug,
)
),
'paged' => get_query_var('paged') ? get_query_var('paged') : 1
);
query_posts( $args );
for this time i have 20 posts with this post type and the default posts per page in wordpress admin (settings/read ...) is set to 10.
if i call the url without a page it shows 3 posts, if i call the url with "page/2/" it shows 3 posts but if i call the page with "page/3/" it shows nothing found ...
i wouldn't change the default value for the posts in the admin - does someone have a idea?
note: to "debug" i let me show the value for "$wp_query->post_count;" - this use the default admin posts per page - 10 ...
regards kai
When you load the page, it will do a query before the template file (archive.php) is called.
That first query will use the defaults set in WordPress; ie. 10 posts per page. By the sounds of things, you're running that second 'query_posts' call within archive.php, but it sounds like that is after you have run the appropriate checks.
Two possible solutions for you:
Modify the first query with the posts_per_page
add_filter( 'pre_get_posts', 'modify_movie_query' );
function modify_movie_query( $wp_query ) {
if( $wp_query->query_vars['post_type'] != 'movie' ) return;
$wp_query->query_vars['posts_per_page'] = 3;
}
Because you have modified a reference to $wp_query, you don't need to return it.
Run the query_posts call at the top of the archive.php template
Option 1 is what I would recommend - it's the most efficient, and the most appropriate.
The approved answer doesn't really work if the archive page is for a custom taxonomy. In that case, you might want to use the following:
add_filter( 'pre_get_posts', 'modify_movie_query' );
function modify_movie_query( $wp_query ) {
if(is_tax('movie-category')){
$wp_query->query_vars['posts_per_page'] = 10;
}
return $wp_query
}