Why doesn't this work?

Probably should be:

AND node_id IN (?)

Make sure $sourceForum is always an array, even if it only contains a single node_id.

Right, but once I change it to node_id IN, I get the error all the time. I checked the options line in the db, it's a simple serialized array. Tried adding an unserialize() to the script, just in case... but that threw an error.

I have found some mention out on the internets with people having problems with IN (?) vs IN ('?'), but I tried it every way I can think of, but still can't get it to work. Here's the whole script as it sits right now. Maybe somebody can spot the problem. My next course of action was to write a page that would just print all the variables, but I haven't been able to find the time.

PHP:
public static function runMoveDeletedThreads()
    {
    $options = XenForo_Application::get('options');
    if ($options->xefDeletedThread === '1')
    {
        if (empty($options->xefModeratedForums[0]))
        {
            return;
        }
        else
        {
            $sourceNodes = array($options->xefModeratedForums);
        }
 
        $db = XenForo_Application::getDb();
 
        $threads = $db->fetchAll("
            SELECT *
            FROM xf_thread
            WHERE discussion_state = 'deleted'
            AND node_id IN ( ? )
            ", $sourceNodes);
 
        if ($threads)
        {
            foreach ($threads AS $thread)
            {
                $dw = XenForo_DataWriter::create('XenForo_DataWriter_Discussion_Thread');
                $dw->setExistingData($thread);
                $dw->set('node_id', $options->xefRecycleForum);
                $dw->save();
            }
        }
    }
}

And this is what the xefModeratedForums options field looks like in the DB, first with several options, then with only one:

PHP:
a:8:{i:0;s:2:"70";i:1;s:2:"73";i:2;s:2:"67";i:3;s:2:"68";i:4;s:2:"74";i:5;s:2:"69";i:6;s:2:"71";i:7;s:2:"72";}
 
a:1:{i:0;s:2:"70";}
 
Try:
PHP:
$threads = $db->fetchRow('
                SELECT *
                FROM xf_thread
                WHERE discussion_state = \'deleted\'
                AND node_id IN (' . $db->quote($sourceNodes) . ')
          ');
 
Try:
PHP:
$threads = $db->fetchRow('
                SELECT *
                FROM xf_thread
                WHERE discussion_state = \'deleted\'
                AND node_id IN (' . $db->quote($sourceNodes) . ')
          ');

Closer, maybe?

Now getting a "A discussion insert was attempted without the required first message." error for the line with "$dw->save();" on it.

A discussion insert was attempted without the required first message.
  1. XenForo_DataWriter_Discussion->_preSave() in XenForo/DataWriter.php at line 1422
  2. XenForo_DataWriter->preSave() in XenForo/DataWriter.php at line 1361
  3. XenForo_DataWriter->save() in MoveThreadCron/CronEntry.php at line 82
  4. MoveThreadCron_CronEntry::runMoveDeletedThreads()
  5. call_user_func() in XenForo/Model/Cron.php at line 356
  6. XenForo_Model_Cron->runEntry() in XenForo/ControllerAdmin/Cron.php at line 204
  7. XenForo_ControllerAdmin_Cron->actionRun() in XenForo/FrontController.php at line 310
  8. XenForo_FrontController->dispatch() in XenForo/FrontController.php at line 132
  9. XenForo_FrontController->run() in /websites/xen.nc/xf11/admin.php at line 13
 
That's because in the example I gave you I used fetchRow instead of fetchAll :oops:
Also all you need to fetch is the thread_id
PHP:
$threads = $db->fetchAll('
                SELECT thread_id
                FROM xf_thread
                WHERE discussion_state = \'deleted\'
                AND node_id IN (' . $db->quote($sourceNodes) . ')
          ');
 
Winner winner, chicken dinner!

That works. So, a quick summary for the search engines: I plugged that script into a cron entry, and it automatically moves soft deleted threads to a separate "recycle bin" forum. It works perfectly for a classified ads forum where there's a lot of churn. I can have this run nightly (or even hourly) and keep the forum tidy for the moderators.

Thanks everybody!
 
Top Bottom