Делаем уведомление на почту о брошенной корзине без модулей для Битрикс

Уведомление на почту о брошенной корзине без модулей для Битрикс

Задумывались вы о том, как часто посетители разных интернет магазинов добавляют в корзину понравившийся товар и затем по каким то разным причинам бросают не оформив заказ до конца? Узнали себя? Окей, я к тому что в этой публикации хочу разобрать вопрос создания уведомлений на почту потенциальному покупателю без всяких дорогих модулей для интернет магазина на платформе Битрикс.

Так же хочу заметить что я не претендую на звание лучший программист года или супер лучшее решение года. Предлагаю как альтернативное решение платным модулям для решения этого вопроса.

Создаем инфоблок

Итак, создадим инфоблок для хранения отправленных корзин с вот такой структурой (затем будем сверяться с данной базой, отправляли ли мы уже или еще нет (исходя из выборки: по дате от… и до…, а так же по ID корзины и ID пользователя):

EMAIL — Почта пользователя, которому было отправлено уведомление (для наглядности)
DATE — Дата отправки
USER_ID — ID пользователя, которому было отправлено уведомление
FUSER_ID — ID корзины

Создание инфоблока для Битрикс

Создание инфоблока для Битрикс

к содержанию ↑

Создаем обработчик

Далее создадим обработчик, который собственно и будет у нас заниматься рассылкой.
Предлагаю создать его здесь /ajax/away_basket.php, так же ниже публикую рабочий, авторский код:

 <?php 
/*	Handler "Away basket"
	Author: Andrey Shevchuk
	Contacts: office@shevchuk-studio.pw
	Date: 17.08.2018
*/
if(empty($_SERVER["DOCUMENT_ROOT"])) $_SERVER["DOCUMENT_ROOT"] = '/home/bitrix/www/'; 
require($_SERVER["DOCUMENT_ROOT"] . "/bitrix/modules/main/include/prolog_before.php");

/* Setup */
define('TEMPLATE_ID', 1); //Email template id
define('HOVERS_FROM', 5); //Hovers from
define('HOVERS_TO', 72); //Hovers to
define('EMAILING_TYPE', 'AwayBasketMailSend'); //Type of mailing
define('AWAY_BASKET_IBLOCK', 0); //Iblock id
define('BASE_CURRENCY', 'RUB'); //Base currency, like RUB, UAH, USD
/* End Setup */

$order_table = NULL;
 
//Table template
$order_table_header = '
<table>
    <tr>
        <th>Наименование</th>
        <th>Кол</th>
        <th>Сумма</th>
    </tr>';
$order_table_footer = '</table>';
 
//Get all baskets
$baskets_array = getBasketsByCreateDateRang((time() - (HOVERS_FROM * 3600)), (time() - (HOVERS_TO * 3600)));  
 
foreach($baskets_array  as $item)
{	
		$order_table =  $order_table_header;
		
		//Get basket	
		$products_arr = getBasketByFuserId($item['FUSER_ID']);  
		
		$price = 0;
		foreach($products_arr as $key=>$product_arr)
		{	
			//Prepare data for sending mail
			$price += ($product_arr["PRICE"] * $product_arr["QUANTITY"]); //Basket sum
		
			//Building order table body
			$order_table .= 
				'<tr>
					<td>'.$product_arr['NAME'].'</td>
					<td>'.$product_arr['QUANTITY'].'</td>
					<td>'.SaleFormatCurrency($product_arr["PRICE"]*$product_arr["QUANTITY"], BASE_CURRENCY).'</td>
				 </tr>';
		} 
		
		if(count($products_arr)>0)
		{    //Get USER
			$rsUser = CUser::GetByID($item['USER_ID']); 
			$arUser = $rsUser->Fetch();
			
			//If exist in iblock don't sending again
			if( $arUser['ID'] >0 and count(getSendedBasketsFromIblock(array('ID'),array('IBLOCK_ID'=>AWAY_BASKET_IBLOCK,'>=PROPERTY_DATE' => \Bitrix\Main\Type\DateTime::createFromTimestamp((time() - (HOVERS_TO * 3600))),'PROPERTY_USER_ID' => $arUser['ID'],'FUSER_ID'=>$item['FUSER_ID']))) >0) continue;

			//Sending 
			if(filter_var($arUser['EMAIL'], FILTER_VALIDATE_EMAIL))
			{	
				$data = array(
					'EMAIL_TO' =>  $arUser['EMAIL'],
					'ORDER_TABLE' => $order_table,   
					'ORDER_USER' => $arUser['NAME'], 
					'EMAIL' => $arUser['EMAIL'], 
					'PRICE' => SaleFormatCurrency($price, BASE_CURRENCY), 
				); 
			
				if(count(sendMessage($data, EMAILING_TYPE, TEMPLATE_ID) >0))
				{	
					//Additing to iblock
					if(addSendingBasketInIblock(array('IBLOCK_ID'=>AWAY_BASKET_IBLOCK, 'DATE'=> time(), 'EMAIL'=>$arUser['EMAIL'], 'USER_ID'=>$arUser['ID'],'FUSER_ID'=>$item['FUSER_ID']))['status'])
					{
						//Writing to log
						WriteToLog('+ BASKET_ID: '.$item['FUSER_ID'].'  - sended: '.$arUser['EMAIL'].' (Date: '.date('d-m-Y H:i:s',time()).', InsertDate: '.$item['DATE_INSERT'].')', false, false, false, true, "away_basket_log", $_SERVER['DOCUMENT_ROOT']."/log/away_basket/");
						echo '+ BASKET_ID: '.$item['FUSER_ID'].'  - sended: '.$arUser['EMAIL'].'<br/>'; 
					}
				}
			}
			unset($arUser);
		}
		unset($products_arr);
		unset($order_table);
}
unset($baskets_array);

function getBasketByFuserId($FUSER_ID = 0)
{
	if (!CModule::IncludeModule("sale")) return;
	
	$result = array();
	$dbBasketItems = CSaleBasket::GetList(
			array(
					"ID" => "DESC"
				),
			array(
					"FUSER_ID" => $FUSER_ID ,
					"LID" => SITE_ID, 
					"ORDER_ID" => "NULL",
					"CAN_BUY"=>'Y',
					"DELAY"=>'N',
				), 
			false,
			false,
			array("ID","PRODUCT_ID","PRICE","QUANTITY","NAME","FUSER_ID","ORDER_ID","USER_ID")
		);
	while ($arItem = $dbBasketItems->Fetch())
	{	 
		array_push($result, $arItem);
	} 
	return $result;
}

function getBasketsByCreateDateRang($time_from = null, $time_to = null)
{
	if (!CModule::IncludeModule("sale")) return array('error' => 'No iblock module!', 'status'=>false);
	
	$result = array();
	$dbBasketItems = CSaleBasket::GetList(
			array( 
				"ID" => "ASC" 
				),
			array(
				"LID" => SITE_ID,  
				"ORDER_ID" => "NULL",
				"CAN_BUY"=>'Y',
				"DELAY"=>'N',
				"<=DATE_INSERT" => \Bitrix\Main\Type\DateTime::createFromTimestamp( $time_from ),  
				">=DATE_INSERT" => \Bitrix\Main\Type\DateTime::createFromTimestamp( $time_to ), 
				), 
			array(
				"FUSER_ID", 
				"USER_ID", 
				"DATE_INSERT"
				),
			false,
			array( "USER_ID" )
		);
		
	while ($arItem = $dbBasketItems->Fetch())
	{	 
		array_push($result, $arItem);
	} 
	return $result;
}

function addSendingBasketInIblock($data = array())
{	  
	if(!CModule::IncludeModule("iblock")) return array('error' => 'No iblock module!', 'status'=>false);
			
	$el = new CIBlockElement;
					
	$prop = array();
	foreach ($data as $key=>$item)
		{
			$prop[$key] = $item;
		} 

	$order = Array(
		"NAME"    => 'BASKET SENDED TO: EMAIL: '. $prop['EMAIL'].', DATE: '.date('d-m-Y, H:i:s',$prop['DATE']).',  USER_ID:'.$prop['USER_ID'], 
		"MODIFIED_BY"    =>  $prop['USER_ID'], 
		"IBLOCK_SECTION_ID" => false,
		"IBLOCK_ID"      => $prop['IBLOCK_ID'],  
		"PROPERTY_VALUES" => $prop, 
	);
	if($ID = $el->Add($order, false, false, true))
		{
			return  array('error' => '', 'status'=>true);
		}else
		{			
			return array('error' =>  $el->LAST_ERROR, 'status'=>false);
		}
} 

function getSendedBasketsFromIblock($arSelect = array(),$arFilter = array())
{	 
	if(!CModule::IncludeModule("iblock")) return array('error' => 'No iblock module!', 'status'=>false);
				
	$el = new CIBlockElement;
	$arFilterNew = Array(
		"IBLOCK_SECTION_ID" => false,
		"IBLOCK_ID"      => $arFilter['IBLOCK_ID'],  
	);
					
	$arFilterNew = array_merge($arFilter, $arFilterNew);
	unset($arFilter);
			 
	if($res = $el->GetList(Array("SORT"=>"ASC"), $arFilterNew, false, false, $arSelect))
		{
			$result = array();
			while($ob = $res->GetNext())
			{ 
				array_push($result, $ob);
			} 
						
			return $result;
		}else
		{
			return array('error' =>  $el->LAST_ERROR, 'status'=>false); 
		}
}

function sendMessage($data, $event, $templateId = null)
{
	return CEvent::Send($event,  'vi', $data, "N", $templateId);
}?>
к содержанию ↑

Создаем тип почтового события

Теперь можем создать тип почтового события, вот например:

Описание (доступные макросы):
#ORDER_USER# — заказчик
#PRICE# — сумма заказа
#EMAIL# — E-Mail заказчика
#ORDER_TABLE# — таблица заказа

Создаем тип почтового события Битрикс

Создаем тип почтового события Битрикс

к содержанию ↑

Создаем почтовый шаблон

Настало время создать почтовый шаблон для ранее созданного типа почтового события, который назвали «AwayBasketMailSend»

Создание почтового шаблона Битрикс

Создание почтового шаблона Битрикс

к содержанию ↑

Как пользоваться и настройка

Для того что бы запустить данный скрипт, достаточно открыть его в браузере по адресу: http://domain.net/ajax/away_basket.php, ну конечно же это для теста что все работает. Если вы получили картину после запуска примерно такого плана, тогда все отлично!

Результат работы скрипта брошенной корзины для Битрикс

Результат работы скрипта брошенной корзины для Битрикс

к содержанию ↑

Настроим cron задачу

Можно поставить запрос на каждый час данную команду:
wget http://domain.net/ajax/away_basket.php

[Всего голосов: 2    Средний: 4.5/5]

Привет, дорогой гость!

Я веб-разработчик, а этот сайт - мой блог. Отвечу на Ваши вопросы в комментариях :) По поводу сотрудничества сюда