Files
2026-09-15 10:35:56 +08:00

112 lines
4.2 KiB
PHP

<?php
declare(strict_types=1);
namespace Esun\MultiLocaleTranslation\Model\Queue;
use Esun\MultiLocaleTranslation\Model\EntityPool;
use Esun\MultiLocaleTranslation\Model\ProviderConfig;
use Esun\MultiLocaleTranslation\Model\StoreViewProvider;
use Magento\Framework\App\ResourceConnection;
use Magento\Framework\Exception\LocalizedException;
class QueueManager
{
private const TABLE_NAME = 'esun_localetranslation_queue';
public function __construct(
private readonly ResourceConnection $resourceConnection,
private readonly EntityPool $entityPool,
private readonly ProviderConfig $providerConfig,
private readonly StoreViewProvider $storeViewProvider
) {
}
/**
* @param int[] $entityIds
* @param int[] $targetStoreIds
* @return array{batch_id:string,created:int,skipped:int}
*/
public function enqueue(
string $entityType,
array $entityIds,
int $sourceStoreId,
array $targetStoreIds,
string $provider
): array {
$this->entityPool->get($entityType);
$enabledProviders = array_column($this->providerConfig->getEnabledOptions(), 'code');
if (!in_array($provider, $enabledProviders, true)) {
throw new LocalizedException(__('The selected translation provider is not enabled.'));
}
$validStoreIds = array_column($this->storeViewProvider->getStoreViewOptions(), 'store_id');
$entityIds = array_values(array_unique(array_filter(array_map('intval', $entityIds))));
$targetStoreIds = array_values(array_unique(array_filter(array_map('intval', $targetStoreIds))));
$targetStoreIds = array_values(array_intersect($targetStoreIds, $validStoreIds));
if ($sourceStoreId > 0) {
$targetStoreIds = array_values(array_diff($targetStoreIds, [$sourceStoreId]));
}
if ($entityIds === [] || $targetStoreIds === []) {
throw new LocalizedException(__('Select at least one entity and one target Store View.'));
}
$connection = $this->resourceConnection->getConnection();
$table = $this->resourceConnection->getTableName(self::TABLE_NAME);
$batchId = bin2hex(random_bytes(16));
$rows = [];
$skipped = 0;
foreach ($entityIds as $entityId) {
foreach ($targetStoreIds as $targetStoreId) {
$existing = (int)$connection->fetchOne(
$connection->select()
->from($table, 'COUNT(*)')
->where('entity_type = ?', $entityType)
->where('entity_id = ?', $entityId)
->where('source_store_id = ?', max(0, $sourceStoreId))
->where('target_store_id = ?', $targetStoreId)
->where('provider = ?', $provider)
->where('status IN (?)', ['pending', 'processing'])
);
if ($existing > 0) {
$skipped++;
continue;
}
$rows[] = [
'batch_id' => $batchId,
'provider' => $provider,
'entity_type' => $entityType,
'entity_id' => $entityId,
'source_store_id' => max(0, $sourceStoreId),
'target_store_id' => $targetStoreId,
'status' => 'pending',
];
}
}
if ($rows !== []) {
$connection->insertMultiple($table, $rows);
}
return ['batch_id' => $batchId, 'created' => count($rows), 'skipped' => $skipped];
}
/** @return array{deleted:int,processing:int} */
public function clearAll(): array
{
$connection = $this->resourceConnection->getConnection();
$table = $this->resourceConnection->getTableName(self::TABLE_NAME);
$processing = (int)$connection->fetchOne(
$connection->select()
->from($table, 'COUNT(*)')
->where('status = ?', 'processing')
);
return [
'deleted' => $connection->delete($table),
'processing' => $processing,
];
}
}