Batch remove tags

Biarritz64

Active member
I found this script by @Xon to remove tags
when run it will delete all tags with less than 10 uses
can someone make it compatible with xf2

Code:
<?php
exit();

$startTime = microtime(true);

@set_time_limit(0);
ignore_user_abort(true);
$fileDir = dirname(__FILE__);

require($fileDir . '/library/XenForo/Autoloader.php');
XenForo_Autoloader::getInstance()->setupAutoloader($fileDir . '/library');

XenForo_Application::initialize($fileDir . '/library', $fileDir);
XenForo_Application::set('page_start_time', $startTime);

$dependencies = new XenForo_Dependencies_Public();
$dependencies->preLoadData();

$db = XenForo_Application::get('db');

$tags = $db->fetchAll("
select *
from xf_tag
where xf_tag.use_count < 10;
");

print count($tags) . " about to delete in 2 seconds\n";
sleep(2);
print "Now deleting\n";

foreach($tags as $tag)
{
    $dw = XenForo_DataWriter::create('XenForo_DataWriter_Tag');
    $dw->setExistingData($tag);
    $dw->delete();
}

$threads = $db->fetchAll("
    SELECT thread_id
    FROM xf_thread
    WHERE xf_thread.tags <> 'a:0:{}' and xf_thread.tags <> ''
");

/** @var XenForo_Model_Tag $tagModel */
$tagModel = XenForo_Model::create('XenForo_Model_Tag');

foreach ($threads AS $thread)
{
XenForo_Db::beginTransaction($db);
    $tagModel->rebuildTagCache('thread', $thread['thread_id']);
XenForo_Db::commit($db);
}
 
Surprised there's no follow up to this. A little tag clean-up when importing from other forum software should be included in the importer. Or, at the very least, post a quick and dirty little script for Xenforo 2.x to accomplish it.

Like others have said, I don't want to spend $ for something I'm only using once after importing.
 
Looking for something like this too. Removing from only the xf_tag table will only result in a lot of error pages as it doesn't strip from the thread data.
 
I found this script by @Xon to remove tags
when run it will delete all tags with less than 10 uses
can someone make it compatible with xf2
I'd also appreciate it if someone could share an update of the OP code that makes it xF2 compatible.
 
I completely forgot about this. I've got an XF2 copy of this script which has been sitting around since 2018 or so.

Utterly no checking that this still works, or doesn't bomb out. Run it against a test instance first!
PHP:
<?php

ignore_user_abort(true);

$dir = __DIR__;
require($dir . '/src/XF.php');

XF::start($dir);
$app = XF::setupApp('XF\Pub\App');

if (\XF::$versionId != $app->options()->currentVersionId)
{
    echo "XF upgrade is pending\n";
    return;
}

print "loading tags:\n ";

$tags = \XF::finder('XF:Tag')->where('use_count', '<', 10)->fetch();

if ($tags->count())
{
    print $tags->count() . " tags in about to delete in 10 seconds\n";
    sleep(10);
    print "Now deleting\n";

    foreach($tags as $tag)
    {
        $tag->delete();
    }
}

print "Running delete jobs\n";

$jobManager = $app->jobManager();
$maxJobRunTime = intval($app->config('jobMaxRunTime'));

do
{
    $jobManager->runQueue(false, $maxJobRunTime);
    $more = $jobManager->queuePending(false);
   
    \XF::triggerRunOnce();
    \XF::app()->em()->clearEntityCache();
    print ".";

} while ($more);
print "\nDone!\n";
 
Last edited:
Utterly no checking that this still works, or doesn't bomb out. Run it against a test instance first!
Thanks! (y)

I modified the criteria slightly to a) not include permanent tags, and b) usage count of 5 or less, and c) not include tags last used within the last 60 days ...

Code:
$tags = \XF::finder('XF:Tag')->where('permanent', 0)->where('use_count', '<=', 5)->where('last_use_date', '<=', time() - (86400*60))->fetch();
 
Last edited:
I completely forgot about this. I've got an XF2 copy of this script which has been sitting around since 2018 or so.

Utterly no checking that this still works, or doesn't bomb out. Run it against a test instance first!
I just tried that on my test forum which da 46 pages of tags (50 per page). After running OI still had 1 page 50. So it sort of works but not quite

EDIT:

It appears to be fine, I just noticed:

Code:
$tags = \XF::finder('XF:Tag')->where('use_count', '<', 10)->fetch();
 
I just tried that on my test forum which da 46 pages of tags (50 per page). After running OI still had 1 page 50. So it sort of works but not quite

EDIT:

It appears to be fine, I just noticed:

Code:
$tags = \XF::finder('XF:Tag')->where('use_count', '<', 10)->fetch();
What do you mean? I mean I don't understand the fix
 
I think he means that the code is designed to delete tags used less than 10 times. so the code basically worked as intended and some tags were left behind. so if you want to delete all tags, you would need to replace 10 with 1 perhaps.

$tags = \XF::finder('XF:Tag')->where('use_count', '<', 1)->fetch();
 
Top Bottom