Skip to content

Commit 55471d1

Browse files
committed
feat: allow export/import media assets
1 parent 8cb5397 commit 55471d1

File tree

8 files changed

+701
-12
lines changed

8 files changed

+701
-12
lines changed

src/Exports/Exporters/BaseExporter.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ protected function zipTempFolder($folderName, bool $deleteFolder = true)
113113
FileHelper::buildZipFromFolder($folderFullPath, $zipFullPath);
114114

115115
if ($deleteFolder) {
116-
$folderDisk->deleteDirectory($folderPath);
116+
// $folderDisk->deleteDirectory($folderPath);
117117
}
118118

119119
return $zipPath;

src/Exports/Exporters/BaseImportUsedDataExporter.php

Lines changed: 65 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,24 @@
33
namespace SolutionForest\InspireCms\Exports\Exporters;
44

55
use Illuminate\Database\Eloquent\Model;
6+
use Illuminate\Support\Facades\Storage;
67
use Illuminate\Support\Str;
8+
use SolutionForest\InspireCms\Helpers\FileHelper;
79
use SolutionForest\InspireCms\Helpers\ImportDataHelper;
810
use SolutionForest\InspireCms\Helpers\TemplateHelper;
911
use SolutionForest\InspireCms\ImportData\Entities\Content as ImportEntitiesContent;
1012
use SolutionForest\InspireCms\ImportData\Entities\DocumentType as ImportEntitiesDocumentType;
1113
use SolutionForest\InspireCms\ImportData\Entities\FieldGroup as ImportEntitiesFieldGroup;
1214
use SolutionForest\InspireCms\ImportData\Entities\Language as ImportEntitiesLanguage;
15+
use SolutionForest\InspireCms\ImportData\Entities\MediaAsset as ImportEntitiesMediaAsset;
1316
use SolutionForest\InspireCms\ImportData\Entities\Navigation as ImportEntitiesNavigation;
1417
use SolutionForest\InspireCms\Models\Contracts\Content;
1518
use SolutionForest\InspireCms\Models\Contracts\DocumentType;
1619
use SolutionForest\InspireCms\Models\Contracts\FieldGroup;
1720
use SolutionForest\InspireCms\Models\Contracts\Language;
1821
use SolutionForest\InspireCms\Models\Contracts\Navigation;
1922
use SolutionForest\InspireCms\Models\Contracts\Template;
23+
use SolutionForest\InspireCms\Support\Models\Contracts\MediaAsset;
2024

