1С-Битрикс. Скрипт для удаления старых корзин
Накатал на коленке скрипт для удаления старых корзин покупателей. В битриксе есть воркер для этой задачи, но он как правило не справляется со своей задачей.
Скрипт смотрит настройку «Сохранять корзину (дней)» модуля «Интернет магазин». Корзины больше этого количества дней будут удалены. Следить за тем, как идёт процесс можно в файле лога (проще всего в консоли сервера коммандой tail -f ~clear_old_basket.log в папке запускаемого скрипта).
Код
// Run script in cli mode if (php_sapi_name() !== 'cli') { header('HTTP/1.1 404 Not Found'); echo '404 Not Found.'; exit; } $_SERVER['DOCUMENT_ROOT'] = __DIR__; $DOCUMENT_ROOT = $_SERVER['DOCUMENT_ROOT']; define('NO_KEEP_STATISTIC', true); define('NOT_CHECK_PERMISSIONS', true); define('CHK_EVENT', true); require($_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/prolog_before.php'); // {{{ settings $limitPerStep = 300; $dayAfterDelete = COption::GetOptionString('sale', 'delete_after', 30); $fileLog = $_SERVER['DOCUMENT_ROOT'] . '/~clear_old_basket.log'; // }}} // {{{ logic if (intval($dayAfterDelete) <= 0) { $dayAfterDelete = 30; } global $DB; @set_time_limit(0); @ignore_user_abort(true); @ini_set('memory_limit', '4G'); $c = 0; $count = 0; @file_put_contents($fileLog, PHP_EOL . "Counting the total number of old baskets.." . PHP_EOL); $countIterator = $DB->Query( sprintf( "SELECT COUNT(f.ID) as TOTAL FROM b_sale_fuser f LEFT JOIN b_sale_order o ON (o.USER_ID = f.USER_ID) WHERE TO_DAYS(f.DATE_UPDATE)<(TO_DAYS(NOW())-%s) AND f.USER_ID is null AND o.ID is null", $dayAfterDelete ) ); if ($countData = $countIterator->Fetch()) { $count = $countData['TOTAL']; } if ($count > 0) { for ($i = 0, $l = ceil($count / $limitPerStep); $i <= $l; $i++) { $res = $DB->Query( sprintf( "SELECT f.ID FROM b_sale_fuser f LEFT JOIN b_sale_order o ON (o.USER_ID = f.USER_ID) WHERE TO_DAYS(f.DATE_UPDATE)<(TO_DAYS(NOW())-%s) AND f.USER_ID is null AND o.ID is null LIMIT %s", $dayAfterDelete, $limitPerStep ) ); while ($ar = $res->Fetch()) { $resB = $DB->Query( sprintf( "SELECT b.ID FROM `b_sale_basket` b WHERE b.FUSER_ID = '%s' and b.ORDER_ID IS NULL;", $ar['ID'] ) ); while ($arB = $resB->Fetch()) { $DB->Query(sprintf("DELETE FROM b_sale_basket_props WHERE BASKET_ID = '%s'", $arB['ID']), true); $DB->Query(sprintf("DELETE FROM b_sale_store_barcode WHERE BASKET_ID = '%s'", $arB['ID']), true); $DB->Query(sprintf("DELETE FROM b_sale_basket WHERE ID = '%s'", $arB['ID']), true); } $DB->Query(sprintf("DELETE FROM b_sale_fuser WHERE ID = '%s'", $ar['ID']), true); } $c += $limitPerStep; @file_put_contents( $fileLog, sprintf( PHP_EOL . "Deleted baskets %s of %s" . PHP_EOL, $c, $count ) ); } } else { @file_put_contents( $fileLog, sprintf( PHP_EOL . "Old baskets not found" . PHP_EOL ) ); } // }}}
6 комментариев
ORM? Не, не слышали
Роман, ORM для слабаков!
Как запустить его? php файл выдает 404
А что значит? // Run script in cli mode
А если в настройках модуля значение параметра не указано? У него есть минимальное автоматическое значение, которое присваивает Битрикс, или это значит, что корзины удаляться не будут никогда?
Антон, в функции COption::GetOptionString третьим параметром передается дефолтное значение. Таким образом, если в настройках не указано, то это будет период в 30 дней