Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions MIGRATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ You can also pass a `Collection` instance built with `Collection::from_sprite()`

| Old (`icon-item` / legacy parent) | New (`blockparty/icon`) |
|---|---|
| `icon` (`name`, `type`, `label`, optional `collection`) | `icon` (requires `collection` + `name`) |
| `icon` (`name`, `type`, `label`, optional `collection`) | `icon` (`collection` + `name`; collection is looked up / fallen back when missing) |
| Parent `collection.name` (legacy object) | `icon.collection` |
| `iconColorValue` / legacy `iconColor.color` | `iconColor` (value kept as-is, including `inherit`) |
| `size` (int) | `size` (int) |
Expand Down Expand Up @@ -98,7 +98,7 @@ The command:
4. Logs migrated / skipped counts
5. Lists missing icon assets (`collection/name`) so you can add them manually to theme assets / collections

When `collection` is missing on the icon object (and not on the parent attrs), the block is skipped — there is no default collection. Missing files among converted icons are reported, not skipped.
When `collection` is missing on the icon object (and not on the parent attrs) but `name` is present, the migrator looks up that name in registered collections (preferred order: `icon-pack`, `theme`, `mediatheque`, then the rest). If still unresolved, it falls back to `mediatheque` for `raw` icons and `icon-pack` otherwise (`sprite` is inferred from `<use>` in the saved HTML when `type` is absent). The block is skipped only when `name` (or collection after these steps) is still missing. Missing files among converted icons are reported as CLI warnings, not skipped.

### Revisions

Expand Down
63 changes: 58 additions & 5 deletions includes/Migration/IconBlockMigrator.php
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ private function convert_old_block( array $block ): array {
* @param array $attrs Source attrs (item or legacy parent).
* @param array $parent_attrs Parent attrs (for className / collection).
* @param string $html Saved HTML of the old block.
* @return array|null Null when an icon was expected but name or collection is missing.
* @return array|null Null when an icon was expected but name or collection is still missing after lookup/fallback.
* @author Jules Fell
*/
private function build_blockparty_block( array $attrs, array $parent_attrs, string $html ): ?array {
Expand All @@ -222,23 +222,33 @@ private function build_blockparty_block( array $attrs, array $parent_attrs, stri
// empty shells must become empty blockparty/icon blocks.
$expects_icon = ( '' !== $name || $old_icon );

// Collection from attrs only (no registry lookup, no project-specific default).
$type = (string) ( $old_icon['type'] ?? ( false !== strpos( $html, '<use' ) ? 'sprite' : 'raw' ) );

// Collection from icon attrs, then parent/item attrs.
$collection = (string) ( $old_icon['collection'] ?? '' );
if ( '' === $collection ) {
$raw = $attrs['collection'] ?? $parent_attrs['collection'] ?? null;
$collection = is_array( $raw ) ? (string) ( $raw['name'] ?? '' ) : (string) $raw;
}

// Abort when we expected an icon but name or collection is missing.
// Registry lookup when name is known but collection was never stored.
if ( '' === $collection && '' !== $name ) {
$collection = $this->resolve_collection_for_icon( $name );
}

// Last resort: frequent BeAPI collection names (not project-specific).
if ( '' === $collection && '' !== $name ) {
$collection = 'raw' === $type ? 'mediatheque' : 'icon-pack';
}

// Abort only when an icon was expected but name or collection is still missing.
if ( $expects_icon && ( '' === $name || '' === $collection ) ) {
return null;
}

$new = [];

if ( '' !== $name ) {
$type = (string) ( $old_icon['type'] ?? ( false !== strpos( $html, '<use' ) ? 'sprite' : 'raw' ) );

$new['icon'] = [
'collection' => $collection,
'name' => $name,
Expand Down Expand Up @@ -326,6 +336,49 @@ private function build_blockparty_block( array $attrs, array $parent_attrs, stri
];
}

/**
* Find the first registered collection that contains the given icon name.
*
* Preferred order: icon-pack, theme, mediatheque, then remaining collections.
*
* @param string $name Icon name.
* @return string Collection name, or empty string if none match.
*/
private function resolve_collection_for_icon( string $name ): string {
if ( ! function_exists( '\\Blockparty\\Icons\\get_icon_collections' ) ) {
return '';
}

$collections = \Blockparty\Icons\get_icon_collections();
if ( empty( $collections ) ) {
return '';
}

$preferred = [ 'icon-pack', 'theme', 'mediatheque' ];
$ordered = [];

foreach ( $preferred as $preferred_name ) {
if ( isset( $collections[ $preferred_name ] ) ) {
$ordered[] = $collections[ $preferred_name ];
}
}

foreach ( $collections as $collection_name => $collection ) {
if ( in_array( $collection_name, $preferred, true ) ) {
continue;
}
$ordered[] = $collection;
}

foreach ( $ordered as $collection ) {
if ( $collection->get( $name ) ) {
return $collection->name();
}
}

return '';
}

/**
* Record a migrated icon that is not available in registered collections.
*
Expand Down
Loading