Problem

Drupal\domain_access\DomainAccessManager exposes 5 public static methods that ecosystem modules consume directly:

  • getAccessValues(FieldableEntityInterface $entity, $field_name = ...)
  • getAllValue(FieldableEntityInterface $entity)
  • getDefaultValue(FieldableEntityInterface $entity, FieldDefinitionInterface $definition)
  • clearStaticCache($entity_id = NULL, $entity_type_id = NULL)
  • userCanAccessDomain(AccountInterface $account, $domain_id): UserDomainAccess

Two of these (getAccessValues() and getAllValue()) are de-facto public API in the ecosystem:

  • domain_path — 11 call sites across 3 files (DomainPathHelper, DomainPathFormHelper, DomainPathItem)
  • domain_shorturl — 1 call site in DomainShortUrlFormHooks
  • domain_extras/domain_access_linkit — 1 call site in AssignedDomainsNodeMatcher

The (now-reverted) @internal tag on DomainAccessManager in #3584261 surfaced the conflict: marking the service @internal while keeping its statics public sends mixed signals and forces every ecosystem call site to add @phpstan-ignore method.internalClass.

Proposal

Extract the static helpers into a dedicated public utility class Drupal\domain_access\Utility\DomainAccessFields (name TBD). Same shape — pure entity-field readers, no DI needed, mirrors how #3583423 extracted DomainStorage::createMachineName() to Drupal\domain\Utility\MachineName::fromString().

On DomainAccessManager, the existing statics become @deprecated in domain:3.x.0 and is removed from domain:4.0.0 BC wrappers that delegate to the new class. Sibling modules migrate via a clean use Drupal\domain_access\Utility\DomainAccessFields; swap.

Once 4.0.0 lands, the wrappers + the cross-module phpstan friction disappear and DomainAccessManager can go back to being @internal cleanly.

Rationale

  • Mirrors the precedent set by MachineName::fromString() in #3583423 — separate "service" (instance, internal-able) from "field utility" (public).
  • The methods are pure-data readers with no instance state — having them on a service class with a __construct() that only exists to host static methods is awkward.
  • Sibling modules get a clean migration path without needing DI churn for what should be a simple field-value lookup.
  • Lets the next deprecation pass (4.0.0) restore @internal on DomainAccessManager without breaking ecosystem callers.

Out of scope

  • The 3 less-used statics (getDefaultValue, clearStaticCache, userCanAccessDomain) — confirm whether to migrate them too. getDefaultValue is referenced by field defaults so its callable signature is constrained; userCanAccessDomain looks fine to migrate; clearStaticCache is internal-only in practice.
  • Other modules' equivalent helpers (none found in the survey — DomainAccessPermissions, DomainAccessHelper, DomainSourceHelper, DomainElementManager have no public statics worth migrating).

Target

Deprecate in domain:3.x, remove wrappers in domain:4.0.0.

Discovered while auditing #3584261.

Issue fork domain-3588246

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

mably created an issue. See original summary.

mably’s picture

Status: Active » Needs review

  • mably committed a9f9ac77 on 3.x
    task: #3588246 Extract DomainAccessManager static helpers (...
mably’s picture

Status: Needs review » Fixed

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.