Skip to content

Commit 25e1bbd

Browse files
committed
better dispatch of conversions
1 parent 0467634 commit 25e1bbd

File tree

7 files changed

+98
-48
lines changed

7 files changed

+98
-48
lines changed

src/Commands/GenerateMediaConversionsCommand.php

Lines changed: 35 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
use Elegantly\Media\Models\Media;
66
use Illuminate\Console\Command;
77
use Illuminate\Database\Eloquent\Builder;
8-
use Illuminate\Database\Eloquent\Collection;
8+
use Laravel\Prompts\Progress;
99

1010
use function Laravel\Prompts\confirm;
1111

@@ -22,50 +22,59 @@ public function handle(): int
2222
$pretend = (bool) $this->option('pretend');
2323
/** @var string[] $conversions */
2424
$conversions = (array) $this->option('conversions');
25+
/** @var string[] $models */
2526
$models = (array) $this->option('models');
27+
/** @var string[] $collections */
2628
$collections = (array) $this->option('collections');
2729

2830
/**
2931
* @var class-string<Media> $model
3032
*/
3133
$model = config('media.model');
3234

33-
/** @var Collection<int, Media> */
34-
$media = $model::query()
35+
$query = $model::query()
3536
->with(['model', 'conversions'])
3637
->when(! empty($ids), fn (Builder $query) => $query->whereIn('id', $ids))
3738
->when(! empty($models), fn (Builder $query) => $query->whereIn('model_type', $models))
38-
->when(! empty($collections), fn (Builder $query) => $query->whereIn('collection_name', $collections))
39-
->get();
40-
41-
$mediaByModel = $media->countBy('model_type');
42-
43-
$this->table(
44-
['Model', 'Count'],
45-
$mediaByModel->map(function (int $count, ?string $model_type) {
46-
return [
47-
$model_type,
48-
$count,
49-
];
50-
})
51-
);
52-
53-
if ($pretend || ! confirm('Continue?')) {
39+
->when(! empty($collections), fn (Builder $query) => $query->whereIn('collection_name', $collections));
40+
41+
$count = $query->count();
42+
43+
if ($pretend || ! confirm("{$count} Media found. Continue?")) {
5444
return self::SUCCESS;
5545
}
5646

57-
$this->withProgressBar($media, function (Media $media) use ($conversions, $force) {
47+
$progress = new Progress('Dispatching Media conversions', $count);
48+
49+
$query->chunkById(5_000, function ($items) use ($progress, $force, $conversions) {
5850

59-
$conversions = empty($conversions) ? array_keys($media->getConversionsDefinitions()) : $conversions;
51+
foreach ($items as $media) {
6052

61-
foreach ($conversions as $name) {
62-
$conversion = $media->getConversion((string) $name);
53+
$media->dispatchConversions(
54+
queued: true,
55+
filter: function ($definition) use ($media, $force, $conversions) {
6356

64-
if ($force || ! $conversion) {
65-
$media->dispatchConversion($name);
66-
}
57+
if (
58+
! empty($conversions) &&
59+
! in_array($definition->name, $conversions)
60+
) {
61+
return false;
62+
}
6763

64+
if (
65+
! $force &&
66+
$media->hasConversion($definition->name)
67+
) {
68+
return false;
69+
}
70+
71+
return true;
72+
}
73+
);
74+
75+
$progress->advance();
6876
}
77+
6978
});
7079

7180
return self::SUCCESS;

src/Concerns/HasMedia.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,9 @@ public function addMedia(
185185
);
186186
}
187187

188-
$media->dispatchConversions();
188+
$media->dispatchConversions(
189+
filter: fn ($definition) => $definition->immediate
190+
);
189191

190192
return $media;
191193
}

src/Jobs/MediaConversionJob.php

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,7 @@ public function uniqueId(): string
3636

3737
public function handle(): void
3838
{
39-
if (
40-
$this->media->model &&
41-
$this->media->model->getMediaCollection($this->media->collection_name)
42-
) {
43-
$this->media->model->executeMediaConversion($this->media, $this->conversion);
44-
} else {
45-
$this->media->executeConversion($this->conversion);
46-
}
47-
39+
$this->media->executeConversion($this->conversion);
4840
}
4941

5042
/**

src/Models/Media.php

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -361,16 +361,21 @@ public function addConversion(
361361

362362
$this->dispatchConversions(
363363
parent: $conversion,
364+
filter: fn ($definition) => $definition->immediate
364365
);
365366

366367
return $conversion;
367368
}
368369

369370
/**
371+
* @param null|(Closure(MediaConversionDefinition $definition):bool) $filter
372+
* @param ?bool $queued force queueing the conversions
370373
* @return $this
371374
*/
372375
public function dispatchConversions(
373-
?MediaConversion $parent = null
376+
?MediaConversion $parent = null,
377+
?Closure $filter = null,
378+
?bool $queued = null,
374379
): static {
375380
if ($parent) {
376381
$definitions = $this->getChildrenConversionsDefinitions($parent->conversion_name);
@@ -379,7 +384,8 @@ public function dispatchConversions(
379384
}
380385

381386
foreach ($definitions as $definition) {
382-
if (! $definition->immediate) {
387+
388+
if ($filter && ! $filter($definition)) {
383389
continue;
384390
}
385391

@@ -390,7 +396,7 @@ public function dispatchConversions(
390396
continue;
391397
}
392398

393-
if ($definition->queued) {
399+
if ($definition->queued || $queued === true) {
394400
$definition->dispatch(
395401
media: $this,
396402
parent: $parent,

tests/Feature/HasMediaTest.php

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@
9696
expect($modelMedia)->toBeInstanceOf(Media::class);
9797
});
9898

99-
it('generates conversions and nested conversions when adding media', function () {
99+
it('generates and loads non queued conversions when adding media', function () {
100100
Storage::fake('media');
101101
$model = new Test;
102102
$model->save();
@@ -107,13 +107,43 @@
107107
disk: 'media'
108108
);
109109

110-
expect(
111-
$media->conversions->pluck('conversion_name')->toArray()
112-
)->toBe([
113-
'poster',
114-
'poster.360',
115-
// 'small' video conversion is queued
116-
]);
110+
expect($media->getConversion('poster'))->not->toBe(null);
111+
expect($media->getConversion('poster.360'))->not->toBe(null);
112+
});
113+
114+
it('generates immediate conversions when adding media', function () {
115+
Storage::fake('media');
116+
$model = new Test;
117+
$model->save();
118+
119+
$media = $model->addMedia(
120+
file: $this->getTestFile('videos/horizontal.mp4'),
121+
collectionName: 'conversions',
122+
disk: 'media'
123+
);
124+
125+
$media->refresh(); // ensure queued conversions are loaded
126+
127+
expect($media->getConversion('poster'))->not->toBe(null);
128+
expect($media->getConversion('poster.360'))->not->toBe(null);
129+
expect($media->getConversion('small'))->not->toBe(null);
130+
});
131+
132+
it('does not generate not immediate conversions when adding media', function () {
133+
Storage::fake('media');
134+
$model = new Test;
135+
$model->save();
136+
137+
$media = $model->addMedia(
138+
file: $this->getTestFile('videos/horizontal.mp4'),
139+
collectionName: 'conversions',
140+
disk: 'media'
141+
);
142+
143+
$media->refresh(); // ensure queued conversions are loaded
144+
145+
expect($media->getConversion('delayed'))->toBe(null);
146+
expect($media->getConversion('poster.delayed'))->toBe(null);
117147

118148
});
119149

tests/Feature/MediaTest.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,9 +192,10 @@
192192

193193
$definitions = $media->getConversionsDefinitions();
194194

195-
expect($definitions)->toHaveLength(2);
195+
expect($definitions)->toHaveLength(3);
196196
expect($definitions['poster'])->toBeInstanceOf(MediaConversionDefinition::class);
197197
expect($definitions['small'])->toBeInstanceOf(MediaConversionDefinition::class);
198+
expect($definitions['delayed'])->toBeInstanceOf(MediaConversionDefinition::class);
198199

199200
});
200201

tests/Models/Test.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,13 +75,23 @@ public function registerMediaCollections(): Arrayable|iterable|null
7575
width: 360,
7676
queued: false,
7777
),
78+
new MediaConversionImage(
79+
name: 'delayed',
80+
immediate: false,
81+
queued: false,
82+
),
7883
]
7984
),
8085
new MediaConversionVideo(
8186
name: 'small',
8287
queued: true,
8388
width: 100,
8489
),
90+
new MediaConversionVideo(
91+
name: 'delayed',
92+
immediate: false,
93+
queued: false,
94+
),
8595
]
8696
),
8797
];

0 commit comments

Comments
 (0)