Set up cron
Some of what a classifieds site does cannot happen inside a page request. E-mail alerts have to go out, premium listings have to expire, spam and unactivated accounts have to be cleaned up, and the XML sitemap has to be regenerated. ShopClass runs all of that on a schedule.
Without a working cron, none of it happens. That is the single most common cause of “my alerts never send” and “expired listings are still showing”.
The recommended setup
Section titled “The recommended setup”Add one crontab entry on the server and let ShopClass decide what is due:
*/5 * * * * php /path/to/site/oc-cli.php cron >/dev/null 2>&1That is the whole configuration. The command checks the hourly, daily and weekly tiers each time it runs and executes only what is actually due, so running it every five minutes costs nothing and keeps alerts prompt.
Then turn the fallback off, so work is not attempted twice:
Admin → Settings → General → uncheck Auto-cron.
Adding the crontab entry
Section titled “Adding the crontab entry”Over SSH:
crontab -eAdd the line, save, and confirm it registered:
crontab -lYou need the CLI PHP binary, not the web server’s module. If plain php is
not on the path, ask your host for the full path — it is often something like
/usr/local/bin/php or /opt/alt/php82/usr/bin/php.
If you prefer separate tiers
Section titled “If you prefer separate tiers”The older, explicit form works too, and is what long-running installs already have:
0 * * * * php /path/to/site/oc-cli.php cron --type=hourly0 3 * * * php /path/to/site/oc-cli.php cron --type=daily0 4 * * 0 php /path/to/site/oc-cli.php cron --type=weeklyWhen you have no shell access
Section titled “When you have no shell access”Many shared hosts do not offer SSH but do offer a cron wizard in the control panel (cPanel: Advanced → Cron Jobs; Plesk: Scheduled Tasks). Point it at the same command.
If the panel only allows fetching a URL rather than running a command, use the web entry point instead:
wget -qO /dev/null https://example.com/index.php?page=cronSet it to run hourly. This is weaker than the CLI — it runs inside a web request and inherits the web server’s timeout — but it is far better than nothing.
The built-in fallback
Section titled “The built-in fallback”If you cannot schedule anything at all, ShopClass can piggyback on visitor traffic instead:
Admin → Settings → General → check Auto-cron.
Due tasks are then triggered by ordinary page views, at most once every five
minutes. Nobody waits for them: on PHP-FPM the page is sent first and the work
runs afterwards in the same process. On other setups ShopClass falls back to
asking itself for ?page=cron over HTTP, which an origin behind a proxy cannot
do — it resolves its own public address to the proxy and never reaches itself,
so nothing runs and nothing says so. If that is your setup, use a real crontab.
The real cost that remains either way: nothing runs while the site has no visitors.
Use it to get started, then move to a real crontab.
Checking that it works
Section titled “Checking that it works”php oc-cli.php doctorAmong its checks, doctor reports cron freshness — how long since the
scheduled tasks last completed. If that number keeps growing, your crontab is
not running the command you think it is.
Run it manually once to see the output rather than the silence a crontab gives you:
php /path/to/site/oc-cli.php cron --type=hourlyWhat runs when
Section titled “What runs when”| Tier | Work |
|---|---|
| Hourly | E-mail alerts, expiring premium listings |
| Daily | Cleanup of expired, spam, blocked and unactivated content; alerts |
| Weekly | Longer-running maintenance |
Plugins add their own work to these tiers through the cron_hourly,
cron_daily and cron_weekly hooks.
Remote storage needs its own entry
Section titled “Remote storage needs its own entry”If listings are offloaded to remote storage, the queue that moves uploaded images is drained from the hourly tier — which on a busy site is not often enough, and the hourly tier does too much else to be run every few minutes. Give it a second entry of its own:
* * * * * php /path/to/site/oc-cli.php storage:work --max-seconds=50 >/dev/null 2>&1This runs the queue worker and nothing else, so a tight schedule is safe. On a site with no remote storage it does nothing and exits cleanly, so it is harmless to add before you need it. See the CLI reference.