Skip to content



Scan extensions for classes. This allows auto-registration based on code-conventions, interfaces, annotations.


Most CiviCRM extensions do not need to implement hook_civicrm_scanClasses directly. They can use the standard mixin scan-classes@1 which scans all classes in the ./CRM and ./Civi folders.

There are a few atypical cases where you may need to implement this hook:

  • Enable scanning of a CMS add-on (Drupal module, WordPress plugin, Joomla extension)
  • Enable scanning of a new or unconventional file-layout
  • Limit scanning to a subset of PHP folders or files.
  • Skip unconventional PHP files that would raise errors during scanning.
  • Optimize scanning performance for a very large source-tree

The results of hook_scanClasses are generally cached and indexed. To perform a new scan, you may need to flush system caches.


hook_civicrm_scanClasses(array &$classes): void


  • array $classes - List of class-names. Each class-name will be scanned.


// Enable scanning for a specific class
function modulename_civicrm_scanClasses(&$classes) {
  $classes = 'CRM_MyExtension_FooBar';
// Scan a specific folder/namespace
function modulename_civicrm_scanClasses(&$classes) {
  $baseDir = CRM_Utils_File::addTrailingSlash(__DIR__);
  \Civi\Core\ClassScanner::scanFolders($classes, $baseDir, 'CRM', '_');


The class-scanner searches for classes that implement certain interfaces. Generally, the classes and interfaces are found in specific namespaces (CRM_ and Civi\).

Notable interfaces include:

  • Civi\Afform\BehaviorInterface
  • Civi\Core\Service\AutoServiceInterface (See also: Service Container)
  • Civi\Test\ExampleDataInterface
  • Civi\UserJob\UserJobInterface
  • Civi\WorkflowMessage\WorkflowMessageInterface (See also: Workflow Messages)

(The scan mechanism is extensible, and this list may not be exhaustive.)