Files
kupshop/bundles/External/ZNZBundle/Resources/script/ZNZActionsScript.php
2025-08-02 16:30:27 +02:00

308 lines
10 KiB
PHP

<?php
declare(strict_types=1);
namespace External\ZNZBundle\Resources\script;
use External\ZNZBundle\Exception\ZNZException;
use External\ZNZBundle\Util\Product\ZNZVisibilityUpdater;
use External\ZNZBundle\Util\ZNZBlockUpdater;
use External\ZNZBundle\Util\ZNZPriceLevelsGenerator;
use External\ZNZBundle\Util\ZNZTranslationsUtil;
use External\ZNZBundle\Util\ZNZUtil;
use KupShop\AdminBundle\Util\Script\Script;
use KupShop\ContentBundle\Util\Block;
use KupShop\I18nBundle\Translations\ITranslation;
use KupShop\I18nBundle\Translations\ProducersTranslation;
use KupShop\I18nBundle\Translations\TemplatesTranslation;
use KupShop\KupShopBundle\Context\ContextManager;
use KupShop\KupShopBundle\Context\LanguageContext;
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
use KupShop\KupShopBundle\Util\Contexts;
use KupShop\KupShopBundle\Util\Functional\Mapping;
use KupShop\SynchronizationBundle\Rabbit\RabbitConsumerConfiguration;
use KupShop\SynchronizationBundle\Util\Rabbit\RabbitConsumer;
use Query\Operator;
class ZNZActionsScript extends Script
{
protected static $name = '[ZNZ] Actions script';
protected static $defaultParameters = [
'generatePriceLevels' => false,
'generateProductsRelated' => false,
'updateProductsVisibility' => false,
'updateTranslations' => false,
'setOrdersUserIdsByEmail' => false,
'cleanActivityLogFromPlatneEntity' => false,
'updateProducerAndTemplateTranslationsByBlocks' => false,
'massProductsDescriptionToHelios' => false,
'massTemplatesDescriptionToHelios' => false,
'cleanupRabbitQueue' => [
'run' => false,
'queue' => 'wpj.Q.znz-profi-parfemy.priority.0',
'cleanupRules' => [
'tableName' => 'ProduktObrazek',
'isDelete' => true,
],
],
];
protected function run(array $arguments)
{
foreach ($arguments as $action => $run) {
if (!$run) {
continue;
}
$method = 'run'.ucfirst($action);
if (!method_exists($this, $method)) {
continue;
}
$this->log('Running "'.$action.'"...');
$this->{$method}($run);
$this->log('Done "'.$action.'"...');
}
}
private function runCleanupRabbitQueue(array $config): void
{
if (!($config['run'] ?? false)) {
return;
}
$rabbitConfig = RabbitConsumerConfiguration::createDefault(
queue: $config['queue'],
);
$loopLimit = 30;
$rules = $config['cleanupRules'] ?? [];
$consumer = ServiceContainer::getService(RabbitConsumer::class);
$loop = 0;
do {
$cleaned = 0;
$consumer->consume($rabbitConfig, function (\AMQPEnvelope $envelope) use ($rules, &$cleaned) {
$data = json_decode($envelope->getBody() ?: '', true) ?: [];
$ackMessage =
(($rules['tableName'] ?? null) === null || ($rules['tableName'] === ($data['Tabulka'] ?? null)))
&& (($rules['isDelete'] ?? null) !== true || !empty($data['Smazat']));
if ($ackMessage) {
$cleaned++;
}
return $ackMessage;
});
$this->log('['.$loop.'] Cleaned: '.$cleaned);
$loop++;
sleep(10);
} while ($loop < $loopLimit);
}
private function runCleanActivityLogFromPlatneEntity(): void
{
$items = array_map(fn ($x) => $x['id'], sqlQueryBuilder()
->select('id')
->from('report_activities')
->where(Operator::like(['report' => '%PlatneEntity%']))
->execute()->fetchAllAssociative());
foreach (array_chunk($items, 10) as $activityIds) {
$this->log('Cleaning batch...');
sqlQueryBuilder()
->delete('report_activities')
->where(Operator::inIntArray($activityIds, 'id'))
->execute();
// sleep for 100 ms
usleep(100000);
$this->log('Batch cleaned');
}
}
/**
* Doplni nazev do prekladu vyrobcu a sablon na zaklade toho, zda je prelozeny popisek v blokach.
*
* Na zaklade toho si oni muzou lehce zafiltrovat, co je a co neni prelozene.
*/
private function runUpdateProducerAndTemplateTranslationsByBlocks(): void
{
sqlGetConnection()->getConfiguration()->setSQLLogger();
$languageContext = Contexts::get(LanguageContext::class);
$contextManager = ServiceContainer::getService(ContextManager::class);
$blockUtil = ServiceContainer::getService(Block::class);
$producersTranslation = ServiceContainer::getService(ProducersTranslation::class);
$templatesTranslation = ServiceContainer::getService(TemplatesTranslation::class);
$updateMethod = function (int $objectId, string $objectName, ?int $blockId, ITranslation $translation) use ($contextManager, $blockUtil, $languageContext) {
$blocksDefault = $contextManager->activateContexts([LanguageContext::class => $languageContext->getDefaultId()], fn () => $blockUtil->getBlocks($blockId ?: 0, true));
$blocksDefault = Mapping::mapKeys($blocksDefault, fn ($k, $v) => [$v['id'], $v]);
foreach ($languageContext->getSupported() as $lang) {
if ($lang->getId() === $languageContext->getDefaultId()) {
continue;
}
if (!$blockId) {
$translation->saveSingleObject(
$lang->getId(),
$objectId,
[
'name' => $objectName,
]
);
continue;
}
$blocks = $contextManager->activateContexts([LanguageContext::class => $lang->getId()], fn () => $blockUtil->getBlocks($blockId, true));
$blocks = Mapping::mapKeys($blocks, fn ($k, $v) => [$v['id'], $v]);
foreach ($blocks as $blockId => $block) {
$defaultContent = trim(strip_tags($blocksDefault[$blockId]['content']));
$currentContent = trim(strip_tags($block['content']));
// pokud nema content a default block content ma, tak neni prelozeny a timpadem nic neprovadim
if (empty($currentContent) && !empty($defaultContent)) {
continue;
}
// pokud default block ma content a prelozeny blok taky, tak "prelozim" title, aby se to tvarilo jako prelozene pri filtrovani
$translation->saveSingleObject(
$lang->getId(),
$objectId,
[
'name' => $objectName,
]
);
}
}
};
$qbProducers = sqlQueryBuilder()
->select('id, id_block, name')
->from('producers');
$this->log('Running producers...');
foreach ($qbProducers->execute() as $producer) {
$updateMethod(
$producer['id'],
$producer['name'],
$producer['id_block'],
$producersTranslation
);
}
$qbTemplates = sqlQueryBuilder()
->select('id, id_block, name')
->from('templates');
$this->log('Running templates...');
foreach ($qbTemplates->execute() as $template) {
$updateMethod(
$template['id'],
$template['name'],
$producer['id_block'],
$templatesTranslation
);
}
$this->log('Done');
}
private function runGeneratePriceLevels(): void
{
$generator = ServiceContainer::getService(ZNZPriceLevelsGenerator::class);
$generator->generate();
}
private function runGenerateProductsRelated(): void
{
$util = ServiceContainer::getService(ZNZUtil::class);
$util->generateProductsRelated();
}
private function runUpdateProductsVisibility(): void
{
$updater = ServiceContainer::getService(ZNZVisibilityUpdater::class);
$updater->updateVisibility();
}
private function runUpdateTranslations(): void
{
$updater = ServiceContainer::getService(ZNZTranslationsUtil::class);
$updater->updateAll();
}
private function runMassProductsDescriptionToHelios(array $config): void
{
$updater = ServiceContainer::getService(ZNZBlockUpdater::class);
if (empty($config)) {
$this->log('Languages not specified!');
return;
}
$qb = sqlQueryBuilder()
->select('id')
->from('products')
->where('id_block IS NOT NULL');
foreach ($qb->execute() as $item) {
$this->progress();
try {
$updater->update('products', $item['id'], $config, false);
} catch (ZNZException $e) {
}
}
}
private function runMassTemplatesDescriptionToHelios(array $config): void
{
$updater = ServiceContainer::getService(ZNZBlockUpdater::class);
if (empty($config)) {
$this->log('Languages not specified!');
return;
}
$qb = sqlQueryBuilder()
->select('id')
->from('templates')
->where('id_block IS NOT NULL');
foreach ($qb->execute() as $item) {
$this->progress();
try {
$updater->update('templates', $item['id'], $config, false);
} catch (ZNZException $e) {
}
}
}
private function runSetOrdersUserIdsByEmail(): void
{
sqlQuery('UPDATE orders o
JOIN users u ON u.email = o.invoice_email
SET o.id_user = u.id
WHERE o.id_user IS NULL;');
}
}
return ZNZActionsScript::class;