. */ declare(strict_types=1); namespace FireflyIII\Console\Commands\Upgrade; use FireflyIII\Console\Commands\ShowsFriendlyMessages; use FireflyIII\Models\Recurrence; use FireflyIII\Models\RecurrenceMeta; use FireflyIII\Models\RecurrenceTransactionMeta; use Illuminate\Console\Command; class UpgradesRecurrenceMetaData extends Command { use ShowsFriendlyMessages; public const string CONFIG_NAME = '481_migrate_recurrence_meta'; protected $description = 'Migrate recurrence meta data'; protected $signature = 'upgrade:481-recurrence-meta {--F|force : Force the execution of this command.}'; /** * Execute the console command. */ public function handle(): int { if ($this->isExecuted() && true !== $this->option('force')) { $this->friendlyInfo('This command has already been executed.'); return 0; } $count = $this->migrateMetaData(); if ($count > 0) { $this->friendlyInfo(sprintf('Migrated %d meta data entries', $count)); } $this->markAsExecuted(); return 0; } private function isExecuted(): bool { $configVar = app('fireflyconfig')->get(self::CONFIG_NAME, false); if (null !== $configVar) { return (bool) $configVar->data; } return false; } private function migrateMetaData(): int { $count = 0; // get all recurrence meta data: $collection = RecurrenceMeta::with('recurrence')->get(); /** @var RecurrenceMeta $meta */ foreach ($collection as $meta) { $count += $this->migrateEntry($meta); } return $count; } private function migrateEntry(RecurrenceMeta $meta): int { /** @var null|Recurrence $recurrence */ $recurrence = $meta->recurrence; if (null === $recurrence) { return 0; } $firstTransaction = $recurrence->recurrenceTransactions()->first(); if (null === $firstTransaction) { return 0; } $value = $meta->value; if ('tags' === $meta->name) { $array = explode(',', $meta->value); $value = json_encode($array, JSON_THROW_ON_ERROR); } RecurrenceTransactionMeta::create( [ 'rt_id' => $firstTransaction->id, 'name' => $meta->name, 'value' => $value, ] ); $meta->forceDelete(); return 1; } private function markAsExecuted(): void { app('fireflyconfig')->set(self::CONFIG_NAME, true); } }