Skip to content

jhedstrom/DrupalDriver

Repository files navigation

Drupal Driver

Latest Stable Version Total Downloads License

ci GitHub Issues GitHub Pull Requests

Join our community

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: This master branch is under heavy development for version 3.x. Drupal 6 and 7 support has been dropped. For the 2.x maintenance line, use the 2.x branch. See the 3.x epic for details and progress.

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;

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 = (object) [
  'type' => 'article',
  'uid' => 1,
  'title' => $driver->getRandom()->name(),
];
$driver->nodeCreate($node);

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

Release notes

See GitHub Releases.

Contributing

Features and bug fixes are welcome!

See CONTRIBUTING.md for more information.

About

A collection of drivers for controlling Drupal.

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Sponsor this project

 

Packages

 
 
 

Contributors

Languages