diff --git a/_config/migration.yml b/_config/migration.yml new file mode 100644 index 00000000..0e290c3e --- /dev/null +++ b/_config/migration.yml @@ -0,0 +1,11 @@ +--- +Name: file-migration +--- +# Remove the HTTPOutputHandler from the logger on the file migration. +# It logs a lot of >= NOTICE errors that pollute the output with backtrace. +SilverStripe\Core\Injector\Injector: + Psr\Log\LoggerInterface.quiet: + type: singleton + class: Monolog\Logger + constructor: + - "file-migration" \ No newline at end of file diff --git a/src/FileMigrationHelper.php b/src/FileMigrationHelper.php index ed9691e1..f1758f05 100644 --- a/src/FileMigrationHelper.php +++ b/src/FileMigrationHelper.php @@ -40,27 +40,24 @@ class FileMigrationHelper extends BaseFileMigrationHelper */ private static $delete_invalid_files = true; - /** - * Specifies the interval for every Nth file looped at which output will be logged. - * - * @config - * @var int - */ - private static $log_interval = 10; - private static $dependencies = [ - 'logger' => '%$' . LoggerInterface::class, + 'logger' => '%$' . LoggerInterface::class . '.quiet', ]; - /** @var LoggerInterface|null */ + /** + * @var LoggerInterface|null + */ private $logger; /** * @param LoggerInterface $logger + * @return $this */ public function setLogger(LoggerInterface $logger) { $this->logger = $logger; + + return $this; } /** @@ -80,6 +77,7 @@ public function run($base = null) // If not, cannot migrate /** @skipUpgrade */ if (!DB::get_schema()->hasField('File', 'Filename')) { + $this->logger->error('Database not ready for migration. Please run dev/build'); return 0; } @@ -96,26 +94,45 @@ public function run($base = null) } $query = $this->getFileQuery(); - $total = $query->count(); + $totalCount = $query->count(); + + if (!$totalCount) { + return 0; + } + + $this->logger->info(sprintf('Migrating %d files', $totalCount)); + foreach ($query as $file) { // Bypass the accessor and the filename from the column $filename = $file->getField('Filename'); - $success = $this->migrateFile($base, $file, $filename); + $this->logger->info(sprintf('Migrating %s', $filename)); - if ($processedCount % $this->config()->get('log_interval') === 0) { - if ($this->logger) { - $this->logger->info("Iterated $processedCount out of $total files. Migrated $migratedCount files."); - } - } + $success = $this->migrateFile($base, $file, $filename); $processedCount++; + $this->logger->info(sprintf( + '[%d / %d, %d%% complete]', + $processedCount, + $totalCount, + floor(($processedCount / $totalCount) * 100) + )); + if ($success) { $migratedCount++; } } + if (class_exists(Versioned::class)) { Versioned::set_reading_mode($originalState); } + + if ($processedCount < $totalCount) { + $this->logger->warning(sprintf( + 'Failed to migrate %d files, please review errors', + $totalCount - $processedCount + )); + } + return $migratedCount; } @@ -179,8 +196,8 @@ protected function migrateFile($base, File $file, $legacyFilename) } $file = File::get_by_id($fileID); } - - if (!is_readable($path)) { + + if (!is_readable($path) || fopen($path, 'r') === false) { if ($this->logger) { $this->logger->warning(sprintf( 'File at %s is not readable and could not be migrated.', @@ -239,6 +256,8 @@ protected function migrateFile($base, File $file, $legacyFilename) } return $removed; } + + return true; } /**