drupal / drupal-driver
A collection of reusable Drupal drivers
Fund package maintenance!
Requires
- php: ^8.2
- drupal/core-utility: ^10 || ^11
- symfony/dependency-injection: ^6.4 || ^7
- symfony/process: ^6.4 || ^7
Requires (Dev)
- behat/mink: ^1.11
- composer/installers: ^2.1
- drevops/phpcs-standard: ^0.7.0
- drupal/address: ^2.0.4
- drupal/coder: ~8.3.0
- drupal/commerce: ^3.0
- drupal/core-composer-scaffold: ^11.2
- drupal/core-recommended: ^11.2
- drupal/mailsystem: ^4.4
- drupal/name: ^1.2
- drupal/smart_date: ^4.2
- drupal/supported_image: ^1
- drupal/time_field: ^2.2.1
- ergebnis/composer-normalize: ^2.50
- mglaman/phpstan-drupal: ^2.0
- mikey179/vfsstream: ^1.6.11
- palantirnet/drupal-rector: ^0.21.1
- php-parallel-lint/php-parallel-lint: ^1.0
- phpspec/prophecy-phpunit: ^2
- phpstan/extension-installer: ^1.4
- phpstan/phpstan: ^2.0
- phpunit/phpunit: ^10.5.19 || ^11.5.3
- rector/rector: ^1 || ^2
- dev-master / 3.0.x-dev
- v3.0.0
- v3.0.0-rc2
- v3.0.0-rc1
- v3.0.0-alpha1
- 2.x-dev
- v2.5.1
- v2.5.0
- v2.4.3
- v2.4.2
- v2.4.1
- v2.4.0
- v2.3.0
- v2.2.2
- v2.2.1
- v2.2.0
- v2.1.2
- v2.1.1
- v2.1.0
- v2.0.0
- v2.0.0-rc1
- v2.0.0-alpha6
- v2.0.0-alpha5
- v2.0.0-alpha4
- v2.0.0-alpha3
- v2.0.0-alpha2
- v2.0.0-alpha1
- v1.4.0
- v1.3.2
- v1.3.1
- v1.3.0
- v1.2.2
- v1.2.1
- v1.2.0
- v1.1.6
- v1.1.5
- v1.1.4
- v1.1.3
- v1.1.2
- v1.1.1
- v1.1.0
- v1.0.17
- v1.0.16
- v1.0.15
- v1.0.14
- v1.0.13
- v1.0.12
- v1.0.11
- v1.0.10
- v1.0.9
- v1.0.8
- v1.0.7
- v1.0.6
- v1.0.5
- v1.0.4
- v1.0.3
- v1.0.2
- v1.0.1
- v1.0.0
- v1.0.0-beta2
- v1.0.0-beta
- dev-feature/v3-doc-polish
- dev-feature/compound-shape
- dev-feature/362-entity-stub
- dev-feature/field-coverage
- dev-feature/file-handler
This package is auto-updated.
Last update: 2026-05-29 01:28:10 UTC
README
A collection of lightweight drivers with a common interface for interacting with Drupal. These are generally intended for testing and are not meant to be API-complete.
Note: v3 supports Drupal 10 and 11 on PHP 8.2+. Sites that need Drupal 7 or PHP 8.1 should pin to the
2.xbranch. See UPGRADING.md for the v2 to v3 migration guide.
Drivers
| Driver | Description |
|---|---|
| Blackbox | No Drupal bootstrap. Interacts only through HTTP. |
| Drupal API | Bootstraps Drupal directly in PHP for programmatic access to entities, fields, users, and configuration. |
| Drush | Interacts with Drupal through the Drush command line tool. |
Installation
composer require drupal/drupal-driver
Usage
use Drupal\Driver\DrupalDriver; use Drupal\Driver\Entity\EntityStub; require 'vendor/autoload.php'; $path = './web'; // Path to Drupal root. $uri = 'http://my-site'; // Site URI. $driver = new DrupalDriver($path, $uri); $driver->setCoreFromVersion(); // Bootstrap Drupal. $driver->bootstrap(); // Create a node. $node = new EntityStub('node', 'article', [ 'uid' => 1, 'title' => $driver->getRandom()->name(), ]); $saved = $driver->nodeCreate($node); $nid = $saved->getId();
Extending
The driver lets consumer projects override two things without forking: individual field handlers and the top-level Core implementation.
Custom field handler
Implement Drupal\Driver\Core\Field\FieldHandlerInterface (extending
AbstractHandler is the usual path):
namespace MyProject\Driver\Field; use Drupal\Driver\Core\Field\AbstractHandler; class PhoneHandler extends AbstractHandler { public function expand(mixed $values): array { // Convert each scenario-facing phone string into the storage shape // Drupal's field system expects (a list of deltas keyed by column). return array_map(static fn (string $number): array => ['value' => $number], (array) $values); } }
Register it on the active Core instance, typically in a test bootstrap:
$driver = new DrupalDriver($root, $uri); $driver->setCoreFromVersion(); $driver->getCore()->registerFieldHandler('phone', \MyProject\Driver\Field\PhoneHandler::class);
Consumer registrations win over the handlers this project ships for the
same field type. Registration order at runtime is: driver default
handlers (populated by Core::registerDefaultFieldHandlers() at
construction) → consumer registrations → registry lookup at expand()
time, with a fall-through to DefaultHandler for field types no handler
claims.
Custom Core
Implement Drupal\Driver\Core\CoreInterface. The class name and
namespace do not matter. The easiest path is to extend
Drupal\Driver\Core\Core and add version-specific field handlers by
re-scanning your own Field/ directory:
namespace MyProject\Driver; use Drupal\Driver\Core\Core as BaseCore; class Core extends BaseCore { protected function registerDefaultFieldHandlers(): void { parent::registerDefaultFieldHandlers(); $this->registerHandlersFromDirectory(__DIR__ . '/Field', __NAMESPACE__ . '\\Field'); } }
Inject it with $driver->setCore($core):
$driver = new DrupalDriver($root, $uri); $driver->setCore(new \MyProject\Driver\Core($root, $uri));
Credits
- Originally developed by Jonathan Hedstrom
- Maintainers
Release notes
See GitHub Releases.
Contributing
Features and bug fixes are welcome!
See CONTRIBUTING.md for more information.