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 inDomainShortUrlFormHooksdomain_extras/domain_access_linkit— 1 call site inAssignedDomainsNodeMatcher
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
@internalonDomainAccessManagerwithout breaking ecosystem callers.
Out of scope
- The 3 less-used statics (
getDefaultValue,clearStaticCache,userCanAccessDomain) — confirm whether to migrate them too.getDefaultValueis referenced by field defaults so its callable signature is constrained;userCanAccessDomainlooks fine to migrate;clearStaticCacheis internal-only in practice. - Other modules' equivalent helpers (none found in the survey —
DomainAccessPermissions,DomainAccessHelper,DomainSourceHelper,DomainElementManagerhave 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
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
Comment #3
mably commentedComment #5
mably commented