2125
abstract class BaseImportUsedDataExporter extends BaseExporter
2226
{
@@ -37,6 +41,9 @@ protected function generateImportFileName(Model $record)
3741
case $record instanceof FieldGroup:
3842
return Str::replace('_', '-', $record->name) . '.json';
3943

44+
case $record instanceof MediaAsset:
45+
return $record->id . '.json';
46+
4047
case $record instanceof Template:
4148
if (is_array($record->content)) {
4249
$themes = array_keys($record->content);
@@ -71,13 +78,6 @@ protected function prepareImportContentFromModel(Model $record)
7178

7279
return json_encode($array, JSON_PRETTY_PRINT);
7380

74-
// case $record instanceof Template:
75-
// $themeContent = $record->content;
76-
// if (! is_array($themeContent)) {
77-
// $themeContent = [inspirecms_templates()->getCurrentTheme() => $themeContent];
78-
// }
79-
// return $themeContent;
80-
8181
case $record instanceof Content:
8282
$array = ImportEntitiesContent::fromRecord($record)->toArray();
8383

@@ -92,6 +92,11 @@ protected function prepareImportContentFromModel(Model $record)
9292
case $record instanceof Language:
9393
$array = ImportEntitiesLanguage::fromRecord($record)->toArray();
9494

95+
return json_encode($array, JSON_PRETTY_PRINT);
96+
97+
case $record instanceof MediaAsset:
98+
$array = ImportEntitiesMediaAsset::fromRecord($record)->toArray();
99+
95100
return json_encode($array, JSON_PRETTY_PRINT);
96101
}
97102

@@ -104,7 +109,7 @@ protected function processRecordForImportUsed(Model $record, $fs, ?string $dir,
104109

105110
$filename = $this->generateImportFileName($record);
106111

107-
if ($record instanceof Template && is_array($filename)) {
112+
if ($record instanceof Template && is_array(value: $filename)) {
108113

109114
foreach ($filename as $theme => $templateFilePath) {
110115

@@ -115,6 +120,52 @@ protected function processRecordForImportUsed(Model $record, $fs, ?string $dir,
115120
$fs->put($path, $templateContent);
116121
}
117122

123+
} elseif ($record instanceof MediaAsset) {
124+
125+
// Export the JSON metadata file
126+
$content = $this->prepareImportContentFromModel($record);
127+
$path = $dir . '/' . trim($filename, '/');
128+
$fs->put($path, $content);
129+
130+
// Handle media files
131+
try {
132+
$dto = ImportEntitiesMediaAsset::fromArray(json_decode($content, true));
133+
foreach ($dto->media_files as $item) {
134+
135+
$paths = $item['__exported_file_path'];
136+
137+
if (!is_array($paths) || empty($paths)) {
138+
continue;
139+
}
140+
141+
foreach ($paths as $key => $value) {
142+
try {
143+
144+
$tmpMediaFilePath = collect([$dir, $value])->map(fn ($path) => trim($path, '/'))->implode('/');
145+
146+
// Ensure the directory exists
147+
if (! $fs->exists(dirname($tmpMediaFilePath))) {
148+
149+
$fs->makeDirectory(dirname($tmpMediaFilePath), 0777, true);
150+
}
151+
152+
$mediaFileContent = ($key == '__real__' ? Storage::disk($record->disk) : Storage::disk($record->conversions_disk))->get($value);
153+
154+
$fs->put($tmpMediaFilePath, $mediaFileContent);
155+
156+
} catch (\Throwable $th) {
157+
// Skip error, handle next file
158+
}
159+
}
160+
}
161+
} catch (\Throwable $th) {
162+
$errors[] = [
163+
'record' => $record->getKey(),
164+
'model' => get_class($record),
165+
'message' => $th->getMessage(),
166+
];
167+
}
168+
118169
} elseif (! is_string($filename)) {
119170
$errors[] = [
120171
'record' => $record->getKey(),
@@ -173,6 +224,12 @@ protected function buildExportingQueryForImportUsed($query, $type)
173224

174225
case ImportDataHelper::FOLDER_IDENTIFIER_TEMPLATE:
175226
return $query;
227+
228+
case ImportDataHelper::FOLDER_IDENTIFIER_MEDIAASSET:
229+
return $query->with([
230+
// 'parent',
231+
'nestableTree',
232+
]);
176233
}
177234

178235
return $query;

src/Exports/Exporters/ImportUsedExporter.php

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use SolutionForest\InspireCms\Models\Contracts\FieldGroup;
1616
use SolutionForest\InspireCms\Models\Contracts\Navigation;
1717
use SolutionForest\InspireCms\Models\Contracts\Template;
18+
use SolutionForest\InspireCms\Support\Models\Contracts\MediaAsset;
1819

1920
class ImportUsedExporter extends BaseImportUsedDataExporter
2021
{
@@ -168,6 +169,7 @@ protected static function getFilterRecordKeyFor(string $type)
168169
ImportDataHelper::FOLDER_IDENTIFIER_TEMPLATE => 'template',
169170
ImportDataHelper::FOLDER_IDENTIFIER_CONTENT => 'content',
170171
ImportDataHelper::FOLDER_IDENTIFIER_NAVIGATION => 'navigation',
172+
ImportDataHelper::FOLDER_IDENTIFIER_MEDIAASSET => 'media_asset',
171173
default => str($type)->snake()->toString(),
172174
};
173175

@@ -209,6 +211,8 @@ private static function buildOptionsFor(string $type, $records)
209211
$label = $record->title;
210212
} elseif ($record instanceof Navigation) {
211213
$label = "{$record->title} ({$record->type})";
214+
} elseif ($record instanceof MediaAsset) {
215+
$label = $record->title . ($record->is_folder ? ' (folder)' : '');
212216
}
213217

214218
$results[$key] = $label ?? $key;
@@ -242,6 +246,8 @@ private static function buildOptionDescriptionsFor(string $type, $records)
242246
$label = $record->slug;
243247
} elseif ($record instanceof Navigation) {
244248
$label = "{$record->category}";
249+
} elseif ($record instanceof MediaAsset) {
250+
$label = $record->id . ($record->is_folder ? ' (folder)' : '');
245251
}
246252

247253
$results[$key] = $label ?? $key;
@@ -263,11 +269,17 @@ protected static function getBaseQueryForModel(string $type)
263269
ImportDataHelper::FOLDER_IDENTIFIER_CONTENT => InspireCmsConfig::getContentModelClass(),
264270
ImportDataHelper::FOLDER_IDENTIFIER_NAVIGATION => InspireCmsConfig::getNavigationModelClass(),
265271
ImportDataHelper::FOLDER_IDENTIFIER_LANGUAGE => InspireCmsConfig::getLanguageModelClass(),
272+
ImportDataHelper::FOLDER_IDENTIFIER_MEDIAASSET => InspireCmsConfig::getMediaAssetModelClass()::with('media'),
266273
default => null,
267274
};
268275

269-
if ($model && is_a($model, Model::class, true)) {
270-
return $model::query();
276+
if ($model) {
277+
if (is_a($model, Model::class, true)) {
278+
return $model::query();
279+
}
280+
else if (is_a($model, \Illuminate\Database\Eloquent\Builder::class, true)) {
281+
return $model;
282+
}
271283
}
272284

273285
return null;

src/Helpers/ImportDataHelper.php

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class ImportDataHelper
2828
self::FOLDER_IDENTIFIER_FIELDGROUP,
2929
self::FOLDER_IDENTIFIER_NAVIGATION,
3030
self::FOLDER_IDENTIFIER_LANGUAGE,
31+
self::FOLDER_IDENTIFIER_MEDIAASSET,
3132
...self::FOLDER_HAS_VIEWS,
3233
];
3334

@@ -46,6 +47,8 @@ class ImportDataHelper
4647

4748
const FOLDER_IDENTIFIER_LANGUAGE = 'Languages';
4849

50+
const FOLDER_IDENTIFIER_MEDIAASSET = 'MediaAssets';
51+
4952
const FOLDER_IDENTIFIER_TEMPLATE = 'Templates';
5053

5154
const FOLDER_IDENTIFIER_VIEW = 'Views';
@@ -152,6 +155,7 @@ public static function generateSampleData()
152155
self::FOLDER_IDENTIFIER_DOCUMENTTYPE => collect(range(1, 4))->map(fn ($i) => "document-type-{$i}.json")->all(),
153156
self::FOLDER_IDENTIFIER_CONTENT => collect(range(1, 1))->map(fn ($i) => "content-{$i}.json")->all(),
154157
self::FOLDER_IDENTIFIER_NAVIGATION => collect(range(1, 2))->map(fn ($i) => "navigation-{$i}.json")->all(),
158+
self::FOLDER_IDENTIFIER_MEDIAASSET => collect(range(1, 3))->map(fn ($i) => "media-asset-{$i}.json")->all(),
155159
];
156160
$data = [];
157161

@@ -363,6 +367,39 @@ public static function generateSampleData()
363367
->all();
364368

365369
break;
370+
371+
case self::FOLDER_IDENTIFIER_MEDIAASSET:
372+
373+
$sequence = collect([
374+
[
375+
'title' => 'Sample Image 1',
376+
'is_folder' => false,
377+
'caption' => 'A sample image for testing',
378+
'description' => 'This is a sample image used for testing media import/export',
379+
'parent_id' => null,
380+
],
381+
[
382+
'title' => 'Sample Document',
383+
'is_folder' => false,
384+
'caption' => 'Sample PDF document',
385+
'description' => 'A sample PDF document for testing',
386+
'parent_id' => null,
387+
],
388+
[
389+
'title' => 'Media Folder',
390+
'is_folder' => true,
391+
'caption' => null,
392+
'description' => 'A sample media folder',
393+
'parent_id' => null,
394+
],
395+
])
396+
->map(fn (array $item) => array_merge($item, [
397+
'id' => Str::uuid()->toString(),
398+
'nestable_id' => rand(1000, 9999),
399+
]))
400+
->all();
401+
402+
break;
366403
}
367404

368405
$targetSequenceIndex = $index === 0 ? $index : $index % count($sequence);

0 commit comments

Comments
 (0)