112 lines
4.2 KiB
PHP
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,
|
|
];
|
|
}
|
|
}
|