0

I need to disable all the entries of 3 (related) sections. After that I'll be running some imports and all actual data will be enabled again (within the correct sites). We're talking about around 2.000 entries per section.

In the admin/control panel I can only select all entries on the current page (per 100) and disable them. There's no option to disable all these entries. So through this method I should repeat this 20 times for each of the 3 sections...

Is there any other way to achieve this? Via the command line, through code or through an SQL query directly onto the database?

2 Answers 2

3

If you need to do this on-demand, you could add a console controller to a custom module so that you can run it via command.

This page in the Craft docs explains how to set that up: https://craftcms.com/docs/4.x/extend/commands.html

For your controller method, you'd want to loop through the entries you want (using a Entry::find()->section('section1,section2,...')->all() query) and for each entry do the following:

$entry->enabled = false;
$success = Craft::$app->elements->saveElement($entry);
if (!$success) {
   // Edit this fail condition as desired, such as outputting info without quitting.
   Craft::error('Couldn’t save the entry "'.$entry->title.'"', __METHOD__);
}

Run your custom CLI command in the console, and it'll disable each entry. If you have a TON of entries, you'll want the controller to instead call a queue job to prevent time-out.

Here's info on queue jobs: https://craftcms.com/docs/4.x/extend/queue-jobs.html

2
  • 1
    This is great! Hadn't thought about reusability. I'm going to need this a few more times probably, so I went with this. Great suggestion to use a job. Works like a charm!
    – 7ochem
    Commented Mar 7, 2023 at 9:45
  • Happy to help! Glad it went smoothly :)
    – cherrykoda
    Commented Mar 8, 2023 at 0:32
1

A content migration is probably the best approach to take. This way, any other modules/plugins that listen to entry events will be able to take the necessary action, and you can run and test it in development before deploying to production.

Here is the migration in its entirety. It should be straightforward enough to read, just be sure to swap out the site and section IDs.

<?php

namespace craft\contentmigrations;

use Craft;
use craft\db\Migration;
use craft\elements\Entry;

class m230306_120000_disable_entries extends Migration
{
    public function safeUp(): bool
    {
        $entries = Entry::find()
            ->siteId([1, 2])
            ->sectionId([1, 2, 3])
            ->all();
        
        foreach ($entries as $entry) {
            // Set to `false` to disable, `true` to enable.
            $entry->enabled = false;
            Craft::$app->elements->saveElement($entry);
        }

        return true;
    }

    public function safeDown(): bool
    {
        return false;
    }
}
2
  • I have two sites. With $entry->enabled = false; does it disable for both/all sites? (= desired behaviour)
    – 7ochem
    Commented Mar 7, 2023 at 8:45
  • No, I added a site ID query param to my answer, which allows you to specify the sites to fetch entries from.
    – Ben Croker
    Commented Mar 7, 2023 at 14:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.