Markus Michalski FAQ

ALTCHA: Installation and Operations

ALTCHA spam protection for Sylius - installation via Composer (Packeton), update, cron jobs for purge and disposable-domain list, uninstall in the correct order

Deutsche Version

Back to overview

ALTCHA: Installation and Operations

Live Demo: Try this and other plugins live — no installation, no risk: demo.markus-michalski.net

Installation

Private repository, distributed through Packeton (https://packeton.markus-michalski.net). Access credentials are provided after license purchase/approval.

{ "repositories": [{ "type": "composer", "url": "https://packeton.markus-michalski.net" }] }
composer require mmd/sylius-altcha-plugin
  1. Register the bundle in config/bundles.php:

    Mmd\SyliusAltchaPlugin\MmdSyliusAltchaPlugin::class => ['all' => true],
    
  2. Import the routes, for example in config/routes/mmd_sylius_altcha.yaml:

    mmd_sylius_altcha_admin:
        resource: "@MmdSyliusAltchaPlugin/config/routes/admin.yaml"
    
    mmd_sylius_altcha_shop:
        resource: "@MmdSyliusAltchaPlugin/config/routes/shop.yaml"
    
  3. Run the setup command and publish the widget assets:

    bin/console mmd:altcha:setup
    bin/console assets:install
    

    mmd:altcha:setup runs only this plugin's own migrations, never those of your app or other plugins, and is idempotent: running it again after a composer update does nothing when there is no new migration. It stops and tells you to run doctrine:migrations:migrate first if Sylius' own migrations are still open, and it checks that the routes from step 2 are imported, printing the snippet if not (it never writes into config/ itself). Plain doctrine:migrations:migrate still works as a fallback. Run it as the same user as your other console commands; in scripts add --no-interaction.

    The widget scripts are always served from <base path>/bundles/mmdsyliusaltchaplugin/, never through Symfony asset packages or Sylius themes - assets:install is enough, sylius:theme:assets:install is not required, and a CDN base_urls/version_strategy setting does not apply to them. With a CSP, allow 'self' in script-src.

  4. Set up the cron jobs (see Cron Jobs): the plugin stores short-lived rows for replay protection and rate limiting that nothing else deletes.

Nothing is protected until you enable a channel in the admin (see Configuration). The storefront hooks and admin grids register themselves automatically; nothing else needs to be imported.

Update

composer update mmd/sylius-altcha-plugin
bin/console mmd:altcha:setup --no-interaction
bin/console cache:clear

Running the setup command again after every update is always safe: without a new migration it does nothing.

Cron Jobs

The plugin stores short-lived rows for replay protection and rate limiting. Nothing but the purge cron job deletes them, so it is part of the basic installation.

Command Recommended interval Description
bin/console mmd:altcha:purge daily Removes expired replay-protection rows (already used challenges), expired rate-limit hits (--rate-limit-retention, default 48h) and gibberish-log entries older than 30 days (--gibberish-log-retention)
bin/console mmd:altcha:update-disposable-domains weekly Refreshes the disposable-mail snapshot from the upstream list; only needed if that check is enabled. Fails closed - a network error or empty response keeps the previous file in place.

Example crontab for the user that also runs your other console commands (adjust the path):

# daily at 03:15: delete expired replay, rate-limit and gibberish-log rows
15 3 * * * cd /var/www/shop && bin/console mmd:altcha:purge --no-interaction

# Sundays at 03:30: refresh the disposable-domain list (only with the disposable-mail check enabled)
30 3 * * 0 cd /var/www/shop && bin/console mmd:altcha:update-disposable-domains --no-interaction

--rate-limit-retention=<seconds> must exceed the longest rate-limit window you configure (at most 24 hours), otherwise hits are deleted that still need to be counted.

The setup command (mmd:altcha:setup) is not a cron job - it is a one-off, idempotent install/update step.

Uninstall

Order matters - the migrations are only known to Doctrine while the bundle is still registered:

  1. Remove every mmd_altcha_widget() call and mmd_altcha.widget* hook from your templates, and the cron jobs for mmd:altcha:purge and mmd:altcha:update-disposable-domains.

  2. With the bundle still registered, roll the seven migrations back, newest first:

    bin/console doctrine:migrations:execute --down 'Mmd\SyliusAltchaPlugin\Migrations\Version20261007090000'
    bin/console doctrine:migrations:execute --down 'Mmd\SyliusAltchaPlugin\Migrations\Version20261003090000'
    bin/console doctrine:migrations:execute --down 'Mmd\SyliusAltchaPlugin\Migrations\Version20261002090000'
    bin/console doctrine:migrations:execute --down 'Mmd\SyliusAltchaPlugin\Migrations\Version20261001090000'
    bin/console doctrine:migrations:execute --down 'Mmd\SyliusAltchaPlugin\Migrations\Version20260930140000'
    bin/console doctrine:migrations:execute --down 'Mmd\SyliusAltchaPlugin\Migrations\Version20260930120000'
    bin/console doctrine:migrations:execute --down 'Mmd\SyliusAltchaPlugin\Migrations\Version20260930100000'
    
  3. Remove the route imports and the bundle entry from config/bundles.php, then composer remove mmd/sylius-altcha-plugin.

Dropping the six mmd_sylius_altcha_* tables by hand instead of rolling back is possible, but then also delete the matching seven Mmd\SyliusAltchaPlugin\Migrations\... rows from doctrine_migration_versions yourself.