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
Register the bundle in config/bundles.php:
Mmd\SyliusAltchaPlugin\MmdSyliusAltchaPlugin::class => ['all' => true],
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"
Run the setup command and publish the widget assets:
bin/console mmd:altcha:setup
bin/console assets:install
mmd:altcha:setupruns only this plugin's own migrations, never those of your app or other plugins, and is idempotent: running it again after acomposer updatedoes nothing when there is no new migration. It stops and tells you to rundoctrine:migrations:migratefirst 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 intoconfig/itself). Plaindoctrine:migrations:migratestill 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.
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.
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.
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 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 rate-limit hits and gibberish-log entries
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.
Order matters - the migrations are only known to Doctrine while the bundle is still registered:
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.
With the bundle still registered, roll the six migrations back, newest first:
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'
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 sixMmd\SyliusAltchaPlugin\Migrations\...rows fromdoctrine_migration_versionsyourself.