Last active
September 9, 2020 13:44
-
-
Save viirre/56998afdb5fde19b0fe438db0ca62768 to your computer and use it in GitHub Desktop.
Upgrade Script Medialibrary v6 to v7
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// Blogpost: XXX | |
// Assumes you have created a new column on your `media` table called `converted` (boolean default false) | |
// app/Console/Commands/UpgradeMediaCommand.php | |
namespace App\Console\Commands; | |
use App\Jobs\UpgradeS3MediaJob; | |
use Illuminate\Console\Command; | |
use Illuminate\Console\ConfirmableTrait; | |
use Spatie\MediaLibrary\Models\Media; | |
class UpgradeMediaCommand extends Command | |
{ | |
use ConfirmableTrait; | |
protected $signature = 'upgrade-media | |
{disk? : Disk to use} | |
{--d|dry-run : List files that will be renamed without renaming them} | |
{--f|force : Force the operation to run when in production}'; | |
protected $description = 'Update the names of the version 6 files of spatie/laravel-medialibrary'; | |
public function handle() | |
{ | |
if (! $this->confirmToProceed()) { | |
return; | |
} | |
$isDryRun = $this->option('dry-run') ?? false; | |
$disk = $this->argument('disk') ?? config('medialibrary.disk_name'); | |
$limit = 5000; | |
Media::query() | |
->where('converted', false) | |
->limit($limit) | |
->orderBy('created_at', 'desc') | |
->chunk(100, function ($mediaCollection) use ($isDryRun, $disk) { | |
dispatch(new UpgradeS3MediaJob($mediaCollection->toArray(), $isDryRun, $disk)); | |
}); | |
} | |
} | |
// app/Jobs/UpgradeS3MediaJob.php | |
namespace App\Jobs; | |
use Illuminate\Bus\Queueable; | |
use Illuminate\Contracts\Queue\ShouldQueue; | |
use Illuminate\Foundation\Bus\Dispatchable; | |
use Illuminate\Queue\SerializesModels; | |
use Illuminate\Support\Facades\Storage; | |
use Illuminate\Support\Str; | |
use Spatie\MediaLibrary\Models\Media; | |
class UpgradeS3MediaJob implements ShouldQueue | |
{ | |
use Dispatchable, Queueable, SerializesModels; | |
private bool $isDryRun; | |
private array $mediaCollectionArray; | |
private array $mediaIdsToUpdate = []; | |
private Collection $mediaFilesToChange; | |
private string $disk; | |
public function __construct(array $mediaCollectionArray, $isDryRun, $disk) | |
{ | |
$this->isDryRun = $isDryRun; | |
$this->mediaCollectionArray = $mediaCollectionArray; | |
$this->disk = $disk; | |
} | |
/** | |
* Execute the job. | |
* | |
* @return void | |
*/ | |
public function handle() | |
{ | |
$this | |
->getMediaFilesToBeRenamed() | |
->renameMediaFiles(); | |
if (! $this->isDryRun) { | |
Media::whereIn('id', $this->mediaIdsToUpdate)->update(['converted' => 1]); | |
info('Updated ' . count($this->mediaIdsToUpdate) . ' items as converted!'); | |
} else { | |
info('Done dry run'); | |
} | |
} | |
protected function getMediaFilesToBeRenamed(): self | |
{ | |
$files = []; | |
foreach ($this->mediaCollectionArray as $mediaArray) { | |
$dir = './media/' . $mediaArray['id']; | |
$newFiles = $this->convert($dir)->toArray(); | |
$files = array_merge($files, $newFiles); | |
} | |
$this->mediaFilesToChange = collect($files); | |
return $this; | |
} | |
protected function convert($directory) | |
{ | |
return collect(Storage::disk($this->disk)->allFiles($directory)) | |
->reject(function (string $file): bool { | |
return ! Str::startsWith($file, 'media') || strpos($file, '/') === false; | |
}) | |
->filter(function (string $file): bool { | |
return $this->hasOriginal($file); | |
}) | |
->filter(function (string $file): bool { | |
return $this->needsToBeConverted($file); | |
}) | |
->map(function (string $file): array { | |
return $this->getReplaceArray($file); | |
}); | |
} | |
protected function renameMediaFiles() | |
{ | |
if ($this->mediaFilesToChange->count() === 0) { | |
info('There are no files to convert.'); | |
} | |
if ($this->isDryRun) { | |
info('This is a dry-run and will not actually rename the files'); | |
} | |
$this->mediaFilesToChange->each(function (array $filePaths) { | |
if (! $this->isDryRun) { | |
Storage::disk($this->disk)->move($filePaths['current'], $filePaths['replacement']); | |
$this->mediaIdsToUpdate[] = $this->getIdFromPath($filePaths['current']); | |
} | |
info("The file `{$filePaths['current']}` has become `{$filePaths['replacement']}`"); | |
}); | |
} | |
protected function hasOriginal(string $filePath): bool | |
{ | |
$path = pathinfo($filePath, PATHINFO_DIRNAME); | |
$oneLevelHigher = dirname($path); | |
if ($oneLevelHigher === '.' || $oneLevelHigher === 'media') { | |
return false; | |
} | |
$original = Storage::disk($this->disk)->files($oneLevelHigher); | |
if (count($original) !== 1) { | |
return false; | |
} | |
return true; | |
} | |
protected function needsToBeConverted(string $file): bool | |
{ | |
$currentFile = pathinfo($file); | |
$original = $this->getOriginal($currentFile['dirname']); | |
return strpos($currentFile['basename'], $original) === false; | |
} | |
protected function getReplaceArray(string $file): array | |
{ | |
$currentFile = pathinfo($file); | |
$currentFilePath = $currentFile['dirname']; | |
$original = $this->getOriginal($currentFilePath); | |
return [ | |
'current' => $file, | |
'replacement' => "{$currentFilePath}/{$original}-{$currentFile['basename']}", | |
]; | |
} | |
protected function getOriginal(string $filePath): string | |
{ | |
$oneLevelHigher = dirname($filePath); | |
$original = Storage::disk($this->disk)->files($oneLevelHigher); | |
return pathinfo($original[0], PATHINFO_FILENAME); | |
} | |
private function getIdFromPath($currentPath) | |
{ | |
$parts = explode('/', $currentPath); | |
return $parts[1]; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment