Link to home
Start Free TrialLog in
Avatar of Lazaro ORTEGA
Lazaro ORTEGA

asked on

Wordpress Post ID range on php/MySql query

I have the following PHP code to update custom fields values on my Wordpress custom post type posts. This code works perfect and in this example it SET all posts with value "premium" to value "any". That works perfect.

What I want to do is to add 2 new variables to specify the post id range to be updated: "$from_post_id" and "$to_post_id".

So, when I add $from_post_id = 10; and  $to_post_id = 20; it will update posts from id 10 to 20 only and not all posts as it does currently.

Here is my current code:

$from_value = 'premium';
$to_value = 'any';


$type = 'ebooks';
$args = array(
  'post_type' => $type,
  'post_status' => array('publish', 'pending', 'draft', 'auto-draft', 'future', 'private', 'inherit', 'trash'),
  'posts_per_page' => -1,
  'ignore_sticky_posts'=> 1
 );
$lbt_query = null;
$lbt_query = new WP_Query($args);
if( $lbt_query->have_posts() ) {
  while ($lbt_query->have_posts()) : $lbt_query->the_post();
  
  if(lbt_get_meta( 'lbt_meta_ebook_membership' ) == $from_value){
 update_post_meta( get_the_id(), 'lbt_meta_ebook_membership', $to_value );
  }
  
  endwhile;
}
wp_reset_query();

Open in new window


Please help.
Thank you.
Avatar of Ryan Chong
Ryan Chong
Flag of Singapore image

a quick fix will be compare the value of get_the_id() in the while loop, like:

$from_value = 'premium';
$to_value = 'any';

$from_post_id = 10;
$to_post_id = 20;
$post_id = 0;

$type = 'ebooks';
$args = array(
  'post_type' => $type,
  'post_status' => array('publish', 'pending', 'draft', 'auto-draft', 'future', 'private', 'inherit', 'trash'),
  'posts_per_page' => -1,
  'ignore_sticky_posts'=> 1
 );
$lbt_query = null;
$lbt_query = new WP_Query($args);
if( $lbt_query->have_posts() ) {
  while ($lbt_query->have_posts()) : $lbt_query->the_post();
  
$post_id = get_the_id();
  if((lbt_get_meta( 'lbt_meta_ebook_membership' ) == $from_value) && ($post_id >= $from_post_id) && ($post_id <= $to_post_id))  {
 update_post_meta( $post_id, 'lbt_meta_ebook_membership', $to_value );
  }
  
  endwhile;
}
wp_reset_query();

Open in new window

A few minor modifications to Ryan's code you might consider.

1) Pull a list of all $post_ids, where $post_id > 10 with LIMIT == 10.

2) Then loop through returned $post_id list.

This ensures your code will work independent of various WordPress operations like deleting/renaming pages + posts.
Avatar of Lazaro ORTEGA
Lazaro ORTEGA

ASKER

Thank you Ryan and David!

I have tried Ryan code and I am still getting:

Fatal error: Out of memory (allocated 1568145408) (tried to allocate 16777216 bytes) in /home/usern/public_html/wp-includes/wp-db.php on line 2510

This Query is consuming all my server memory when I try to update just 2 records. My database has 100.000 posts and this is the problem.

I have set temporary no memory_limit ( in php.ini and in WP define('WP_MEMORY_LIMIT', '-1');  ) and I am still running out of memory.

Why is this query so memory consuming even I I try to update just 2 posts:

$from_post_id = 316;
$to_post_id = 318;
$post_id = 0;

Any way to improve this?

Thank you so much for your great help.
For the args to WP_Query, you can pass in an array of the IDs you want back, so rather than your query pulling in 100,000 records and then looping through them, you would only retreive the ones you want. If you pull in 100,00 records, and then try to examine the meta for each record, that would perform an additional 100,000 individual queries on your DB - probably explains the memory issue :) You could have reduced this impact by changing the order of your if statements:

if ($post_id >= $from_post_id && $post_id <= $to_post_id && lbt_get_meta( 'lbt_meta_ebook_membership' ) == $from_value &&  )  {

That would then only query the meta if the ID was between the 2 values, rather than query the meta and then checking the IDs.
 
Take a look at this approach by passing in the IDs that you want:

$from_value = 'premium';
$to_value = 'any';

$from_post_id = 10;
$to_post_id = 20;

for ($i = $from_post_id; $i <= $to_post_id ; $i++) $ids[] = $i;

$args = array(
    'post_type' => 'ebooks',
    'post_status' => 'any',
    'posts_per_page' => -1,
    'ignore_sticky_posts' => 1,
    'post__in' => $ids,
);

$lbt_query = new WP_Query($args);

if ( $lbt_query->have_posts() ):

    while ($lbt_query->have_posts()) :
        $lbt_query->the_post();
        $post_id = get_the_id();

        if ( lbt_get_meta( 'lbt_meta_ebook_membership' ) == $from_value ) {
            update_post_meta( $post_id, 'lbt_meta_ebook_membership', $to_value );
        }
    endwhile;

endif;

Open in new window

Thank you Chris for your help!

Yes, this is exact what I want! I tried your code and I am getting: "Fatal error: Call to undefined function lbt_get_meta()"

when lbt_get_meta() is already declared, I do not get this error with the original code where I call that function too, it happens only when I call it from inside your loop. Why this?

Thank you so much!
Hey Lazaro,

I can't see anything in my code that would break the call to lbt_get_meta(). Effectively, the loop is exactly the same as what you originally had. The only fundmental difference is the args we now pass into WP_Query.

Are you sure you haven't made any other changes along the way.
This question needs an answer!
Become an EE member today
7 DAY FREE TRIAL
Members can start a 7-Day Free trial then enjoy unlimited access to the platform.
View membership options
or
Learn why we charge membership fees
We get it - no one likes a content blocker. Take one extra minute and find out why we block content.