You can do this without writing any code using WP CLI by chaining 2 commands together:
- the command to retrieve all posts from April 2017 or earlier
- the command to update all posts and set the post_status set to
draft
Retrieving All the Posts Before April 2017
We can use wp post list
to do this, and we will need them as post IDs to pass to the next command. More details on this command here.
For example we can fetch all posts from 2017 like this:
wp post list --year="2017" --format=ids
And all posts from April like this:
wp post list --year="2017" --month="4" --format=ids
This way we can run this command for each month of 2017, and each year before that, and pass the result into the next command
Setting A Post to Draft
We can do this with wp post update 123
where 123 is the ID of the post to change
wp post update 123 --post_status="draft"
Bringing the Two together
So lets set all posts in 2016 to draft:
wp post update $(wp post list --year="2016" --format=ids) --post_status="draft"
And 2015:
wp post update $(wp post list --year="2015" --format=ids) --post_status="draft"
And 2014:
wp post update $(wp post list --year="2014" --format=ids) --post_status="draft"
etc
General Notes
- You will want to do this via WP CLI, doing it on every
admin_init
hook will slow things down, and if it can’t finish what it’s doing before the time limit is reached, your site will never load WP Admin - Queries that ask for everything are bad for your site, and can cripple your database, or trigger out of memory warnings. Always fetch posts in batches of 100 or less. You can always run a second and a third query, just don’t fetch them all at once
- Never, ever, modify files in
wp-includes
orwp-admin
. All your changes will be overwritten when WP updates. It’s a recipe for disaster. In 2012 a site got hacked releasing customer data and earning the company a multi-million $$ fine because they’d modified WP Core instead of using themes and plugins, then couldn’t update it to get new security fixes and thought it was no big deal - Use
WP_Query
instead ofget_posts
, it uses cache by default and it’s closer to a real post loop - Indent properly, and get an editor that will indent for you, it will solve an entire class of bugs and mistakes
- You asked an XY question, where you came up with a solution to a problem, didn’t know how to implement it, and asked how to implement the solution. You should have asked how to solve the problem, if you had, a whole list of possible answers could have been posted which can’t now. E.g. using
pre_get_posts
to hide posts before April 2017 ( it solves your problem but it’s not what you asked for )