feat: orchestrate package imports
This commit is contained in:
@@ -0,0 +1,136 @@
|
||||
<?php
|
||||
/**
|
||||
* Orchestrates content package imports.
|
||||
*
|
||||
* @package WPContentSync
|
||||
*/
|
||||
|
||||
namespace WPContentSync\Sync;
|
||||
|
||||
use WPContentSync\Content\ContentHandlerRegistry;
|
||||
use WPContentSync\Content\ContentImportException;
|
||||
use WPContentSync\Logging\LoggerInterface;
|
||||
use WPContentSync\Package\ContentPackage;
|
||||
use WPContentSync\Settings\SettingsRepository;
|
||||
|
||||
final class SyncEngine {
|
||||
private ContentHandlerRegistry $handlers;
|
||||
private SyncStateRepository $state_repository;
|
||||
private SettingsRepository $settings_repository;
|
||||
private LoggerInterface $logger;
|
||||
|
||||
public function __construct(
|
||||
ContentHandlerRegistry $handlers,
|
||||
SyncStateRepository $state_repository,
|
||||
SettingsRepository $settings_repository,
|
||||
LoggerInterface $logger
|
||||
) {
|
||||
$this->handlers = $handlers;
|
||||
$this->state_repository = $state_repository;
|
||||
$this->settings_repository = $settings_repository;
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
public function importPackage( ContentPackage $package ): SyncResult {
|
||||
$operation_id = uniqid( 'wpcs_', true );
|
||||
$total = $this->totalRecords( $package );
|
||||
$processed = 0;
|
||||
$results = array();
|
||||
$context = SyncContext::forImport(
|
||||
$package->source(),
|
||||
$package->destination(),
|
||||
$this->settings_repository->get()->conflictStrategy(),
|
||||
$operation_id
|
||||
);
|
||||
|
||||
$this->logger->info(
|
||||
'Starting content package import.',
|
||||
array(
|
||||
'operation_id' => $operation_id,
|
||||
'total' => $total,
|
||||
)
|
||||
);
|
||||
|
||||
foreach ( $this->handlers->ordered() as $handler ) {
|
||||
$bucket = $handler->bucket();
|
||||
$records = $this->recordsForBucket( $package, $bucket );
|
||||
|
||||
$this->state_repository->save( SyncOperationState::running( $operation_id, $bucket, $processed, $total ) );
|
||||
|
||||
try {
|
||||
$results[] = $handler->importRecords( $records, $context );
|
||||
} catch ( ContentImportException $exception ) {
|
||||
$this->state_repository->save(
|
||||
SyncOperationState::fromArray(
|
||||
array(
|
||||
'operation_id' => $operation_id,
|
||||
'status' => 'failed',
|
||||
'current_bucket' => $bucket,
|
||||
'processed' => $processed,
|
||||
'total' => $total,
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
$this->logger->error(
|
||||
'Content package import failed.',
|
||||
array(
|
||||
'operation_id' => $operation_id,
|
||||
'bucket' => $exception->bucket(),
|
||||
'record' => $exception->record(),
|
||||
'error' => $exception->getMessage(),
|
||||
)
|
||||
);
|
||||
|
||||
$results[] = SyncResult::failure( array( $exception->getMessage() ) );
|
||||
|
||||
return SyncResult::merge( $results );
|
||||
}
|
||||
|
||||
$processed += count( $records );
|
||||
}
|
||||
|
||||
$result = SyncResult::merge( $results );
|
||||
$this->state_repository->save( SyncOperationState::completed( $operation_id, $processed, $total ) );
|
||||
|
||||
$this->logger->info(
|
||||
'Completed content package import.',
|
||||
array_merge(
|
||||
array( 'operation_id' => $operation_id ),
|
||||
$result->toArray()
|
||||
)
|
||||
);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function totalRecords( ContentPackage $package ): int {
|
||||
$total = 0;
|
||||
|
||||
foreach ( $package->manifest() as $count ) {
|
||||
$total += max( 0, (int) $count );
|
||||
}
|
||||
|
||||
return $total;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<int, array<string, mixed>>
|
||||
*/
|
||||
private function recordsForBucket( ContentPackage $package, string $bucket ): array {
|
||||
$records = $package->records()[ $bucket ] ?? array();
|
||||
|
||||
if ( ! is_array( $records ) ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
return array_values(
|
||||
array_filter(
|
||||
$records,
|
||||
static function ( $record ): bool {
|
||||
return is_array( $record );
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user