Skip to content

Drupal project support #48

@syntlyx

Description

@syntlyx

A reference Drupal project for testing is available at: https://github.com/syntlyx/drupal-example

How Drupal is structured

A standard Drupal Composer project looks like this:

project/
├── composer.json
├── composer.lock
├── vendor/
└── web/                        # web root (varies, see below)
    ├── core/                   # Drupal core
    ├── modules/
    │   ├── contrib/            # contributed modules
    │   └── custom/             # project-specific modules
    ├── themes/
    │   ├── contrib/
    │   └── custom/
    ├── profiles/               # install profiles
    └── sites/

Detecting a Drupal project

PHPantom can reliably detect Drupal from composer.json:

"require": {
    "drupal/core-recommended": "^10.0"
}

Relevant package names to detect: drupal/core, drupal/core-recommended, drupal/core-dev.

Resolving the web root

The web root is not always web/. It is defined in composer.json under:

"extra": {
    "drupal-scaffold": {
        "locations": {
            "web-root": "docroot/"
        }
    }
}

Common values: web/, docroot/, public/, html/. If the key is absent, fall back to checking which of these directories contains core/lib/Drupal.php.

Paths to index

Once the web root is resolved, the following directories should be scanned:

Path Contains
{web-root}/core/ Drupal core classes, interfaces, hooks
{web-root}/modules/contrib/ Contributed modules
{web-root}/modules/custom/ Project-specific modules
{web-root}/themes/contrib/ Contributed themes
{web-root}/themes/custom/ Project themes
{web-root}/profiles/ Install profiles
{web-root}/sites/ Site-specific code

PHP file extensions

Drupal uses several non-.php extensions for valid PHP files:

Extension Purpose
.module Hook implementations, main module file
.install hook_schema(), update hooks, hook_install()
.theme Theme hook implementations
.profile Install profile hooks
.inc Shared include files
.engine Theme engine files (rare)

All of these start with <?php and are plain PHP.

Paths to exclude

Test directories should be excluded from indexing — they add noise and can contain duplicate class definitions:

Path Reason
{web-root}/core/tests/ Drupal core test classes
{web-root}/core/modules/*/tests/ Per-module core tests
{web-root}/modules/contrib/*/tests/ Contrib module tests
{web-root}/modules/custom/*/tests/ Custom module tests (optional, project preference)
{web-root}/themes/contrib/*/tests/ Contrib theme tests
vendor/*/tests/ Vendor package tests
vendor/*/Tests/ Some packages use capital T

Note that both tests/ and Tests/ variants exist in the wild — Drupal core and most contrib use lowercase, but some Composer packages (Symfony, Doctrine) use uppercase.

The .gitignore problem

Drupal's default .gitignore excludes the web root scaffold files:

/web/core
/web/modules/contrib
/web/themes/contrib
/vendor

These directories are excluded from version control because they are managed by Composer — but they must be indexed by PHPantom. web/core in particular contains all of Drupal's base interfaces, hooks, and services that every module depends on.

Using .gitignore to determine what to skip will silently drop the most important parts of the codebase.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions