Skip to main content

Registries

Every extensible subsystem in Downloads Manager ships as a registry-and-adapter pair. Each registry holds a small interface, one or more built-in adapters, and a code event that lets third parties register their own. The shape matches MC\Quests.

Registries are bound on the container in Listener::appSetup(). The closure is lazy: the built-in adapters are registered and the *_handlers event is fired the first time the registry is resolved, not at boot.

$app->container()->set('mc_dm.{registry}_registry', function () {
$registry = new {Registry}Registry();
self::registerBuiltIn{Registry}($registry);
\XF::fire('mc_dm_{registry}_handlers', [$registry]);
return $registry;
});

The four registries

#RegistryContainer keyEventBuilt-insThird-party expected
1Gatemc_dm.gate_registrymc_dm_gate_handlersPermission, Criteria, Password, Hotlink, Captcha, RateLimit, Bandwidthvirus-scan gate, NSFW gate (ships as separate add-on)
2Processormc_dm.processor_registrymc_dm_processor_handlershash, size, mime, magic-byte, decompression-bombvirus scan
3Sourcemc_dm.source_registrymc_dm_source_handlersDirectUrl, GitHubRelease, S3, MagnetIPFS, GitLab/Gitea releases, tracker-only sources
4Statsmc_dm.stats_registrymc_dm_stats_handlersBuiltInAggregatorPlausible, Matomo

Why only four

Fields, search, notifications, and storage use the existing core extension points instead of an add-on registry:

  • Fields use the native \XF\CustomField\Definition system (8 native types plus the match_type column).
  • Search uses the native Source interface. This is the same swap point Enhanced Search uses for Elasticsearch.
  • Notifications use XF\Notifier\AbstractNotifier subclasses, the same pattern the Resource Manager uses.
  • Storage uses the Flysystem MountManager directly via internal-data://mc-downloads/.... Admins reroute this add-on (and every other add-on) by editing config.php.

Adding a registry on top of any of these would just duplicate the existing swap points.

Building an adapter

Every registry exposes the same shape: a register($id, $adapter) method and a get($id) method. To add an adapter:

  1. Implement the registry's interface (e.g. MC\DownloadsManager\Gate\Gate).
  2. Subscribe to the registry's event in your add-on's code_event_listeners.xml.
  3. Call $registry->register('your_id', new YourAdapter()) from the listener.

See each registry page for the interface contract and concrete examples.