- Issue created by @bnjmnm
- 🇧🇪Belgium wim leers Ghent 🇧🇪🇪🇺
Surprising this is only surfacing now, because the root cause has been around since April 10, 2024! 🤯
Root cause:
\Drupal\experience_builder\Plugin\Field\FieldTypeOverride\PathItemOverride::propertyDefinitions()
, which does:public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) { $properties = parent::propertyDefinitions($field_definition); $properties['alias']->addConstraint('ValidPath'); return $properties; }
To be investigated why that prevents this from working 😬
- 🇬🇧United Kingdom jessebaker
I just found it now because I'm implementing the "Publish all changes" button and the tests (that I'm writing) for that cannot pass because it's currently not possible to publish changes due to this issue!
- 🇺🇸United States mglaman WI, USA
I thought we had an issue about this, sorry! It's documented in https://git.drupalcode.org/project/experience_builder/-/blob/0.x/tests/s... and we ran into it while working on ✨ Creating a page generates the URL path dynamically when editing. Active
// Path field is always invalid for new entities. // @see \Drupal\path\Plugin\Field\FieldWidget\PathWidget::validateFormElement().
The widget excludes the violation if it's a new entity. I was hoping JSON:API had a fix for this
- First commit to issue fork.
- 🇬🇧United Kingdom longwave UK
PathItemOverride is doing the opposite of what we think it's doing: ValidPath checks that the path is in use and will return a valid page instead of a 404. But when setting an alias we explicitly don't need or want that to happen!
It's not clear from commit history or comments exactly why this is here, so let's just remove it for now?
- 🇬🇧United Kingdom longwave UK
It's struck me that the intent of this is that the alias is a valid alias, rather than a path, so we can do that.
- 🇧🇪Belgium wim leers Ghent 🇧🇪🇪🇺
This is hard-blocking #3497530 — see #3497530-16: [PP-1] Implement the "Publish All" button → .
- 🇧🇪Belgium wim leers Ghent 🇧🇪🇪🇺
It's not clear from commit history or comments exactly why this is here, so let's just remove it for now?
😬🙈 That code dates back to the earliest XB days: https://wimleers.com/xb-week-5#chaos-origin — I know where to dig to answer that.
- 🇧🇪Belgium wim leers Ghent 🇧🇪🇪🇺
See how commit
eab37106
added this test expectation:'⿲sdc_test_all_props:all-props␟test-string-format-' . JsonSchemaStringFormat::URI_REFERENCE->value => [ 'storage' => $all_string_storage_props, 'format' => [ 'ℹ︎path␟alias', ], ],
(Which means the
path
field type'salias
property is a match.)This then evolved in subsequent commits to:
'optional, type=string&format=uri-reference' => [ 'component props' => [ '⿲sdc_test_all_props:all-props␟test_string_format_' . str_replace('-', '_', JsonSchemaStringFormat::URI_REFERENCE->value), ], 'storage' => $all_string_storage_props, 'format_any_prop' => [ 'ℹ︎path␟alias', ], 'format_main_prop' => [ 'ℹ︎path␟alias', ], 'instances' => [ 'ℹ︎␜entity:node:foo␝path␞␟alias', 'ℹ︎␜entity:path_alias␝path␞␟value', ], 'adapter_matches_field_type' => [], 'adapter_matches_instance' => [], ],
Which shows that it found actual
FieldConfig
s ("field instances") that provide this.It is 📌 Fix the visually broken "image" component instance: use FileUriItem's computed `url` property, not the stored `value` property Active that made the drastic change, from what's quoted above to:
'optional, type=string&format=uri-reference' => [ 'component props' => [ '⿲sdc_test_all_props:all-props␟test_string_format_' . str_replace('-', '_', JsonSchemaStringFormat::URI_REFERENCE->value), ], 'storage' => $all_string_storage_props, 'format_any_prop' => [ 'ℹ︎file_uri␟url', 'ℹ︎file_uri␟value', 'ℹ︎file␟entity␜␜entity:file␝uri␞0␟url', 'ℹ︎file␟entity␜␜entity:file␝uri␞0␟value', 'ℹ︎image␟entity␜␜entity:file␝uri␞0␟url', 'ℹ︎image␟entity␜␜entity:file␝uri␞0␟value', 'ℹ︎link␟uri', 'ℹ︎uri␟value', ], 'format_main_prop' => [ 'ℹ︎file_uri␟value', 'ℹ︎file␟entity␜␜entity:file␝uri␞0␟url', 'ℹ︎file␟entity␜␜entity:file␝uri␞0␟value', 'ℹ︎image␟entity␜␜entity:file␝uri␞0␟url', 'ℹ︎image␟entity␜␜entity:file␝uri␞0␟value', 'ℹ︎link␟uri', 'ℹ︎uri␟value', ], 'instances' => [ 'ℹ︎␜entity:file␝uri␞␟url', 'ℹ︎␜entity:file␝uri␞␟value', 'ℹ︎␜entity:node:foo␝field_silly_image␞␟entity␜␜entity:file␝uri␞␟url', 'ℹ︎␜entity:node:foo␝field_silly_image␞␟entity␜␜entity:file␝uri␞␟value', ], 'adapter_matches_field_type' => [], 'adapter_matches_instance' => [], ],
That's powered by this change in that commit:
// TRICKY: Drupal core does not support RFC3987 aka IRIs, but it's a superset of RFC3986. - static::URI, static::IRI => new DataTypeShapeRequirement('PrimitiveType', [], UriInterface::class), - // @todo Verify that \Drupal\Core\Path\Plugin\Validation\Constraint\ValidPathConstraintValidator matches this close enough. - static::URI_REFERENCE, static::IRI_REFERENCE => new DataTypeShapeRequirement('ValidPath', []), + static::URI_REFERENCE, static::URI, static::IRI, static::IRI_REFERENCE => new DataTypeShapeRequirement('PrimitiveType', [], UriInterface::class),
As of that moment, XB's
PathItemOverride
indeed became obsolete and should've been removed 🙈😬 -
wim leers →
committed 2756b20d on 0.x authored by
longwave →
Issue #3503347 by longwave, wim leers, bnjmnm, jessebaker, mglaman:...
-
wim leers →
committed 2756b20d on 0.x authored by
longwave →
- 🇧🇪Belgium wim leers Ghent 🇧🇪🇪🇺
@longwave in #10:
It's struck me that the intent of this is that the alias is a valid alias, rather than a path, so we can do that.
That was indeed the intent. And
static::URI_REFERENCE, static::URI, static::IRI, static::IRI_REFERENCE => new DataTypeShapeRequirement('PrimitiveType', [], UriInterface::class),
in
\Drupal\experience_builder\JsonSchemaInterpreter\JsonSchemaStringFormat::toDataTypeShapeRequirements()
is not actually validating that, because\Drupal\Core\Validation\Plugin\Validation\Constraint\PrimitiveTypeConstraintValidator::validate()
does this utterly baffling thing:// Ensure that URIs comply with http://tools.ietf.org/html/rfc3986, which // requires: // - That it is well formed (parse_url() returns FALSE if not). // - That it contains a scheme (parse_url(, PHP_URL_SCHEME) returns NULL if // not). if ($typed_data instanceof UriInterface && in_array(parse_url($value, PHP_URL_SCHEME), [NULL, FALSE], TRUE)) { $valid = FALSE; }
Essentially, what we need eventually, is better validation than that. More precise. But that's not an immediate concern.
So: could you please open a follow-up if you already were working on a solution for that? 🤓🙏