Skip to the content
Documentation
Help Start
Reading in:
  • German: 9,059 of 9,059 pages
About the help in other languages
All help pages

RSS import cleanup

Read this page if your site imports RSS feeds, or if you used the bccleanuprss extension. An RSS import adds an object for every item in the feed and never takes one away. A site importing a busy feed therefore grows…

Download as PDF

Address: https://doc.exponential.earth/exphelp/viewer/bc/6.0/cleanuprss.md

On this page

RSS import cleanup

Read this page if your site imports RSS feeds, or if you used the bccleanuprss extension. An RSS import adds an object for every item in the feed and never takes one away. A site importing a busy feed therefore grows without limit: the destination folder reaches tens of thousands of children, the administration interface slows down on it, the search index fills with items nobody will read again, and the nightly backup carries all of it. Since 6.0.15 the kernel can trim that for you: keep the newest N items of each active RSS import; remove the rest.

The code is ported from the bccleanuprss extension by Brookins Consulting (https://github.com/se7enxweb/bccleanuprss), GPL v2 or later. The original's selection method is kept; see What was kept, and what changed.

In short

What changedNew command bin/php/cleanuprss.php (./console exp:cleanuprss --apply), cronjob part cleanuprss, class expCleanupRSS, settings content.ini [RSSImportCleanupSettings].
Who is affectedNobody until you enable it. Users of the bccleanuprss extension: its settings file bccleanuprss.ini is not read.
How to checkphp bin/php/cleanuprss.php --dry-run --allow-root-user prints what it would remove, or why it removes nothing.
How to switch onSet Enabled, ClassIdentifiers[] and KeepPerFeed, dry-run, then schedule the cronjob part.

Set it up in five minutes

  1. Add to settings/override/content.ini.append.php:

    [RSSImportCleanupSettings]
    Enabled=true
    KeepPerFeed=200
    ClassIdentifiers[]
    ClassIdentifiers[]=article
    MoveToTrash=true
  2. Clear the INI cache: php bin/php/ezcache.php --clear-tag=ini --allow-root-user

  3. Dry-run and read the list: php bin/php/cleanuprss.php --dry-run --allow-root-user

  4. Run it: php bin/php/cleanuprss.php --apply --allow-root-user

  5. Schedule it nightly: php runcronjobs.php cleanuprss in your crontab.

It does nothing until you tell it what to remove

This removes content. Three separate conditions must hold before it will touch anything, and none of them holds on an installation that has not been set up for it:

  1. Enabled=true
  2. ClassIdentifiers[] names at least one class
  3. KeepPerFeed is at least 1

Any one of them unmet and the run stops and says which:

$ php bin/php/cleanuprss.php
Nothing was removed: RSSImportCleanupSettings/Enabled is not true in content.ini.

That is not an error — an installation that has not asked for this is the normal case. Both the script and the cronjob exit cleanly, so the part can be scheduled before it is configured.

Settings

settings/content.ini, beside the import's own settings. Override per siteaccess like anything else.

[RSSImportCleanupSettings]
Enabled=false
KeepPerFeed=100
ClassIdentifiers[]
CleanupUser=admin
LogFile=rsscleanup.log
MoveToTrash=true
SettingMeaning
EnabledOff until the site says otherwise.
KeepPerFeedHow many items to keep per feed, newest first. At least 1.
ClassIdentifiers[]The classes that may be removed. Nothing outside this list is touched however old it is — a folder or a page that happens to sit in the destination is safe. Empty means nothing is removed.
CleanupUserRemoving is permission checked, so the run becomes this user. A missing account stops the run with a message.
LogFileWhere the run is recorded, under var/<var dir>/log/. Empty writes no file.
MoveToTrashWhether removed items go to the trash, where they can be recovered, or are deleted outright.

A working configuration:

[RSSImportCleanupSettings]
Enabled=true
KeepPerFeed=200
ClassIdentifiers[]
ClassIdentifiers[]=article
MoveToTrash=true

About MoveToTrash

true is the default because an automated, scheduled, permanent deletion of content with no way back is not a reasonable default. Note that the trash then grows instead — pair it with the trashpurge.php cronjob, or set it to false once you trust the class list.

Running it

By hand

php bin/php/cleanuprss.php --dry-run --allow-root-user
php bin/php/cleanuprss.php --apply --allow-root-user
php bin/php/cleanuprss.php --apply --keep=50 --allow-root-user
php bin/php/cleanuprss.php --apply -s my_siteaccess --allow-root-user
./console exp:cleanuprss --dry-run --allow-root-user     # the same script through the console

(--allow-root-user only when you run as root. The dry run was run on this installation and, with the shipped Enabled=false, printed the "Nothing was removed" line shown above.)

Option
--dry-runList what would be removed, and remove nothing.
--keep=NKeep this many per feed instead of the configured number. Does not lift the other two conditions.

Plus the ordinary script options (-s, -q, -d, --help).

Always dry-run first on a site you have not run this on before. It prints every item it would remove, by name and node id.

As a cronjob

php runcronjobs.php cleanuprss
./console cron:cleanuprss        # the same part through the console

The part is declared in settings/cronjob.ini:

[CronjobPart-cleanuprss]
Scripts[]=cleanuprss.php

It is a named part rather than one of the default Scripts[], so it runs only when asked for. Nightly is usually right — it is the import that needs throttling, not the clock.

What it actually does

For each active import (eZRSSImport::fetchActiveList()):

  1. Take the import's destination_node_id. Skip the feed if it has none, or if the node is gone — that is reported, not fatal.
  2. Ask for that node's children, of the configured classes, published status, depth 1, sorted newest first and offset by KeepPerFeed.
  3. Whatever comes back is by definition the surplus; remove it in one call.

Step 2 is the whole trick, and it is the original's. Because the keep count is the query's offset, there is no second pass deciding what to drop and no window in which the newest items could be returned — the items to keep are skipped by the database.

Depth => 1 means only direct children. An item's own children go with it when it is removed, but a sub-folder of the destination is not searched.

From a template or PHP

$cleanup = new expCleanupRSS( array( 'dry-run' => true ) );

if ( $cleanup->isEnabled() )
{
    $cleanup->cleanup();
    $counts = $cleanup->counts();   // feeds, examined, removed
    $perFeed = $cleanup->perFeed(); // name, node, surplus
}
else
{
    echo $cleanup->reason();
}

Constructor options: dry-run, keep, quiet.

What was kept, and what changed

The selection method — newest-first sorted, offset by the keep count — is the original's and is why this port exists rather than a rewrite.

Everything around it changed, and most of the changes were not cosmetic:

WasNow
Constructorpublic function BCCleanupRSS(), a PHP 4 constructor__construct()
Default class listRSSClasses[]=16, RSSClasses[]=1 — numeric ids, which on a stock installation are article and folderempty, and identifiers rather than ids
Enabled by defaultyesno
RemovalremoveSubtrees( ..., false ) — permanent, not configurableMoveToTrash, defaulting to the trash
Dry runnone--dry-run
Missing cleanup userfatal error on the next linestops the run and says so
Removal callsone removeSubtrees() per item, each clearing caches and reindexingone call per feed
Terminal outputglobal $cli, set only if the caller made oneeZCLI::instance()
Settingsbccleanuprss.inicontent.ini [RSSImportCleanupSettings], next to [RSSImportSettings]

The PHP 4 constructor is worth spelling out: PHP 8 removed them, so new BCCleanupRSS() no longer ran that method. Every property it set — rssLimit, rssClasses, logFile — stayed undefined, and the class could not work at all on any supported PHP version.

The default class list is worth spelling out too. RSSClasses[]=1 is folder on a stock installation. Enabled by default, against a destination containing folders, that removes folders.

Naming

bc-prefixed names are gone, as this is no longer a vendor extension: BCCleanupRSS → expCleanupRSS, bccleanuprss.ini → a block in content.ini. Brookins Consulting's copyright lines are kept in every ported file — the branding goes, the attribution does not.

Files

File
kernel/classes/expcleanuprss.phpexpCleanupRSS
bin/php/cleanuprss.phpthe command line script
cronjobs/cleanuprss.phpthe cronjob part
settings/content.ini[RSSImportCleanupSettings]
settings/cronjob.ini[CronjobPart-cleanuprss]
autoload/ezp_kernel.phpthe class map entry

Tests

A private functional script builds its own fixture (a folder, an active eZRSSImport pointing at it, twelve articles published an hour apart and one folder that must survive because its class is not on the list) and checks that each of the three conditions refuses on its own, that a dry run finds the surplus and removes nothing, that a real run leaves exactly the newest five, that the unlisted class is untouched, that a second run finds nothing, and that what was removed is recoverable from the trash. It is not shipped. To check the behaviour yourself, follow "Running it" with --dry-run first on a copy of the installation.

Something wrong on this page? Report an error

Documentation license

This documentation is free documentation, licensed under the GNU Free Documentation License 1.3 or later.

Exponential Copyright © 1998-2026 Exponential Foundation and 7x