This commit is contained in:
2026-02-05 16:22:55 +03:00
parent 1adbe9591c
commit 3a75beee32
18 changed files with 319 additions and 335 deletions
@@ -2,9 +2,10 @@
namespace Bx\Discount\Agents;
use Bx\Discount\Tools;
use Wt\Core\Agent\AAgentCase;
class SpiderAgentManager extends AAgentCase
class SpiderAgentCase extends AAgentCase
{
/**
* @return array
@@ -33,9 +34,11 @@ class SpiderAgentManager extends AAgentCase
$agent = app()->factory()->main()->getAgentFactory()->getEntityById($arAgent['ID']);
}
$spider = discountApp()->service()->spider();
$spider->setAgent($agent);
$spider->next();
if(Tools::isEnable()){
$spider = discountApp()->service()->spider();
$spider->setContext($agent);
$spider->next();
}
return static::class . "::exec(\$arAgent);";
}
-13
View File
@@ -2,7 +2,6 @@
namespace Bx\Discount\Ajax;
use Bx\Discount\Agents\SpiderAgentManager;
use Wt\Core\Ajax\AAjaxHandler;
class BxDiscount extends AAjaxHandler
@@ -12,18 +11,6 @@ class BxDiscount extends AAjaxHandler
$this->getResponse()->addData(['method' => 'ajaxStart']);
}
public function spiderAgentDelete()
{
$agentManager = new SpiderAgentManager();
$agentManager->delete();
}
public function spiderAgentAdd()
{
$agentManager = new SpiderAgentManager();
$agentManager->add();
}
public function test()
{
$this->getResponse()->addData(['method' => 'test', 'version' => discountApp()->module()->getVersion()]);
-122
View File
@@ -1,122 +0,0 @@
<?php
namespace Bx\Discount;
use Wt\Core\Entity\AgentEntity;
class ElementSpider
{
protected $agent;
public function __construct()
{
}
public function next()
{
if(!$this->canDo()){
if($this->isDataExpired()){
$this->reset();
}
return false;
}
$lastId = $this->getLastId();
if($lastId == 0){
$this->setBeginTimestamp();
}
$iBlockId = discountApp()->config('CATALOG_IBLOCK_ID');
$ids = Tools::getElementList($lastId);
if(count($ids) == 0){
$this->setEndTimestamp();
}
$__lastId = 0;
foreach ($ids as $id){
$__lastId = $id;
Tools::setTicketValueFromDiscount($id);
}
$this->setLastId($__lastId);
return true;
}
public function canDo()
{
$resetTimestamp = $this->getResetTimestamp();
$spiderBeginTimestamp = $this->getBeginTimestamp();
$spiderEndTimestamp = $this->getEndTimestamp();
return ($resetTimestamp > $spiderEndTimestamp)
|| ($resetTimestamp > $spiderBeginTimestamp);
}
public function isDataExpired()
{
$spiderEndTimestamp = $this->getEndTimestamp();
$renewalPeriod = discountApp()->config('RENEWAL_PERIOD');
return $spiderEndTimestamp + $renewalPeriod < time();
}
public function getLastId()
{
return (int)discountApp()->setting()->get('last_id', 0);
}
public function setLastId($lastId)
{
discountApp()->setting()->set('last_id', (int)$lastId);
return $this;
}
public function setBeginTimestamp()
{
discountApp()->setting()->set('spider_begin_timestamp', time());
return $this;
}
public function getBeginTimestamp()
{
return (int)discountApp()->setting()->get('spider_begin_timestamp', 0);
}
public function setEndTimestamp()
{
discountApp()->setting()->set('spider_end_timestamp', time());
return $this;
}
public function getEndTimestamp()
{
return (int)discountApp()->setting()->get('spider_end_timestamp', 0);
}
public function setResetTimestamp()
{
discountApp()->setting()->set('spider_reset_timestamp', time());
return $this;
}
public function getResetTimestamp()
{
return (int)discountApp()->setting()->get('spider_reset_timestamp', 0);
}
public function reset()
{
$this->setLastId(0);
$this->setResetTimestamp();
return $this;
}
public function setAgent($agent)
{
$this->agent = $agent;
}
/**
* @return AgentEntity|null
*/
public function getAgent()
{
return $this->agent;
}
}
+8
View File
@@ -16,6 +16,14 @@ class DiscountEntity extends AEntity
return parent::getFactory(); // TODO: Change the autogenerated stub
}
/**
* @return string
*/
public function getType()
{
return $this->getRaw('TYPE', '0');
}
/**
* @return DiscountFields
*/
+8 -2
View File
@@ -2,7 +2,7 @@
namespace Bx\Discount\Facade;
use Bx\Discount\ElementSpider;
use Bx\Discount\Spiders\ElementSpider;
use Wt\Core\Facade\AFacade;
class DefaultServiceFacade extends AFacade
@@ -13,7 +13,13 @@ class DefaultServiceFacade extends AFacade
*/
public function spider()
{
return $this->app->container()->make(ElementSpider::class);
return $this->app->container()->make(ElementSpider::class, [
discountApp()->module()->getId(),
'element',
discountApp()->config('spider.micro_task_period', 60),
discountApp()->config('spider.expire', 3600),
discountApp()->config('spider.period', 86400),
]);
}
}
+9
View File
@@ -43,6 +43,15 @@ class DiscountFactory extends AORMFactory
return parent::getEntityById($id);
}
/**
* @param array $arResult
* @return DiscountEntity
*/
public function getEntityByResult(array $arResult)
{
return parent::getEntityByResult($arResult); // TODO: Change the autogenerated stub
}
/**
* @param array $filter
* @param array $order
+17 -52
View File
@@ -24,61 +24,26 @@ class ADiscount
protected static function updateAdditionalDiscountData($id)
{
$depsLoaded = \Bitrix\Main\Loader::includeModule('iblock');
if(!$depsLoaded) {
return;
}
$res_element = \CIBlockElement::GetList(
['SORT' => 'ASC'],
['IBLOCK_ID' => discountApp()->config('DISCOUNT_TYPE_IBLOCK_ID'), 'NAME' => $id],
false,
false,
['ID', 'NAME', 'PROPERTY_TYPE']
);
$res_element_count = $res_element->SelectedRowsCount();
if($res_element_count){
$obElement = $res_element->GetNext();
\CIBlockElement::SetPropertyValuesEx(
$obElement['ID'],
discountApp()->config('DISCOUNT_TYPE_IBLOCK_ID'),
[
'TYPE' => $_POST['PRODUCT_TYPE'],
'MIN_COUNT_PROD' => $_POST['MIN_COUNT_PROD']
]
);
} else {
$el = new \CIBlockElement();
$arTypeField = [
'IBLOCK_ID' => discountApp()->config('DISCOUNT_TYPE_IBLOCK_ID'),
'NAME' => $id,
'PROPERTY_VALUES' => [
'TYPE' => $_POST['PRODUCT_TYPE'],
'MIN_COUNT_PROD' => $_POST['MIN_COUNT_PROD'],
],
];
$el->Add($arTypeField);
}
$discountFactory = discountApp()->factory()->main()->getDiscountFactory();
return $discountFactory->updateOrCreate([
'=DISCOUNT_ID' => $id,
], [
'DISCOUNT_ID' => $id,
'PRODUCT_TYPE' => (string)$_POST['PRODUCT_TYPE'],
'MIN_COUNT_PROD' => (int)$_POST['MIN_COUNT_PROD'],
]);
}
protected static function addAdditionalDiscountData($id)
{
$depsLoaded = \Bitrix\Main\Loader::includeModule('iblock');
if(!$depsLoaded) {
return;
}
$el = new \CIBlockElement();
$arTypeField = [
'IBLOCK_ID' => discountApp()->config('DISCOUNT_TYPE_IBLOCK_ID'),
'NAME' => $id,
'PROPERTY_VALUES' => [
'TYPE' => $_POST['PRODUCT_TYPE'],
'MIN_COUNT_PROD' => $_POST['MIN_COUNT_PROD'],
],
];
$r = $el->Add($arTypeField);
$discountFactory = discountApp()->factory()->main()->getDiscountFactory();
return $discountFactory->updateOrCreate([
'=DISCOUNT_ID' => $id,
], [
'DISCOUNT_ID' => $id,
'PRODUCT_TYPE' => (string)$_POST['PRODUCT_TYPE'],
'MIN_COUNT_PROD' => (int)$_POST['MIN_COUNT_PROD'],
]);
}
/**
@@ -104,7 +69,7 @@ class ADiscount
if(count($arResult) > $counter){
foreach($arResult as $key => $discount){
$discountViewType = Tools::getProductTypeArray($discount['ID']);
$discountViewType = Tools::getDiscountEntity($discount['ID']);
if($discountViewType['PRODUCT_TYPE'] === 'Q'){
unset($arResult[$key]);
}
+6
View File
@@ -38,6 +38,12 @@ class DiscountTable extends ADataManager
'autocomplete' => true,
'title' => 'Id',
]),
'DISCOUNT_ID' => new \Bitrix\Main\Entity\IntegerField('DISCOUNT_ID', [
'title' => 'DiscountId',
]),
'TYPE' => new \Bitrix\Main\Entity\StringField('TYPE', [
'title' => 'Type',
]),
'CREATED_AT' => new \Bitrix\Main\Entity\DatetimeField('CREATED_AT', [
'title' => 'CreatedAt',
'user_edit' => false,
+1 -1
View File
@@ -2,7 +2,7 @@
namespace Bx\Discount\Providers;
use Bx\Discount\ElementSpider;
use Bx\Discount\Spiders\ElementSpider;
use Wt\Core\Interfaces\IApp;
use Wt\Core\Providers\ADefaultServiceProvider;
+30
View File
@@ -0,0 +1,30 @@
<?php
namespace Bx\Discount\Spiders;
use Bx\Discount\Tools;
use Wt\Core\Spiders\ListSpider;
class ElementSpider extends ListSpider
{
protected function do()
{
parent::do();
$catalogIBlockId = discountApp()->config('catalog_iblock_id', 0);
if(!$catalogIBlockId){
return;
}
$lastId = $this->getLastId();
$ids = Tools::getElementList($lastId);
$__lastId = 0;
foreach ($ids as $id){
$__lastId = $id;
Tools::setTicketValueFromDiscount($id);
}
if($ids){
$this->setLastId($__lastId);
}
}
}
+112 -69
View File
@@ -31,111 +31,151 @@ class Tools
if(defined('SALE_DISCOUNT_MIGRATE_MODE') && SALE_DISCOUNT_MIGRATE_MODE){
return false;
}
return discountApp()->config('ENABLE');
return discountApp()->config('enable', false);
}
public static function getProductTypeArray($discountID)
/**
* @param $discountId
* @return Entity\DiscountEntity
*/
public static function getDiscountEntity($discountId)
{
$arProductType = [];
$arProductType['PRODUCT_TYPE'] = '0';
$arProductType['MIN_COUNT_PROD'] = 0;
$discountFactory = discountApp()->factory()->main()->getDiscountFactory();
$discountEntity = $discountFactory->getEntityById($discountId);
if(empty($discountID) || ($discountID < 0)){
return $arProductType;
if(!$discountEntity){
return $discountFactory->getEntityByResult([]);
}
$depsLoaded = Loader::includeModule('iblock');
if(!$depsLoaded) {
return $arProductType;
}
$iBlockId = discountApp()->config('DISCOUNT_TYPE_IBLOCK_ID');
if(!$iBlockId){
return $arProductType;
}
$res_element = \CIBlockElement::GetList(
['SORT' => 'ASC'],
['IBLOCK_ID' => $iBlockId, '=NAME' => $discountID],
false,
false,
['ID', 'NAME', 'PROPERTY_TYPE', 'PROPERTY_MIN_COUNT_PROD']
);
$res_element_count = $res_element->SelectedRowsCount();
if($res_element_count){
$obElement = $res_element->GetNext(true, false);
$arProductType['PRODUCT_TYPE'] = (string)$obElement['PROPERTY_TYPE_VALUE'];
$arProductType['MIN_COUNT_PROD'] = (int)$obElement['PROPERTY_MIN_COUNT_PROD_VALUE'];
}
return $arProductType;
return $discountEntity;
}
public static function setTicketValueFromDiscount($elementId)
{
$includeModule = Loader::includeModule('catalog')
&& Loader::includeModule('iblock');
&& Loader::includeModule('iblock')
&& Loader::includeModule('sale');
if(!$includeModule) {
return false;
}
$iBlockId = discountApp()->config('CATALOG_IBLOCK_ID');
$ticketPropId = discountApp()->config('TICKET_PROP_ID');
$iBlockId = discountApp()->config('catalog_iblock_id');
$map = discountApp()->config('MAP')->toArray();
$rawDiscountList = \CCatalogDiscount::GetDiscount(
$discountList = \CCatalogDiscount::GetDiscount(
$elementId,
$iBlockId,
[], //CATALOG_GROUP_ID
[], //catalog_group_id_list
[2],
'N', // renewal
's1',
false
);
$discountList = [];
foreach ($rawDiscountList as $i => $discount){
$discountId = $discount['ID'];
$arProductType = static::getProductTypeArray($discountId);
$discountList[$discountId]['PAN_SETTINGS'] = $arProductType;
if(!is_array($discountList)){
$discountList = [];
}
// pre($discountList, 0);
$iterator = \CIBlockElement::GetPropertyValues(
$iBlockId,
['ID' => $elementId],
false,
['ID' => $ticketPropId]
);
$ticketPropValueList = [];
$arTicketPropValue = $iterator->Fetch();
if($arTicketPropValue && $arTicketPropValue[$ticketPropId]){
$ticketPropValueList = $arTicketPropValue[$ticketPropId];
$af = app()->factory()->iBlock()->getEntityById($iBlockId);
$propertyFactory = $af->getPropertyFactory();
$elementFactory = $af->getElementFactory();
$elementEntity = $elementFactory->getEntityById($elementId);
if(!$elementEntity){
return false;
}
sort($ticketPropValueList);
$newTicketValue = array_diff($ticketPropValueList, $map);
$pvc = $elementEntity->getPropertyValueCollection();
$currentPropertyValueList = [];
foreach ($map as $type => $typeMap){
foreach ($typeMap as $propertyCode => $propertyValue) {
static::prepareMapPropertyCodeAndValue($propertyCode, $propertyValue);
foreach ($discountList as $discountId => $discount){
$ticketType = $discount['PAN_SETTINGS']['PRODUCT_TYPE'];
if($ticketType && $map[$ticketType]){
$newTicketValue[] = $map[$ticketType];
$propertyEntity = $propertyFactory->getEntityByCode($propertyCode);
if($propertyEntity?->getBaseType() != 'L'){
continue;
}
if(!isset($currentPropertyValueList[$propertyEntity->getId()])){
$pve = $pvc->getByCode($propertyCode);
$currentValue = $pve->getValue();
$currentValueCollection = collect($currentValue);
$currentPropertyValueList[$propertyEntity->getId()] = $currentValueCollection->values()->sort()->toArray();
}
}
}
sort($newTicketValue);
$currentPropertyValueList = collect($currentPropertyValueList)->sort()->toArray();
pre($currentPropertyValueList);
if($newTicketValue != $ticketPropValueList) {
\CIBlockElement::SetPropertyValuesEx($elementId, $iBlockId, [
$ticketPropId => $newTicketValue?:false
]);
$newPropertyValueList = $currentPropertyValueList;
foreach ($map as $type => $typeMap){
foreach ($typeMap as $propertyCode => $propertyValue) {
static::prepareMapPropertyCodeAndValue($propertyCode, $propertyValue);
if(discountApp()->config('UPDATE_ELEMENT_INDEX')){
$propertyEntity = $propertyFactory->getEntityByCode($propertyCode);
if($propertyEntity?->getBaseType() != 'L'){
continue;
}
/**
* @var \Wt\Core\Collection\IBlock\PropertyEnumCollection $valueCollection
*/
$valueCollection = $propertyEntity->getValueCollection();
$valueEntity = $valueCollection->getByXmlId($propertyValue);
$newPropertyValueList[$propertyEntity->getId()]
= collect($newPropertyValueList[$propertyEntity->getId()])
->deleteValue($valueEntity->getId())
->values()->toArray();
}
}
foreach ($discountList as $discountId => $discount){
$discountEntity = static::getDiscountEntity($discountId);
$type = $discountEntity->getType();
if(isset($map[$type]) && is_array($map[$type])){
$typeMap = $map[$type];
foreach ($typeMap as $propertyCode => $propertyValue) {
static::prepareMapPropertyCodeAndValue($propertyCode, $propertyValue);
$propertyEntity = $propertyFactory->getEntityByCode($propertyCode);
if($propertyEntity?->getBaseType() != 'L'){
continue;
}
/**
* @var \Wt\Core\Collection\IBlock\PropertyEnumCollection $valueCollection
*/
$valueCollection = $propertyEntity->getValueCollection();
$valueEntity = $valueCollection->getByXmlId($propertyValue);
$newPropertyValueList[$propertyEntity->getId()]
= collect($newPropertyValueList[$propertyEntity->getId()])
->push($valueEntity->getId())
->values()->toArray();
}
}
}
pre($newPropertyValueList);
if($newPropertyValueList != $currentPropertyValueList) {
pre('set');
foreach ($newPropertyValueList as $propertyId => $propertyValue){
if(is_array($propertyValue) && !$propertyValue){
$newPropertyValueList[$propertyId] = false;
}
}
\CIBlockElement::SetPropertyValuesEx($elementId, $iBlockId, $newPropertyValueList);
if(discountApp()->config('update_element_index')){
\Bitrix\Iblock\PropertyIndex\Manager::updateElementIndex($iBlockId, $elementId);
}
}
return true;
}
public static function prepareMapPropertyCodeAndValue(&$propertyCode, &$propertyValue)
{
if (is_int($propertyCode)) {
[$propertyCode, $propertyValue] = explode('.', $propertyValue);
}
}
public static function getElementList($lastId = 0)
{
$includeModule = Loader::includeModule('iblock');
@@ -143,7 +183,10 @@ class Tools
return [];
}
$iBlockId = discountApp()->config('CATALOG_IBLOCK_ID');
$iBlockId = discountApp()->config('catalog_iblock_id', 0);
if(!$iBlockId) {
return [];
}
$rs = \CIBlockElement::GetList(
['ID' => 'ASC'],
@@ -155,7 +198,7 @@ class Tools
],
false,
[
'nTopCount' => discountApp()->config('PAGE_SIZE', 50),
'nTopCount' => discountApp()->config('page_size', 50),
],
['ID', 'IBLOCK_ID']
);