Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into fix/updating-bard-con…
Browse files Browse the repository at this point in the history
…figs-in-fieldsets
  • Loading branch information
duncanmcclean committed Nov 12, 2024
2 parents 885eb55 + dc44d69 commit 9691e27
Show file tree
Hide file tree
Showing 17 changed files with 264 additions and 70 deletions.
11 changes: 10 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
# Changelog

### 1.1.2 (2024-11-06)
## 1.2.0 (2024-11-08)

### What's new
* UX Improvements #24 by @duncanmcclean
* Added "CSV Delimiter" option #29 by @duncanmcclean
* You can now import publish states (& toggle fields) #30 by @duncanmcclean



## 1.1.2 (2024-11-06)

### What's fixed
* Fixed validation error when creating an import in a multi-site #27 by @duncanmcclean
Expand Down
5 changes: 4 additions & 1 deletion DOCUMENTATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,12 +137,15 @@ The importer includes a few transformers out of the box for Core fieldtypes, but
use App\ImportTransformers\YourTransformer;
use Illuminate\Support\ServiceProvider;
use Statamic\Importer\Importer;
use Statamic\Statamic;

class AppServiceProvider extends ServiceProvider
{
public function boot(): void
{
Importer::registerTransformer('fieldtype', YourTransformer::class);
Statamic::booted(function () {
Importer::registerTransformer('fieldtype', YourTransformer::class);
});
}
}
```
Expand Down
10 changes: 0 additions & 10 deletions resources/js/components/EditImportForm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -72,16 +72,6 @@ export default {
}
},
computed: {
hasErrors() {
return this.error || Object.keys(this.errors).length;
},
isDirty() {
return this.$dirty.has(this.publishContainer);
},
},
mounted() {
this.quickSaveKeyBinding = this.$keys.bindGlobal(['mod+s'], e => {
e.preventDefault();
Expand Down
20 changes: 10 additions & 10 deletions resources/js/components/Fieldtypes/ImportMappingsFieldtype.vue
Original file line number Diff line number Diff line change
Expand Up @@ -46,18 +46,18 @@
</template>

<style>
.field-mappings-table .form-group {
padding-top: 16px;
padding-bottom: 16px;
}
.field-mappings-table .form-group {
padding-top: 16px;
padding-bottom: 16px;
}
.field-mappings-table .form-group:first-child {
padding-top: 0;
}
.field-mappings-table .form-group:first-child {
padding-top: 0;
}
.field-mappings-table .form-group:last-child {
padding-bottom: 0;
}
.field-mappings-table .form-group:last-child {
padding-bottom: 0;
}
</style>

<script>
Expand Down
19 changes: 8 additions & 11 deletions src/Fieldtypes/ImportMappingsFieldtype.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public function preload()
{
return [
'fields' => $this->fields()->map(function (Fields $fields, string $handle) {
$field = $this->field()->parent()->destinationBlueprint()->field($handle);
$field = $this->field()->parent()->mappingFields()->get($handle);

return [
'type' => $field->type(),
Expand All @@ -39,9 +39,7 @@ public function preload()
public function preProcess($data): array
{
return $this->fields()->map(function (Fields $fields, string $handle) use ($data) {
$field = $this->field()->parent()->destinationBlueprint()->field($handle);

return $fields->addValues(Arr::get($data, $field->handle(), []))->preProcess()->values()->all();
return $fields->addValues(Arr::get($data, $handle, []))->preProcess()->values()->all();
})->all();
}

Expand Down Expand Up @@ -90,18 +88,17 @@ private function fields(): Collection
$import = $this->field()->parent();

$row = match ($import->get('type')) {
'csv' => (new Csv($import))->getItems($import->get('path'), [])->first(),
'xml' => (new Xml($import))->getItems($import->get('path'), [])->first(),
'csv' => (new Csv($import))->getItems($import->get('path'))->first(),
'xml' => (new Xml($import))->getItems($import->get('path'))->first(),
};

return $import->destinationBlueprint()->fields()->all()
return $import->mappingFields()->all()
->reject(function (Field $field) {
$transformer = Importer::getTransformer($field->type());

return in_array($field->type(), ['section', 'grid', 'replicator', 'group'])
&& ! $transformer;
return in_array($field->type(), ['section', 'grid', 'replicator', 'group', 'array']) && ! $transformer;
})
->mapWithKeys(function (Field $field) use ($row) {
->mapWithKeys(function (Field $field) use ($import, $row) {
$fields = [];

if ($transformer = Importer::getTransformer($field->type())) {
Expand All @@ -119,7 +116,7 @@ private function fields(): Collection
'clearable' => true,
],
...$fields,
])->setHandle('mappings-'.$field->handle());
])->setHandle("import-mappings-{$field->handle()}".md5($import->config()->toJson()));

return [$field->handle() => $blueprint->fields()];
});
Expand Down
10 changes: 8 additions & 2 deletions src/Http/Controllers/ExtractFromImportFields.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,15 @@

trait ExtractFromImportFields
{
protected function extractFromFields($import, $fields)
protected function extractFromFields($import, $blueprint)
{
$fields = $fields->preProcess();
$fields = $blueprint
->fields()
->setParent($import)
->addValues($import->config()->merge([
'name' => $import->name(),
])->all())
->preProcess();

$values = $fields->values();

Expand Down
3 changes: 2 additions & 1 deletion src/Http/Controllers/ImportController.php
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ public function update(Request $request, Import $import)
'path' => $path,
'destination' => collect($values['destination'])->filter()->all(),
'strategy' => $values['strategy'],
'source' => $values['source'],
'mappings' => $values['mappings'],
'unique_field' => $values['unique_field'],
]));
Expand All @@ -185,7 +186,7 @@ public function update(Request $request, Import $import)
// We need to refresh the blueprint after saving, so the field conditions are up-to-date.
$blueprint = $import->blueprint();

[$values, $meta] = $this->extractFromFields($import, $fields);
[$values, $meta] = $this->extractFromFields($import, $blueprint);

return [
'data' => array_merge((new ImportResource($import->fresh()))->resolve()['data'], [
Expand Down
32 changes: 31 additions & 1 deletion src/Imports/Blueprint.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
use Statamic\Facades;
use Statamic\Facades\Collection;
use Statamic\Facades\Site;
use Statamic\Importer\Sources\Csv;
use Statamic\Importer\Sources\Xml;

class Blueprint
{
Expand Down Expand Up @@ -78,7 +80,7 @@ function (string $attribute, mixed $value, Closure $fail) {
'field' => [
'type' => 'button_group',
'display' => __('Data Type'),
'instructions' => __('Choose what type of data are you importing'),
'instructions' => __('Choose what type of data are you importing.'),
'width' => 50,
'options' => [
['key' => 'entries', 'value' => __('Entries')],
Expand Down Expand Up @@ -159,6 +161,7 @@ function (string $attribute, mixed $value, Closure $fail) {
'display' => __('Configuration'),
'instructions' => __('importer::messages.configuration_instructions'),
'fields' => [
...static::getSourceFields($import),
[
'handle' => 'mappings',
'field' => [
Expand Down Expand Up @@ -206,6 +209,33 @@ function (string $attribute, mixed $value, Closure $fail) {
]);
}

private static function getSourceFields(?Import $import = null): array
{
if (! $import) {
return [];
}

$fields = match ($import->get('type')) {
'csv' => (new Csv($import))->fields(),
'xml' => (new Xml($import))->fields(),
};

if ($fields->items()->isEmpty()) {
return [];
}

return [[
'handle' => 'source',
'field' => [
'type' => 'group',
'hide_display' => true,
'fullscreen' => false,
'border' => false,
'fields' => $fields->items()->all(),
],
]];
}

private static function buildFieldConditions(Import $import): array
{
$conditions = [
Expand Down
38 changes: 28 additions & 10 deletions src/Imports/Import.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
use Statamic\Facades\Collection;
use Statamic\Facades\Taxonomy;
use Statamic\Facades\User;
use Statamic\Fields\Blueprint as StatamicBlueprint;
use Statamic\Fields\Fields;
use Statamic\Importer\Facades\Import as ImportFacade;
use Statamic\Importer\Importer;
use Statamic\Support\Traits\FluentlyGetsAndSets;
Expand Down Expand Up @@ -124,23 +126,39 @@ public function deleteUrl(): string
return cp_route('utilities.importer.destroy', $this->id());
}

public function blueprint(): \Statamic\Fields\Blueprint
public function blueprint(): StatamicBlueprint
{
return Blueprint::getBlueprint($this);
}

public function destinationBlueprint(): \Statamic\Fields\Blueprint
/**
* Returns the blueprint of the destination collection, taxonomy, or user.
*/
public function destinationBlueprint(): StatamicBlueprint
{
if ($this->get('destination.type') === 'entries') {
return Collection::find($this->get('destination.collection'))->entryBlueprint();
}
return match ($this->get('destination.type')) {
'entries' => Collection::find($this->get('destination.collection'))->entryBlueprint(),
'terms' => Taxonomy::find($this->get('destination.taxonomy'))->termBlueprint(),
'users' => User::blueprint(),
};
}

if ($this->get('destination.type') === 'terms') {
return Taxonomy::find($this->get('destination.taxonomy'))->termBlueprint();
}
/**
* Returns a Fields instance of the fields available for mapping.
* Sometimes, additional fields will be appended, like "Published" for
* entries, which doesn't exist as a blueprint field.
*/
public function mappingFields(): Fields
{
$blueprint = clone $this->destinationBlueprint();

if ($this->get('destination.type') === 'users') {
return User::blueprint();
if ($this->get('destination.type') === 'entries') {
$blueprint->ensureField('published', [
'type' => 'toggle',
'display' => __('Published'),
]);
}

return $blueprint->fields();
}
}
26 changes: 5 additions & 21 deletions src/Jobs/ImportItemJob.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,8 @@
use Statamic\Facades\Collection;
use Statamic\Facades\Entry;
use Statamic\Facades\Site;
use Statamic\Facades\Taxonomy;
use Statamic\Facades\Term;
use Statamic\Facades\User;
use Statamic\Fields\Blueprint;
use Statamic\Importer\Importer;
use Statamic\Importer\Imports\Import;

Expand All @@ -29,13 +27,14 @@ public function __construct(public Import $import, public array $item) {}

public function handle(): void
{
$blueprint = $this->getBlueprint();
$fields = $this->import->mappingFields();
$blueprint = $this->import->destinationBlueprint();

$data = collect($this->import->get('mappings'))
->reject(fn (array $mapping) => empty($mapping['key']))
->mapWithKeys(function (array $mapping, string $fieldHandle) use ($blueprint) {
->mapWithKeys(function (array $mapping, string $fieldHandle) use ($fields, $blueprint) {
$field = $fields->get($fieldHandle);
$value = Arr::get($this->item, $mapping['key']);
$field = $blueprint->field($fieldHandle);

if (! $value) {
return [$fieldHandle => null];
Expand All @@ -47,7 +46,7 @@ public function handle(): void

return [$fieldHandle => $value];
})
->filter()
->reject(fn ($value) => is_null($value))
->all();

match ($this->import->get('destination.type')) {
Expand All @@ -57,21 +56,6 @@ public function handle(): void
};
}

protected function getBlueprint(): Blueprint
{
if ($this->import->get('destination.type') === 'entries') {
return Collection::find($this->import->get('destination.collection'))->entryBlueprint();
}

if ($this->import->get('destination.type') === 'terms') {
return Taxonomy::find($this->import->get('destination.taxonomy'))->termBlueprint();
}

if ($this->import->get('destination.type') === 'users') {
return User::blueprint();
}
}

protected function findOrCreateEntry(array $data): void
{
$collection = Collection::find($this->import->get('destination.collection'));
Expand Down
1 change: 1 addition & 0 deletions src/ServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ class ServiceProvider extends AddonServiceProvider
'date' => Transformers\DateTransformer::class,
'entries' => Transformers\EntriesTransformer::class,
'terms' => Transformers\TermsTransformer::class,
'toggle' => Transformers\ToggleTransformer::class,
'users' => Transformers\UsersTransformer::class,
];

Expand Down
21 changes: 21 additions & 0 deletions src/Sources/AbstractSource.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,31 @@

namespace Statamic\Importer\Sources;

use Illuminate\Support\Arr;
use Illuminate\Support\LazyCollection;
use Statamic\Extend\HasFields;
use Statamic\Importer\Contracts\Source;
use Statamic\Importer\Imports\Import;

abstract class AbstractSource implements Source
{
use HasFields;

public function __construct(public ?Import $import = null) {}

abstract public function getItems(string $path): LazyCollection;

public function fieldItems(): array
{
return [];
}

protected function config(?string $key = null, $default = null): mixed
{
if (is_null($key)) {
return collect($this->import->get('source'));
}

return Arr::get($this->import->get('source'), $key, $default);
}
}
Loading

0 comments on commit 9691e27

Please sign in to comment.