Problem/Motivation
When the label mode is "Automatically generate the label and hide the label field", the module writes a literal marker into the label widget's default value and replaces it at presave. Two shapes are in use on 8.x-3.x, all four occurrences written as literal strings:
auto_entitylabel.moduleline 99:$widget['value']['#default_value'] = '%AutoEntityLabel%';auto_entitylabel.moduleline 177:$placeholder = strtr('%AutoEntityLabel: @entityId%', ['@entityId' => $entity->uuid()]);- lines 190 and 259, which compare the label back against those two shapes
That works inside the module. The side effect is that the marker is a value on the entity, so any other code inspecting entity values between form build and presave sees it as if a user had typed it. There is no supported way for another module to ask "is this label a placeholder rather than user input", short of hard coding the same strings and keeping them in sync with this module.
A current example from inline_entity_form. #3099844 deals with an optional IEF field whose referenced entity has required fields: the widget validates and saves a child entity even when the user never touched the subform. The merge request under discussion there decides whether to skip the subform by asking whether the entity is empty, and it deliberately still looks at the label key, because skipping every base field would make an entity with a typed title look empty too. With automatic labels enabled, the untouched subform carries the marker in its title, counts as non-empty, and the fix never engages.
#3207966 looks like a sibling of the same shape, where the marker reaches an entity reference validation message and is shown to the user as "This entity (node: %AutoEntityLabel%) cannot be referenced."
#3523418 is another point where this module and inline_entity_form meet, there for nested subforms, so the two modules already have a shared surface worth making explicit.
Steps to reproduce
Measured on Drupal 11.4.7, PHP 8.4, auto_entitylabel 8.x-3.4, inline_entity_form 3.0.0 with MR !136 of #3099844 applied.
- Create content type
individualwith two required fields, and set its label mode to "Automatically generate the label and hide the label field". - Create content type
recordwith an optional entity reference field toindividual, using theinline_entity_form_simplewidget. - Open the
recordform, fill in only the host fields, leave the embeddedindividualsubform untouched, and save.
Expected with that merge request applied: the untouched subform is recognised as empty and skipped.
Actual: it is treated as filled and its required fields block the save. Logging the field responsible inside the emptiness check gives:
field that counts as filled: bundle=individual name=title type=string config_field=no value=%AutoEntityLabel%Setting the same bundle's label mode to disabled, changing nothing else, makes the same merge request behave as intended.
Proposed resolution
Keep the mechanism as it is, make it recognisable from the outside:
- a public constant for the plain marker, for example
AutoEntityLabelManager::PLACEHOLDER - a public helper covering both shapes, so callers do not have to know about the UUID variant:
public static function isPlaceholder(string $label): bool { return $label === self::PLACEHOLDER || (bool) preg_match('/^%AutoEntityLabel: .+%$/', $label); }
The module's own four call sites then use the constant and the helper instead of repeating the literals.
This does not fix the emptiness check in inline_entity_form, that decision belongs to that issue. It gives that code, and anything else that reads entity values before presave, a supported way to ask the question.
Remaining tasks
- Agree on the naming and where the helper belongs,
AutoEntityLabelManagerbeing the obvious home. - Merge request adding the constant and the helper, and converting the four existing literals.
- Unit test for
isPlaceholder()covering the plain marker, the UUID variant, a user typed title and an empty string. - Optional follow up: mention the helper in the module documentation so integrators find it.
I can open the merge request if the approach sounds right.
User interface changes
None.
API changes
Additive only. One new public constant and one new public static method on AutoEntityLabelManager. No signature changes, no behaviour changes, nothing removed, so existing sites are unaffected.
Data model changes
None.
Comments