diff --git a/README.md b/README.md index 522af20..2157513 100644 --- a/README.md +++ b/README.md @@ -170,6 +170,7 @@ ddev craft wp-import --help - Radio Button - Range - Relationship +- Repeater - Select - Tab - Taxonomy diff --git a/src/Command.php b/src/Command.php index 4e24e9f..1b60db0 100644 --- a/src/Command.php +++ b/src/Command.php @@ -397,6 +397,15 @@ public function acfLayoutTabsForEntity(string $type, string $name, FieldLayout $ return $tabs; } + public function fieldsForEntity(string $type, string $name): array + { + $acfFields = []; + foreach ($this->fieldGroupsForEntity($type, $name) as $groupData) { + $acfFields = array_merge($acfFields, $groupData['fields']); + } + return $acfFields; + } + private function fieldGroupsForEntity(string $type, string $name): Generator { foreach ($this->wpInfo['field_groups'] as $groupData) { @@ -427,7 +436,7 @@ private function locationMatchesRules(string $type, string $name, array $rules): return false; } - private function acfFieldElements(array $fields): array + public function acfFieldElements(array $fields): array { return Collection::make($fields) ->map(fn(array $fieldData) => match($fieldData['type']) { @@ -501,18 +510,7 @@ private function acfAdapter(array $data): BaseAcfAdapter return $this->acfAdapters[$data['type']]; } - public function prepareAcfFieldValues(string $type, string $slug, array $acfValues): array - { - // get all the fields from all matching field groups - $acfFields = []; - foreach ($this->fieldGroupsForEntity($type, $slug) as $groupData) { - $acfFields = array_merge($acfFields, $groupData['fields']); - } - - return $this->prepareAcfFieldValuesInternal($acfFields, $acfValues); - } - - private function prepareAcfFieldValuesInternal(array $acfFields, array $acfValues): array + public function prepareAcfFieldValues(array $acfFields, array $acfValues): array { $fieldValues = []; @@ -529,7 +527,7 @@ private function prepareAcfFieldValuesInternal(array $acfFields, array $acfValue if ($fieldData['type'] === 'group') { $fieldValues = array_merge( $fieldValues, - $this->prepareAcfFieldValuesInternal($fieldData['sub_fields'], is_array($fieldValue) ? $fieldValue : []), + $this->prepareAcfFieldValues($fieldData['sub_fields'], is_array($fieldValue) ? $fieldValue : []), ); } else { $handle = $this->normalizeAcfFieldHandle($fieldName); diff --git a/src/acfadapters/Repeater.php b/src/acfadapters/Repeater.php new file mode 100644 index 0000000..4d31c2d --- /dev/null +++ b/src/acfadapters/Repeater.php @@ -0,0 +1,87 @@ + + */ +class Repeater extends BaseAcfAdapter +{ + public static function type(): string + { + return 'repeater'; + } + + public function create(array $data): FieldInterface + { + $entryType = $this->entryType($data); + $field = new Matrix(); + $field->setEntryTypes([$entryType]); + $field->viewMode = $data['pagination'] ? Matrix::VIEW_MODE_INDEX : Matrix::VIEW_MODE_BLOCKS; + if ($data['min']) { + $field->minEntries = $data['min']; + } + if ($data['max']) { + $field->maxEntries = $data['max']; + } + if ($data['button_label'] && $data['button_label'] !== 'Add Row') { + $field->createButtonLabel = $data['button_label']; + } + return $field; + } + + private function entryType(array $data): EntryType + { + $entryTypeHandle = sprintf('acf_%s_%s', StringHelper::toHandle($data['name']), $data['ID']); + $entryType = Craft::$app->entries->getEntryTypeByHandle($entryTypeHandle); + if ($entryType) { + return $entryType; + } + + $entryType = new EntryType(); + $entryType->name = $data['label'] ?: "Untitled ACF Field {$data['ID']}"; + $entryType->handle = $entryTypeHandle; + + $fieldLayout = new FieldLayout(); + $fieldLayout->setTabs([ + new FieldLayoutTab([ + 'layout' => $fieldLayout, + 'name' => 'Content', + 'elements' => $this->command->acfFieldElements($data['sub_fields']), + ]), + ]); + $entryType->setFieldLayout($fieldLayout); + + $this->command->do("Creating `$entryType->name` entry type", function() use ($entryType) { + if (!Craft::$app->entries->saveEntryType($entryType)) { + throw new Exception(implode(', ', $entryType->getFirstErrors())); + } + }); + + return $entryType; + } + + public function normalizeValue(mixed $value, array $data): mixed + { + $entryType = $this->entryType($data); + return array_map(fn(array $row) => [ + 'type' => $entryType->handle, + 'fields' => $this->command->prepareAcfFieldValues($data['sub_fields'], $row), + ], $value); + } +} diff --git a/src/importers/PostType.php b/src/importers/PostType.php index aae9f99..464df89 100644 --- a/src/importers/PostType.php +++ b/src/importers/PostType.php @@ -148,10 +148,10 @@ public function populate(ElementInterface $element, array $data): void } if (!empty($data['acf'])) { - $fieldValues = array_merge( - $fieldValues, - $this->command->prepareAcfFieldValues('post_type', $this->slug(), $data['acf']), - ); + $fieldValues = array_merge($fieldValues, $this->command->prepareAcfFieldValues( + $this->command->fieldsForEntity('post_type', $this->slug()), + $data['acf'], + )); } foreach ($fieldValues as $handle => $value) { diff --git a/src/importers/Taxonomy.php b/src/importers/Taxonomy.php index c8a4b67..4bc94b9 100644 --- a/src/importers/Taxonomy.php +++ b/src/importers/Taxonomy.php @@ -76,10 +76,10 @@ public function populate(ElementInterface $element, array $data): void ]; if (!empty($data['acf'])) { - $fieldValues = array_merge( - $fieldValues, - $this->command->prepareAcfFieldValues('taxonomy', $this->slug(), $data['acf']), - ); + $fieldValues = array_merge($fieldValues, $this->command->prepareAcfFieldValues( + $this->command->fieldsForEntity('taxonomy', $this->slug()), + $data['acf'], + )); } foreach ($fieldValues as $handle => $value) {