All skills
grasmash avatar

/drupal-contrib-mgmt

@eb9b3d3

Comprehensive guide for managing Drupal contributed modules via Composer, including updates, patches, version compatibility, and Drupal 11 upgrades. Use when updating modules or resolving dependency issues.

Use this Skill: https://skilld.dev/gh/grasmash/drupal-claude-skills/drupal-contrib-mgmt

This session only. Nothing lands on disk.

referencesd11-common-deprecations.md

≈1.7k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Common Drupal 11 Deprecations and Fixes

Deprecated Constants

REQUEST_TIME

Deprecated in: Drupal 8.3.0 Removed in: Drupal 11.0.0

OLD:

$timestamp = REQUEST_TIME;
$time_ago = REQUEST_TIME - $node->getCreatedTime();

NEW:

// Inject TimeInterface service
use Drupal\Core\Datetime\TimeInterface;

class MyClass {
  protected $time;

  public function __construct(TimeInterface $time) {
    $this->time = $time;
  }

  public static function create(ContainerInterface $container) {
    return new static($container->get('datetime.time'));
  }

  public function myMethod() {
    $timestamp = $this->time->getRequestTime();
    $time_ago = $this->time->getRequestTime() - $node->getCreatedTime();
  }
}

Deprecated Functions

user_roles()

Deprecated in: Drupal 10.2.0 Removed in: Drupal 11.0.0

OLD:

$roles = user_roles(TRUE); // Exclude anonymous

NEW:

use Drupal\user\Entity\Role;

$roles = Role::loadMultiple();
$role_names = [];
foreach ($roles as $role_id => $role) {
  if ($role_id !== 'anonymous') {
    $role_names[$role_id] = $role->label();
  }
}

user_role_names()

Deprecated in: Drupal 10.2.0 Removed in: Drupal 11.0.0

OLD:

$role_options = user_role_names(TRUE);

NEW:

use Drupal\user\Entity\Role;

$roles = Role::loadMultiple();
$role_options = [];
foreach ($roles as $role_id => $role) {
  if ($role_id !== 'anonymous') {
    $role_options[$role_id] = $role->label();
  }
}

file_validate_extensions()

Deprecated in: Drupal 10.2.0 Removed in: Drupal 11.0.0

OLD:

$errors = file_validate_extensions($file, 'mp3 wav ogg');

NEW:

// Inject file.validator service
use Drupal\Core\File\FileSystemInterface;
use Drupal\file\Validation\FileValidatorInterface;

class MyClass {
  protected $fileValidator;

  public function __construct(FileValidatorInterface $file_validator) {
    $this->fileValidator = $file_validator;
  }

  public static function create(ContainerInterface $container) {
    return new static($container->get('file.validator'));
  }

  public function validateFile($file) {
    $validators = [
      'FileExtension' => [
        'extensions' => 'mp3 wav ogg',
      ],
    ];
    $violations = $this->fileValidator->validate($file, $validators);
    return $violations;
  }
}

system_retrieve_file()

Deprecated in: Drupal 10.2.0 Removed in: Drupal 11.0.0 Replacement: None - must be refactored

OLD:

$file = system_retrieve_file($url, $destination, FALSE, FILE_EXISTS_REPLACE);

NEW:

// Use file_system service and http_client
use Drupal\Core\File\FileSystemInterface;
use GuzzleHttp\ClientInterface;

class MyClass {
  protected $fileSystem;
  protected $httpClient;

  public function __construct(FileSystemInterface $file_system, ClientInterface $http_client) {
    $this->fileSystem = $file_system;
    $this->httpClient = $http_client;
  }

  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('file_system'),
      $container->get('http_client')
    );
  }

  public function retrieveFile($url, $destination) {
    try {
      $response = $this->httpClient->get($url);
      $data = $response->getBody()->getContents();

      $directory = dirname($destination);
      $this->fileSystem->prepareDirectory($directory, FileSystemInterface::CREATE_DIRECTORY);

      return $this->fileSystem->saveData($data, $destination, FileSystemInterface::EXISTS_REPLACE);
    }
    catch (\Exception $e) {
      \Drupal::logger('my_module')->error('Failed to retrieve file: @error', ['@error' => $e->getMessage()]);
      return FALSE;
    }
  }
}

