PHPackages                             alexdesignworks/drupal\_helpers - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. alexdesignworks/drupal\_helpers

AbandonedLibrary[Utility &amp; Helpers](/categories/utility)

alexdesignworks/drupal\_helpers
===============================

Helper classes for Drupal

81.3k3[1 issues](https://github.com/AlexSkrypnyk/drupal_helpers/issues)PHPCI passing

Since Feb 24Pushed 1mo ago4 watchersCompare

[ Source](https://github.com/AlexSkrypnyk/drupal_helpers)[ Packagist](https://packagist.org/packages/alexdesignworks/drupal_helpers)[ RSS](/packages/alexdesignworks-drupal-helpers/feed)WikiDiscussions 2.x Synced 2mo ago

READMEChangelog (5)DependenciesVersions (1)Used By (0)

  ![Drupal Helpers logo](logo.png)

Helper utilities for Drupal
===========================

[](#helper-utilities-for-drupal)

[![GitHub Issues](https://camo.githubusercontent.com/73b7a5fe6d1c579329cbebaf992d207722c6fc7190706a0fda2653f0513a9a6d/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6973737565732f416c6578536b7279706e796b2f64727570616c5f68656c706572732e737667)](https://github.com/AlexSkrypnyk/drupal_helpers/issues)[![GitHub Pull Requests](https://camo.githubusercontent.com/13b56048ae5ddef8995ffa54ae1866175b9b6fd3b08a6e9add404e3ae27be56f/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6973737565732d70722f416c6578536b7279706e796b2f64727570616c5f68656c706572732e737667)](https://github.com/AlexSkrypnyk/drupal_helpers/pulls)[![Build, test and deploy](https://github.com/AlexSkrypnyk/drupal_helpers/actions/workflows/test.yml/badge.svg)](https://github.com/AlexSkrypnyk/drupal_helpers/actions/workflows/test.yml)[![codecov](https://camo.githubusercontent.com/79f95cb4a9efff93b0469e15e7e89cbd4966e118f44f5b7dbd10785bbc173397/68747470733a2f2f636f6465636f762e696f2f67682f416c6578536b7279706e796b2f64727570616c5f68656c706572732f67726170682f62616467652e7376673f746f6b656e3d54364958594154345655)](https://codecov.io/gh/AlexSkrypnyk/drupal_helpers)[![GitHub release (latest by date)](https://camo.githubusercontent.com/cbb3a3a9c0d4f7ae256fbaf7d9caeb238d7737cc05c295c12c14c90afd051b7a/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f762f72656c656173652f416c6578536b7279706e796b2f64727570616c5f68656c70657273)](https://camo.githubusercontent.com/cbb3a3a9c0d4f7ae256fbaf7d9caeb238d7737cc05c295c12c14c90afd051b7a/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f762f72656c656173652f416c6578536b7279706e796b2f64727570616c5f68656c70657273)[![LICENSE](https://camo.githubusercontent.com/a5c6eb0681928a4dd79ac7e58470acd6f38311266b09bbb477d61b157c1ce757/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f416c6578536b7279706e796b2f64727570616c5f68656c70657273)](https://camo.githubusercontent.com/a5c6eb0681928a4dd79ac7e58470acd6f38311266b09bbb477d61b157c1ce757/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f416c6578536b7279706e796b2f64727570616c5f68656c70657273)[![Renovate](https://camo.githubusercontent.com/35389190ce58a3690fe850342c1c3fd4f54e4c10ba8996741c8558ee24bf50dc/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f72656e6f766174652d656e61626c65642d677265656e3f6c6f676f3d72656e6f76617465626f74)](https://camo.githubusercontent.com/35389190ce58a3690fe850342c1c3fd4f54e4c10ba8996741c8558ee24bf50dc/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f72656e6f766174652d656e61626c65642d677265656e3f6c6f676f3d72656e6f76617465626f74)

[![PHP 8.2](https://camo.githubusercontent.com/048575f831dc651cb5dd833ad64019025a5d2b167c14eeffbffe88d99f614330/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e322d3737374242342e737667)](https://camo.githubusercontent.com/048575f831dc651cb5dd833ad64019025a5d2b167c14eeffbffe88d99f614330/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e322d3737374242342e737667)[![PHP 8.3](https://camo.githubusercontent.com/c11b693fb1fab7475e3f8cef6f611517121bf28e1604043ab0b41c5c1d0332ff/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e332d3737374242342e737667)](https://camo.githubusercontent.com/c11b693fb1fab7475e3f8cef6f611517121bf28e1604043ab0b41c5c1d0332ff/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e332d3737374242342e737667)[![PHP 8.4](https://camo.githubusercontent.com/57027d373b7f5a7948c357666d6dd77ce090b410c617c924030ced42e76ede6e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e342d3737374242342e737667)](https://camo.githubusercontent.com/57027d373b7f5a7948c357666d6dd77ce090b410c617c924030ced42e76ede6e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e342d3737374242342e737667)[![Drupal 10](https://camo.githubusercontent.com/e5f6e92ce118cc419657eb53f5efddc13221f8a3e319188e8b4269bb0ab0ea9c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f44727570616c2d31302d3030394344452e737667)](https://camo.githubusercontent.com/e5f6e92ce118cc419657eb53f5efddc13221f8a3e319188e8b4269bb0ab0ea9c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f44727570616c2d31302d3030394344452e737667)[![Drupal 11](https://camo.githubusercontent.com/54ae7b934de2b0f91c1b3e3396214d198f42d82cf9b21a031ce3a8f67a9a00b7/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f44727570616c2d31312d3030364141392e737667)](https://camo.githubusercontent.com/54ae7b934de2b0f91c1b3e3396214d198f42d82cf9b21a031ce3a8f67a9a00b7/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f44727570616c2d31312d3030364141392e737667)

---

Features
--------

[](#features)

 🎯 **Static facade for clean deploy hooks**Access all helpers through `Helper::term()`, `Helper::config()`, etc. — no need to inject services or know container names. One `use` statement is all you need.

```
use Drupal\drupal_helpers\Helper;

Helper::term()->createTree('tags', ['News', 'Events', 'Blog']);
Helper::config()->set('system.site', 'name', 'My Site');
```

 ⚡ **Batch processing for large datasets**Pass the `$sandbox` array from your deploy hook and the helper automatically batches operations across multiple requests — no manual tracking of `$sandbox['#finished']`.

```
// Batch-update every article node:
function my_module_deploy_001(array &$sandbox): ?string {
  return Helper::entity($sandbox)->batchEntity('node', 'article', function ($node) {
    $node->set('field_migrated', TRUE);
    $node->save();
  });
}

// Batch-delete all articles:
function my_module_deploy_002(array &$sandbox): ?string {
  return Helper::entity($sandbox)->deleteAll('node', 'article');
}

// Batch-process arbitrary items with a callback:
function my_module_deploy_003(array &$sandbox): ?string {
  $emails = ['user1@example.com', 'user2@example.com', /* ... hundreds more */];
  return Helper::user($sandbox)->batch($emails, function ($email) {
    Helper::user()->create($email, ['editor']);
  }, 'users');
}
```

 🧰 **Taxonomy, menu, field, entity, config, user, and redirect helpers**Common deploy hook operations covered out of the box:

- Create taxonomy term trees (flat or nested) with duplicate detection.
- Build menu link hierarchies from arrays.
- Delete fields and field instances with automatic data purging.
- Import config YAML from modules.
- Create users with roles and auto-generated passwords.
- Create, import (CSV), and clean up redirects.

 🔌 **Extendable via Drupal services**Every helper is a standard Drupal service registered in `drupal_helpers.services.yml`. You can override, decorate, or inject them into your own services using Drupal's dependency injection container.

```
# Use a helper as a dependency in your own service:
services:
  my_module.migrator:
    class: Drupal\my_module\Migrator
    arguments: ['@drupal_helpers.term', '@drupal_helpers.entity']
```

 🛡️ **Module requirement checking**Helpers that depend on contrib modules (e.g., Redirect requires the `redirect`module) declare their requirements via `requiredModules()`. The facade checks these at access time and throws a clear error if a module is missing — no cryptic "service not found" exceptions.

Usage
-----

[](#usage)

All helpers are accessed via the `Helper` facade:

```
use Drupal\drupal_helpers\Helper;

// Simple — no sandbox:
Helper::term()->createTree('topics', $tree);
Helper::field()->delete('field_old');

// Batched — with sandbox:
function my_module_deploy_001(array &$sandbox): ?string {
  return Helper::entity($sandbox)->deleteAll('node', 'article');
}
```

Available methods
-----------------

[](#available-methods)

HelperDescription[Config](#config)Configuration helpers for deploy hooks.[Entity](#entity)Entity helpers for deploy hooks.[Field](#field)Field helpers for deploy hooks.[Menu](#menu)Menu link helpers for deploy hooks.[Redirect](#redirect)Redirect helpers for deploy hooks.[Term](#term)Taxonomy term helpers for deploy hooks.[User](#user)User helpers for deploy hooks.---

### Config

[](#config)

[Source](src/Helpers/Config.php)

> Configuration helpers for deploy hooks.

 Set a value in a configuration object.
`set(string $config_name, string $key, mixed $value): void````
Helper::config()->set('system.site', 'name', 'My Site');
```

 Get a value from a configuration object.
`get(string $config_name, string $key): mixed````
$site_name = Helper::config()->get('system.site', 'name');
```

 Delete a configuration object.
`delete(string $config_name): void````
Helper::config()->delete('my_module.settings');
```

 Import a config from a module's config/install directory.
`import(string $module_name, string $config_name, string $subdirectory = 'install'): void````
Helper::config()->import('my_module', 'views.view.my_view');
Helper::config()->import('my_module', 'node.type.page', 'optional');
```

 Import multiple configs from a module.
`importMultiple(string $module_name, array $config_names, string $subdirectory = 'install'): void````
Helper::config()->importMultiple('my_module', [
  'views.view.my_view',
  'field.storage.node.field_custom',
]);
```

 Set the site front page.
`setFrontPage(string $path): void````
Helper::config()->setFrontPage('/node/1');
```

### Entity

[](#entity)

[Source](src/Helpers/Entity.php)

> Entity helpers for deploy hooks.

 Delete all entities of a given type and optional bundle.
`deleteAll(string $entity_type, ?string $bundle = NULL): ?string````
Helper::entity()->deleteAll('node', 'article');

// With sandbox for large datasets:
function my_module_deploy_001(array &$sandbox): ?string {
  return Helper::entity($sandbox)->deleteAll('node', 'article');
}
```

### Field

[](#field)

[Source](src/Helpers/Field.php)

> Field helpers for deploy hooks.

 Delete a field from all entity bundles and purge its data.
`delete(string $field_name): void````
Helper::field()->delete('field_subtitle');
```

 Delete a field instance from a specific entity bundle.
`deleteInstance(string $field_name, string $entity_type, string $bundle): void````
Helper::field()->deleteInstance('field_subtitle', 'node', 'article');
```

### Menu

[](#menu)

[Source](src/Helpers/Menu.php)

> Menu link helpers for deploy hooks.

 Create menu links from a nested tree structure.
`createTree(string $menu_name, array $tree, ?string $parent_id = NULL): array````
$tree = [
  'Home' => '/',
  'About' => [
    'path' => '/about',
    'children' => [
      'Team' => '/about/team',
      'Contact' => '/about/contact',
    ],
  ],
  'External' => 'https://example.com',
];
Helper::menu()->createTree('main', $tree);
```

 Delete all menu links from a menu.
`deleteTree(string $menu_name): ?string````
Helper::menu()->deleteTree('main');
```

 Find a menu link by properties.
`findItem(string $menu_name, array $properties): ?MenuLinkContentInterface````
$link = Helper::menu()->findItem('main', ['title' => 'About']);
```

 Update properties on an existing menu link found by properties.
`updateItem(string $menu_name, array $find_properties, array $updates): ?MenuLinkContentInterface````
Helper::menu()->updateItem('main', ['title' => 'About'], [
  'path' => '/about-us',
  'weight' => 5,
]);
```

### Redirect

[](#redirect)

[Source](src/Helpers/Redirect.php)

> Redirect helpers for deploy hooks.

 Create a redirect.
`create(string $source_path, string $redirect_path, int $status_code = 301, bool $skip_existing = TRUE): mixed````
Helper::redirect()->create('old-page', '/new-page');
Helper::redirect()->create('legacy', 'https://example.com', 302);
```

 Create multiple redirects.
`createMultiple(array $redirects): int````
Helper::redirect()->createMultiple([
  ['source' => 'old-page', 'target' => '/new-page'],
  ['source' => 'legacy', 'target' => 'https://example.com', 'status_code' => 302],
]);
```

 Delete redirects by source path.
`deleteBySource(string $source_path): int````
Helper::redirect()->deleteBySource('old-page');
```

 Delete all redirect entities.
`deleteAll(): ?string````
Helper::redirect()->deleteAll();
```

 Import redirects from a CSV file.
`importFromCsv(string $file_path): ?string````
Helper::redirect()->importFromCsv('/path/to/redirects.csv');

// With sandbox for large files:
function my_module_deploy_001(array &$sandbox): ?string {
  return Helper::redirect($sandbox)->importFromCsv('/path/to/redirects.csv');
}
```

### Term

[](#term)

[Source](src/Helpers/Term.php)

> Taxonomy term helpers for deploy hooks.

 Create terms from a nested tree structure.
`createTree(string $vocabulary, array $tree, bool $preserve_existing = TRUE, int $parent_tid = 0): array````
// Flat list:
Helper::term()->createTree('tags', ['News', 'Events', 'Blog']);

// Nested hierarchy:
Helper::term()->createTree('topics', [
  'Finance' => [
    'Budgets',
    'Grants',
  ],
  'Governance' => [
    'Policy' => [
      'Internal',
      'External',
    ],
    'Compliance',
  ],
  'Operations',
]);
```

 Delete all terms from a vocabulary.
`deleteAll(string $vocabulary): ?string````
Helper::term()->deleteAll('tags');
```

 Find a term by name in a vocabulary.
`find(string $name, ?string $vocabulary = NULL): ?TermInterface````
$term = Helper::term()->find('News', 'tags');
```

### User

[](#user)

[Source](src/Helpers/User.php)

> User helpers for deploy hooks.

 Create a user account.
`create(string $email, array $roles = [], array $fields = []): UserInterface````
Helper::user()->create('admin@example.com', ['administrator']);
Helper::user()->create('editor@example.com', ['editor'], [
  'name' => 'editor1',
  'status' => 1,
]);
```

 Create multiple user accounts.
`createMultiple(array $emails, array $roles = [], array $fields = []): array````
Helper::user()->createMultiple([
  'user1@example.com',
  'user2@example.com',
], ['editor']);
```

 Assign roles to an existing user.
`assignRoles(string $user_identifier, array $roles): void````
Helper::user()->assignRoles('admin@example.com', ['administrator']);
```

 Remove roles from an existing user.
`removeRoles(string $user_identifier, array $roles): void````
Helper::user()->removeRoles('admin@example.com', ['administrator']);
```

Maintenance
-----------

[](#maintenance)

### Local development

[](#local-development)

1. Install PHP with SQLite support and Composer
2. Clone this repository
3. Run `ahoy build`

### Building website

[](#building-website)

`ahoy build` assembles the codebase, starts the PHP server and provisions the Drupal website with this extension enabled. These operations are executed using scripts within [`.devtools`](.devtools) directory. CI uses the same scripts to build and test this extension.

The resulting codebase is then placed in the `build` directory. The extension files are symlinked into the Drupal site structure.

The `build` command is a wrapper for more granular commands:

```
ahoy assemble     # Assemble the codebase
ahoy start        # Start the PHP server
ahoy provision    # Provision the Drupal website
```

The `provision` command is useful for re-installing the Drupal website without re-assembling the codebase.

#### Drupal versions

[](#drupal-versions)

The Drupal version used for the codebase assembly is determined by the `DRUPAL_VERSION` variable and defaults to the latest stable version.

You can specify a different version by setting the `DRUPAL_VERSION` environment variable before running the `ahoy build` command:

```
DRUPAL_VERSION=11 ahoy build        # Drupal 11
DRUPAL_VERSION=11@alpha ahoy build  # Drupal 11 alpha
DRUPAL_VERSION=10@beta ahoy build   # Drupal 10 beta
DRUPAL_VERSION=11.1 ahoy build      # Drupal 11.1
```

The `minimum-stability` setting in the `composer.json` file is automatically adjusted to match the specified Drupal version's stability.

#### Provisioning the website

[](#provisioning-the-website)

The `provision` command installs the Drupal website from the `standard`profile with the extension (and any `suggest`'ed extensions) enabled. The profile can be changed by setting the `DRUPAL_PROFILE` environment variable.

The website will be available at . The hostname and port can be changed by setting the `WEBSERVER_HOST` and `WEBSERVER_PORT` environment variables.

An SQLite database is created in `/tmp/site_drupal_helpers.sqlite` file. You can browse the contents of the created SQLite database using [DB Browser for SQLite](https://sqlitebrowser.org/).

A one-time login link will be printed to the console.

### Coding standards

[](#coding-standards)

The `ahoy lint` command checks the codebase using multiple tools:

- PHP code standards checking against `Drupal` and `DrupalPractice` standards.
- PHP code static analysis with PHPStan.
- PHP deprecated code analysis and auto-fixing with Drupal Rector.
- JavaScript code analysis with ESLint.
- CSS code analysis with Stylelint.

The configuration files for these tools are located in the root of the codebase.

#### Fixing coding standards issues

[](#fixing-coding-standards-issues)

To fix coding standards issues automatically, run `ahoy lint-fix`. This runs the same tools as `lint` command but with the `--fix` option (for the tools that support it).

### Testing

[](#testing)

The `ahoy test` command runs the PHPUnit tests for this extension.

The tests are located in the `tests/src` directory. The `phpunit.xml` file configures PHPUnit to run the tests. It uses Drupal core's bootstrap file `core/tests/bootstrap.php` to bootstrap the Drupal environment before running the tests.

The `test` command is a wrapper for multiple test commands:

```
ahoy test-unit                    # Run Unit tests
ahoy test-kernel                  # Run Kernel tests
ahoy test-functional              # Run Functional tests
```

#### Running specific tests

[](#running-specific-tests)

You can run specific tests by passing a path to the test file or PHPUnit CLI option (`--filter`, `--group`, etc.) to the `ahoy test` command:

```
ahoy test-unit tests/src/Unit/MyUnitTest.php
ahoy test-unit -- --group=wip
```

You may also run tests using the `phpunit` command directly:

```
cd build
php -d pcov.directory=.. vendor/bin/phpunit tests/src/Unit/MyUnitTest.php
php -d pcov.directory=.. vendor/bin/phpunit --group=wip
```

---

*This repository was created using the [Drupal Extension Scaffold](https://github.com/AlexSkrypnyk/drupal_extension_scaffold) project template*

###  Health Score

33

—

LowBetter than 75% of packages

Maintenance56

Moderate activity, may be stable

Popularity22

Limited adoption so far

Community16

Small or concentrated contributor base

Maturity34

Early-stage or recently created project

 Bus Factor1

Top contributor holds 83.5% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

### Community

Maintainers

![](https://www.gravatar.com/avatar/b57b0fd0b96f77f2efa1a1889af0ae607fa139bcc1256e809ee3ebbb30907364?d=identicon)[alexdrevops](/maintainers/alexdrevops)

---

Top Contributors

[![AlexSkrypnyk](https://avatars.githubusercontent.com/u/378794?v=4)](https://github.com/AlexSkrypnyk "AlexSkrypnyk (101 commits)")[![christopher-hopper](https://avatars.githubusercontent.com/u/452515?v=4)](https://github.com/christopher-hopper "christopher-hopper (16 commits)")[![renovate[bot]](https://avatars.githubusercontent.com/in/2740?v=4)](https://github.com/renovate[bot] "renovate[bot] (2 commits)")[![dan-lennox](https://avatars.githubusercontent.com/u/473659?v=4)](https://github.com/dan-lennox "dan-lennox (1 commits)")[![GuyPaddock](https://avatars.githubusercontent.com/u/2631799?v=4)](https://github.com/GuyPaddock "GuyPaddock (1 commits)")

---

Tags

drupaldrupal-helpersphpupdateutility

### Embed Badge

![Health badge](/badges/alexdesignworks-drupal-helpers/health.svg)

```
[![Health](https://phpackages.com/badges/alexdesignworks-drupal-helpers/health.svg)](https://phpackages.com/packages/alexdesignworks-drupal-helpers)
```

###  Alternatives

[cebe/yii2-gravatar

Gravatar Widget for Yii 2

441.8M35](/packages/cebe-yii2-gravatar)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
