Это давний баг Битрикса, не знаю, почему разработчики его не правят, но выход пока такой:
<? // Обновление списка лидов, компаний, сделок, контактов, предложений для актуализации настроек прав доступа define("NO_KEEP_STATISTIC", true); define("NOT_CHECK_PERMISSIONS", true); define('CHK_EVENT', true); ini_set('memory_limit', '-1'); require($_SERVER["DOCUMENT_ROOT"] . "/bitrix/modules/main/include/prolog_before.php"); @set_time_limit(0); @ignore_user_abort(true); global $USER; $USER->Authorize(1); CModule::IncludeModule("crm"); $CCrmLead = new CCrmLead(); $CCrmCompany = new CCrmCompany(); $CCrmContact = new CCrmContact(); $CCrmDeal = new CCrmDeal(); $CCrmQuote = new CCrmQuote(); $eventManager = \Bitrix\Main\EventManager::getInstance(); $companyUpdatedHandlers = $eventManager->findEventHandlers("crm", "OnAfterCrmCompanyUpdate"); $companyBeforeUpdateHandlers = $eventManager->findEventHandlers("crm", "OnBeforeCrmCompanyUpdate"); $contactBeforeUpdatedHandlers = $eventManager->findEventHandlers("crm", "OnBeforeCrmContactUpdate"); $contactUpdatedHandlers = $eventManager->findEventHandlers("crm", "OnAfterCrmContactUpdate"); $quoteBeforeUpdatedHandlers = $eventManager->findEventHandlers("crm", "OnBeforeCrmQuoteUpdate"); $quoteUpdatedHandlers = $eventManager->findEventHandlers("crm", "OnAfterCrmQuoteUpdate"); // Классы с обработчиками событий для удаления $arCallbacksToDelete = ['myCrmCompanyContactHandler', "EventClass"]; foreach ($companyBeforeUpdateHandlers as $iEventHandlerKey => $handler) { if (in_array($handler["CALLBACK"][0], $arCallbacksToDelete)) { $eventManager->removeEventHandler("crm", "OnBeforeCrmCompanyUpdate", $iEventHandlerKey); } } foreach ($companyUpdatedHandlers as $iEventHandlerKey => $handler) { if (in_array($handler["CALLBACK"][0], $arCallbacksToDelete)) { $eventManager->removeEventHandler("crm", "OnAfterCrmCompanyUpdate", $iEventHandlerKey); } } foreach ($contactBeforeUpdatedHandlers as $iEventHandlerKey => $handler) { if (in_array($handler["CALLBACK"][0], $arCallbacksToDelete)) { $eventManager->removeEventHandler("crm", "OnBeforeCrmContactUpdate", $iEventHandlerKey); } } foreach ($contactUpdatedHandlers as $iEventHandlerKey => $handler) { if (in_array($handler["CALLBACK"][0], $arCallbacksToDelete)) { $eventManager->removeEventHandler("crm", "OnAfterCrmContactUpdate", $iEventHandlerKey); } } foreach ($quoteBeforeUpdatedHandlers as $iEventHandlerKey => $handler) { if (in_array($handler["CALLBACK"][0], $arCallbacksToDelete)) { $eventManager->removeEventHandler("crm", "OnBeforeCrmQuoteUpdate", $iEventHandlerKey); } } foreach ($quoteUpdatedHandlers as $iEventHandlerKey => $handler) { if (in_array($handler["CALLBACK"][0], $arCallbacksToDelete)) { $eventManager->removeEventHandler("crm", "OnAfterCrmQuoteUpdate", $iEventHandlerKey); } } //Для сделки и лида такой цикл не нужен, там просто вызываем метод update с ключом ENABLE_SYSTEM_EVENTS = false // Лимит кол-ва обрабатываемых записей (0 - без ограничения) // Можно передать из терминала "php update_company_rights.php 1000" $limit = 0; if ($argc >= 2) { $limit = $argv[1]; } // Получаем список лидов $leadsResult = $CCrmLead->GetListEx(array('ID' => 'ASC'), array(), false, false); $leadsCounter = 0; $leadsStartTime = microtime(true); // Проходим по предложениям, чтобы обновились права // обновим поле OPENED на противоположное текущему и вернем обратно while ($arLead = $leadsResult->GetNext()) { if ($limit > 0 && $leadsCounter >= $limit) { break; } // Сохраняем оригинальное значение $originalOpened = $arLead["OPENED"]; $valueToChange = 0; // Устанавливаем противоположное оригинальному значение if ($originalOpened == "Y") { $valueToChange = "N"; } elseif ($originalOpened == "N") { $valueToChange = "Y"; } if ($valueToChange !== 0) { $arFieldsToChange = ['ID' => $arLead["ID"], "OPENED" => $valueToChange, "NO_EVENT_ROUTE" => "Y"]; // Обновляем элемент на новое значение if (!$CCrmLead->Update($arLead["ID"], $arFieldsToChange, false, false, ['ENABLE_SYSTEM_EVENTS' => false])) { echo "ERROR \r\n "; echo $CCrmLead->LAST_ERROR; echo " \r\n "; } // Возвращаем поле обратно $arFieldsToChange["OPENED"] = $originalOpened; if (!$CCrmLead->Update($arLead["ID"], $arFieldsToChange, false, false, ['ENABLE_SYSTEM_EVENTS' => false])) { echo "ERROR \r\n "; echo $CCrmLead->LAST_ERROR; echo " \r\n "; } } $leadsCounter++; } $leadsEndTime = microtime(true); // Получаем список компаний $companiesResult = $CCrmCompany->GetListEx(array('ID' => 'ASC'), array(), false, false); // Проходим по компаниям, чтобы обновились права // обновим поле OPENED на противоположное текущему и вернем обратно $companiesCounter = 0; $companiesStartTime = microtime(true); while ($arCompany = $companiesResult->GetNext()) { if ($limit > 0 && $companiesCounter >= $limit) { break; } // Сохраняем оригинальное значение $originalOpened = $arCompany["OPENED"]; $valueToChange = 0; // Устанавливаем противоположное оригинальному значение if ($originalOpened == "Y") { $valueToChange = "N"; } elseif ($originalOpened == "N") { $valueToChange = "Y"; } if ($valueToChange !== 0) { $arFieldsToChange = ['ID' => $arCompany["ID"], "OPENED" => $valueToChange, "NO_EVENT_ROUTE" => "Y"]; // Обновляем элемент на новое значение if (!$CCrmCompany->Update($arCompany["ID"], $arFieldsToChange, false, false, [])) { echo "ERROR \r\n "; echo $CCrmCompany->LAST_ERROR; echo " \r\n "; } // Возвращаем поле обратно $arFieldsToChange["OPENED"] = $originalOpened; if (!$CCrmCompany->Update($arCompany["ID"], $arFieldsToChange, false, false, [])) { echo "ERROR \r\n "; echo $CCrmCompany->LAST_ERROR; echo " \r\n "; } } $companiesCounter++; } $companiesEndTime = microtime(true); // Получаем список контактов $contactsResult = $CCrmContact->GetListEx(array('ID' => 'ASC'), array(), false, false); $contactsCounter = 0; $contactsStartTime = microtime(true); // Проходим по контактам, чтобы обновились права // обновим поле OPENED на противоположное текущему и вернем обратно while ($arContact = $contactsResult->GetNext()) { if ($limit > 0 && $contactsCounter >= $limit) { break; } // Сохраняем оригинальное значение $originalOpened = $arContact["OPENED"]; $valueToChange = 0; // Устанавливаем противоположное оригинальному значение if ($originalOpened == "Y") { $valueToChange = "N"; } elseif ($originalOpened == "N") { $valueToChange = "Y"; } if ($valueToChange !== 0) { $arFieldsToChange = ['ID' => $arContact["ID"], "OPENED" => $valueToChange, "NO_EVENT_ROUTE" => "Y"]; // Обновляем элемент на новое значение if (!$CCrmContact->Update($arContact["ID"], $arFieldsToChange, false, false, [])) { echo "ERROR \r\n "; echo $CCrmContact->LAST_ERROR; echo " \r\n "; } // Возвращаем поле обратно $arFieldsToChange["OPENED"] = $originalOpened; if (!$CCrmContact->Update($arContact["ID"], $arFieldsToChange, false, false, [])) { echo "ERROR \r\n "; echo $CCrmContact->LAST_ERROR; echo " \r\n "; } } $contactsCounter++; } $contactsEndTime = microtime(true); // Получаем список сделок $dealsResult = $CCrmDeal->GetListEx(array('ID' => 'ASC'), array(), false, false); $dealsCounter = 0; $dealsStartTime = microtime(true); // Проходим по сделкам, чтобы обновились права // обновим поле OPENED на противоположное текущему и вернем обратно while ($arDeal = $dealsResult->GetNext()) { if ($limit > 0 && $dealsCounter >= $limit) { break; } // Сохраняем оригинальное значение $originalOpened = $arDeal["OPENED"]; $valueToChange = 0; // Устанавливаем противоположное оригинальному значение if ($originalOpened == "Y") { $valueToChange = "N"; } elseif ($originalOpened == "N") { $valueToChange = "Y"; } if ($valueToChange !== 0) { $arFieldsToChange = ['ID' => $arDeal["ID"], "OPENED" => $valueToChange, "NO_EVENT_ROUTE" => "Y"]; // Обновляем элемент на новое значение if (!$CCrmDeal->Update($arDeal["ID"], $arFieldsToChange, false, false, ['ENABLE_SYSTEM_EVENTS' => false])) { echo "ERROR \r\n "; echo $CCrmDeal->LAST_ERROR; echo " \r\n "; } // Возвращаем поле обратно $arFieldsToChange["OPENED"] = $originalOpened; if (!$CCrmDeal->Update($arDeal["ID"], $arFieldsToChange, false, false, ['ENABLE_SYSTEM_EVENTS' => false])) { echo "ERROR \r\n "; echo $CCrmDeal->LAST_ERROR; echo " \r\n "; } } $dealsCounter++; } $dealsEndTime = microtime(true); // Получаем список предложений $quotesResult = $CCrmQuote->GetList(array('ID' => 'ASC'), array(), false, false); $quotesCounter = 0; $quotesStartTime = microtime(true); // Проходим по предложениям, чтобы обновились права // обновим поле OPENED на противоположное текущему и вернем обратно while ($arQuote = $quotesResult->GetNext()) { if ($limit > 0 && $quotesCounter >= $limit) { break; } // Сохраняем оригинальное значение $originalOpened = $arQuote["OPENED"]; $valueToChange = 0; // Устанавливаем противоположное оригинальному значение if ($originalOpened == "Y") { $valueToChange = "N"; } elseif ($originalOpened == "N") { $valueToChange = "Y"; } if ($valueToChange !== 0) { $arFieldsToChange = ['ID' => $arQuote["ID"], "OPENED" => $valueToChange, "NO_EVENT_ROUTE" => "Y"]; // Обновляем элемент на новое значение if (!$CCrmQuote->Update($arQuote["ID"], $arFieldsToChange, false, false)) { echo "ERROR \r\n "; echo $CCrmQuote->LAST_ERROR; echo " \r\n "; } // Возвращаем поле обратно $arFieldsToChange["OPENED"] = $originalOpened; if (!$CCrmQuote->Update($arQuote["ID"], $arFieldsToChange, false, false)) { echo "ERROR \r\n "; echo $CCrmQuote->LAST_ERROR; echo " \r\n "; } } $quotesCounter++; } $quotesEndTime = microtime(true); $leadsExecTime = ($leadsEndTime - $leadsStartTime) / 60; $companiesExecTime = ($companiesEndTime - $companiesStartTime) / 60; $contactsExecTime = ($contactsEndTime - $contactsStartTime) / 60; $dealsExecTime = ($dealsEndTime - $dealsStartTime) / 60; $quotesExecTime = ($quotesEndTime - $quotesStartTime) / 60; echo "Время обновления " . $leadsCounter . " лидов = " . $leadsExecTime . "<br>"; echo "Время обновления " . $companiesCounter . " компаний = " . $companiesExecTime . "<br>"; echo "Время обновления " . $contactsCounter . " контактов = " . $contactsExecTime . "<br>"; echo "Время обновления " . $dealsCounter . " сделок = " . $dealsExecTime . "<br>"; echo "Время обновления " . $quotesCounter . " предложений = " . $quotesExecTime . "<br>"; |