Issue #3614227: A venue package does not round-trip: export drops zones, modes, subsections and configurations

The bug

Exporting a venue and importing it back did not give you the venue you exported, and said nothing about it. Verified on both sides:

  • VenueExporter::exportBand() wrote only key, label and weight for a section, so map_element (its clickable zone on the plan) and default_mode (how it is normally sold) never left;
  • VenueImporter::createBand() was called with an empty extra-field list for sections, so even a manifest carrying those keys by hand was ignored;
  • exportPlaces() omitted subsection, which is what lets a configuration close or pool part of an area, and weight.

Build a hall, set its zones and modes, export, re-import: 1,422 seats you cannot sell the way you sold them, with nothing in the manifest or the command output to say so.

What this does

Carries the layout in full. Sections gain map_element and default_mode, places gain subsection and weight, in both directions. Manifest version goes to 2; a version 1 package still imports, because every new key is optional and its absence means what it always meant.

Written only when the entity has a value, so a venue that names no zones and overrides no modes exports exactly the manifest it did before. That is what keeps the bundled Auditorium example and the existing round-trip assertions unchanged.

exportBand()'s bool $with_color became a string[] $extra, since it now has two callers wanting different sets. That removed the instanceof GradeInterface special case as well.

Configurations stay out, and the command now says so

This takes the middle option from the issue. A configuration decides how a hall is opened for a given event rather than what the hall is, and it references slots and categories from outside the venue, so it is not layout and does not belong in a venue package.

But silence was half the bug, so yoyaku:venue-export now counts the venue's configurations and warns when there are any, naming what a re-import will not restore. The person who will rely on that file to rebuild a hall is standing right there when it is written.

A shadowing bug fixed in passing

createPlaces() did $place = $place['place'] ?? ..., overwriting the row array with a string, and the next line read $place['label'] off that string. Harmless today only because the place entity has no label field, so the branch never runs. The printed number now lives in its own variable.

Tests

testTheLayoutSurvivesTheRoundTrip imports a manifest with zones, a default mode and subsections, asserts them on the entities (so it fails whether the importer ignored them or the exporter forgot them), then exports and asserts the values come back with nothing invented for the areas and places that never had them.

Confirmed to fail against the unfixed source: Failed asserting that null is identical to 'orchestre-zone'.

Docs

The io README documents the new keys and gains a section on what a package does not carry. docs/venue-map.md had warned that zones, modes and subsections were lost; that paragraph is now down to configurations alone, which is the part that is still true.

Verification

VenueIoTest green, phpcs and cspell clean over the module (with --standard=Drupal,DrupalPractice, since the repo-local phpcs config excludes contrib and inspects nothing). Full suite left to CI. No new translatable strings in the module; the drush message uses dt() like its neighbors, so fr.po is unchanged.

Merge request reports

Loading
Loading