_drupal_flush_css_js()

Deprecated in: Drupal 10.2.0 Removed in: Drupal 11.0.0

OLD:

_drupal_flush_css_js();

NEW:

// Inject asset.query_string service
use Drupal\Core\Asset\AssetQueryStringInterface;

class MyClass {
  protected $assetQueryString;

  public function __construct(AssetQueryStringInterface $asset_query_string) {
    $this->assetQueryString = $asset_query_string;
  }

  public static function create(ContainerInterface $container) {
    return new static($container->get('asset.query_string'));
  }

  public function flushAssets() {
    $this->assetQueryString->reset();
  }
}

Deprecated Class Constants

FileSystemInterface::EXISTS_* Constants

Deprecated in: Drupal 10.3.0 Removed in: Drupal 12.0.0 (warning for D11)

OLD:

use Drupal\Core\File\FileSystemInterface;

$file = $file_system->copy($source, $destination, FileSystemInterface::EXISTS_REPLACE);

NEW:

use Drupal\Core\File\FileExists;

$file = $file_system->copy($source, $destination, FileExists::Replace);

Twig Deprecations

spaceless Filter

Deprecated in: Twig 3.12 Removed in: Drupal 11.0.0

OLD:

{% apply spaceless %}
  <div>
    <span>Content</span>
  </div>
{% endapply %}

NEW:

{# Remove spaceless - use CSS or HTML minification instead #}
<div>
  <span>Content</span>
</div>

Module Info File Changes

core_version_requirement

Required for: Drupal 11 compatibility

OLD:

name: My Module
type: module
core_version_requirement: ^9 || ^10

NEW:

name: My Module
type: module
core_version_requirement: ^9 || ^10 || ^11

Create patch:

# From the project root; contrib is not a git repo, so take a temporary baseline first
MODULE_DIR=docroot/modules/contrib/my_module   # or web/modules/contrib/my_module
git -C "$MODULE_DIR" init -q && git -C "$MODULE_DIR" add -A
git -C "$MODULE_DIR" -c user.name=patch -c user.email=patch@localhost commit -qm pristine
# Edit $MODULE_DIR/my_module.info.yml
git -C "$MODULE_DIR" diff > patches/my_module-d11-info.patch
git -C "$MODULE_DIR" checkout -- . && rm -rf "$MODULE_DIR/.git"

Quick Reference: Service Names

Old Function/Constant Service Name Interface
REQUEST_TIME datetime.time Drupal\Core\Datetime\TimeInterface
user_roles() N/A Drupal\user\Entity\Role::loadMultiple()
file_validate_extensions() file.validator Drupal\file\Validation\FileValidatorInterface
system_retrieve_file() file_system + http_client FileSystemInterface + ClientInterface
_drupal_flush_css_js() asset.query_string Drupal\Core\Asset\AssetQueryStringInterface

Testing Your Fixes

After making changes, always:

  1. Clear cache: drush cr
  2. Run upgrade_status: drush upgrade_status:analyze module_name
  3. Check logs: drush watchdog:show --severity=Error
  4. Visit pages: Test actual functionality
  5. Run tests: If module has tests, run them

Finding More Information

Source: SKILL.md on GitHub

3 warnings16d5 checks · Risk SAFE
  • Gen Agent Trust Hub16d

    This skill provides a comprehensive and secure workflow for managing Drupal contributed modules, emphasizing the use of official community sources, standard tools like Composer and Drush, and best practices for patch management and version upgrades.

  • Socket16d

    1 alert: gptAnomaly

  • Snyk16d

    Risk: MEDIUM · 1 issue

  • Runlayer6mo

    5/8 files flagged

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at eb9b3d3. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 2 months ago.

Steadyupdated 4 months ago

README badge

README badge for grasmash/drupal-claude-skills/drupal-contrib-mgmt