Last active
December 7, 2023 12:46
-
-
Save EscApp2/0af0ecf1c274fbd6b20681f1191c46bb to your computer and use it in GitHub Desktop.
favorite, favorite class for bitrix| favorites v2 на свойстве UF_FAVORITES
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<? | |
define("NO_KEEP_STATISTIC", true); // Не собираем стату по действиям AJAX | |
require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_before.php"); | |
$action = (string)$_REQUEST['action']; | |
if($action == "addToFav"){ | |
$id = (int)$_REQUEST['id']; | |
if($id>0){ | |
nav_favorite::addToFav($id); | |
} | |
$return = array(); | |
$favItems = nav_favorite::getFavItems(); | |
$return['count'] = count($favItems); | |
echo CUtil::PhpToJSObject($return); | |
die(); | |
} | |
if($action == "removeFromFav"){ | |
$id = (int)$_REQUEST['id']; | |
if($id>0){ | |
nav_favorite::removeFromFav($id); | |
} | |
$return = array(); | |
$favItems = nav_favorite::getFavItems(); | |
$return['count'] = count($favItems); | |
echo CUtil::PhpToJSObject($return); | |
die(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<? | |
class nav_favorite{ | |
const iblock_id = 19; | |
const cookie = "FAV_ID"; | |
const prefix = "FAV_CUSTOM"; | |
function init(){ | |
//pre($_SESSION[self::prefix][self::cookie]); | |
//die(); | |
//if( | |
//!isset($_SESSION[self::prefix][self::cookie]) || | |
//!is_array($_SESSION[self::prefix][self::cookie]) | |
//){ | |
global $USER; | |
global $APPLICATION; | |
$Cookie_full = false; | |
//if(!isset($_SESSION[self::prefix][self::cookie])){ | |
$Cookie = $APPLICATION->get_cookie(self::cookie,self::prefix); | |
$arCookie = unserialize($Cookie); | |
if(!is_array($arCookie)){ | |
$arCookie = array(); | |
} | |
if(empty($arCookie)){ | |
$_SESSION[self::prefix][self::cookie] = array(); | |
}else{ | |
$Cookie_full = true; | |
$_SESSION[self::prefix][self::cookie] = $arCookie; | |
} | |
//} | |
if($USER->IsAuthorized()){ | |
if($Cookie_full){ | |
//pre('cookies_full'); | |
$CookieFavItems = $_SESSION[self::prefix][self::cookie]; | |
//pre($CookieFavItems); | |
$arFilter = array(); | |
$arFilter['PROPERTY_USER_ID'] = $USER->GetID(); | |
$_SESSION[self::prefix][self::cookie] = self::getFavItemsFromIblock($arFilter); | |
//pre($_SESSION[self::prefix][self::cookie]); | |
foreach($CookieFavItems as $ItemId){ | |
self::addToFav($ItemId); | |
} | |
$APPLICATION->set_cookie(self::cookie, serialize(array()), false, "/",false, false ,true ,self::prefix); | |
}else{ | |
$arFilter = array(); | |
$arFilter['PROPERTY_USER_ID'] = $USER->GetID(); | |
$_SESSION[self::prefix][self::cookie] = self::getFavItemsFromIblock($arFilter); | |
} | |
} | |
//} | |
//pre($_SESSION[self::prefix][self::cookie]); | |
} | |
function debug(){ | |
global $APPLICATION; | |
$Cookie = $APPLICATION->get_cookie(self::cookie,self::prefix); | |
$ar = array( | |
"session"=>$_SESSION[self::prefix][self::cookie], | |
"cookie"=> $Cookie, | |
"cookie_array"=>unserialize($Cookie), | |
); | |
return $ar; | |
} | |
function getFavItemsFromIblock($arFilter){ | |
$FavItems = array(); | |
if(CModule::IncludeModule('iblock')){ | |
$arFilter['IBLOCK_ID'] = self::iblock_id; | |
$res_elem = CIBlockElement::GetList( | |
array(), | |
$arFilter, | |
false, | |
false, | |
array("ID","IBLOCK_ID","CODE","NAME","PROPERTY_PRODUCT_ID")); | |
while($ar_elem = $res_elem->Fetch()){ | |
if(!empty($ar_elem["PROPERTY_PRODUCT_ID_VALUE"])){ | |
$FavItems[] = $ar_elem["PROPERTY_PRODUCT_ID_VALUE"]; | |
} | |
} | |
} | |
return $FavItems; | |
} | |
/* get */ | |
function getFavItems(){ | |
return self::getFavItemsFromSession(); | |
} | |
function getFavItemsFromSession(){ | |
return $_SESSION[self::prefix][self::cookie]; | |
} | |
/* is */ | |
function isInFav($ItemId){ | |
$FavItems = self::getFavItemsFromSession(); | |
if(in_array($ItemId,$FavItems)){ | |
return true; | |
} | |
return false; | |
} | |
/* add */ | |
function addToFav($ItemId){ | |
if(empty($ItemId)){ | |
return false; | |
} | |
if(self::isInFav($ItemId)){ | |
return true; | |
} | |
global $USER; | |
if($USER->IsAuthorized()){ | |
return self::addToFavIblock($ItemId); | |
}else{ | |
return self::addToFavCookie($ItemId); | |
} | |
} | |
function addToFavIblock($ItemId){ | |
if(CModule::IncludeModule('iblock')){ | |
$el = new CIBlockElement; | |
global $USER; | |
$arFields = array( | |
"NAME"=>"favorite_".randString(10), | |
"CODE"=>"favorite_".randString(10), | |
"IBLOCK_ID"=>self::iblock_id, | |
"PROPERTY_VALUES" => array( | |
"USER_ID"=>$USER->GetID(), | |
"PRODUCT_ID"=>$ItemId, | |
), | |
); | |
$bool = $el->Add($arFields); | |
if($bool){ | |
$_SESSION[self::prefix][self::cookie][] = $ItemId; | |
return true; | |
}else{ | |
return false; | |
} | |
} | |
} | |
function addToFavCookie($ItemId){ | |
//pre('addToFavCookie'); | |
$FavItems = self::getFavItems(); | |
//pre($FavItems); | |
$FavItems[] = $ItemId; | |
self::setFavItemsCookie($FavItems); | |
return true; | |
} | |
function setFavItemsCookie($FavItems){ | |
$cookie = serialize($FavItems); | |
global $APPLICATION; | |
$APPLICATION->set_cookie(self::cookie, $cookie, false, "/",false, false ,true ,self::prefix); | |
$_SESSION[self::prefix][self::cookie] = $FavItems; | |
return true; | |
} | |
/* remove */ | |
function removeFromFav($ItemId){ | |
if(empty($ItemId)){ | |
return false; | |
} | |
if(!self::isInFav($ItemId)){ | |
return true; | |
} | |
global $USER; | |
if($USER->IsAuthorized()){ | |
return self::removeFromFavIblock($ItemId); | |
}else{ | |
return self::removeFromFavCookie($ItemId); | |
} | |
} | |
function removeFromFavCookie($ItemId){ | |
$FavItems = self::getFavItems(); | |
foreach($FavItems as $key=>$item){ | |
if($item == $ItemId){ | |
unset($FavItems[$key]); | |
} | |
} | |
self::setFavItemsCookie($FavItems); | |
return true; | |
} | |
function removeFromFavSession($ItemId){ | |
$FavItems = self::getFavItems(); | |
foreach($FavItems as $key=>$item){ | |
if($item == $ItemId){ | |
unset($FavItems[$key]); | |
} | |
} | |
$_SESSION[self::prefix][self::cookie] = $FavItems; | |
return true; | |
} | |
function removeFromFavIblock($ItemId){ | |
if(CModule::IncludeModule('iblock')){ | |
$el = new CIBlockElement; | |
global $USER; | |
$FavItems = array(); | |
if(CModule::IncludeModule('iblock')){ | |
$arFilter = array(); | |
$arFilter['IBLOCK_ID'] = self::iblock_id; | |
$arFilter['PROPERTY_USER_ID'] = $USER->GetID(); | |
$arFilter['PROPERTY_PRODUCT_ID'] = $ItemId; | |
$res_elem = CIBlockElement::GetList( | |
array(), | |
$arFilter, | |
false, | |
false, | |
array("ID")); | |
if($ar_elem = $res_elem->Fetch()){ | |
$bool = CIBlockElement::Delete($ar_elem['ID']); | |
if($bool){ | |
self::removeFromFavSession($ItemId); | |
return true; | |
} | |
} | |
} | |
} | |
return false; | |
} | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<? | |
/* | |
1)В шаблоны каталога и карточки товаров добавить js_favorite и data-id | |
2)В коде указать FAVORITES_PAGE и как определить товар в функции setUserUnFavorites | |
3)В скрипте шаблонов добавить правки к событиям onCatalogSectionChangeOffer (создать) и onCatalogElementChangeOffer(изменить) | |
4)У пользователя создать UF_FAVORITES | |
5) В хедере добавить js_favorite_count если нужно показывать количество и вывести count(getFavorites()) | |
*/ | |
AddEventHandler('main', 'OnProlog', 'includeFavorites',99999); | |
function includeFavorites() { | |
global $APPLICATION; | |
$dir = $APPLICATION->GetCurDir(); | |
if(strpos($dir, '/bitrix/admin/') !== false){ | |
return true; | |
} | |
if(strpos($dir, '/bitrix/gadgets/') !== false){ | |
return true; | |
} | |
if(strpos($dir, '/upload/') !== false){ | |
return true; | |
} | |
if(defined('ADMIN_SECTION')){ | |
return true; | |
} | |
if( | |
!empty($_SERVER['HTTP_X_REQUESTED_WITH']) | |
&& strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest' | |
){ | |
return true; | |
} | |
if($_SERVER['REQUEST_METHOD'] != "GET"){ | |
return true; | |
} | |
ob_start(); | |
?><script class="includeFavorites" > | |
(function(window) { | |
var __favorites = { | |
init:function(){ | |
let that = this; | |
that.AJAX_FAVORITES = []; | |
that.FAVORITES_PAGE = "/wishlist/"; | |
that.__debounce_fn_timer = false; | |
that.makeGetUserAjaxFavorites(function(){ | |
$(document).ready(function(){ | |
that.render(); | |
$(document).off('click', '.js_favorite'); | |
$(document).on('click', '.js_favorite', function(){ | |
that.makeUserFavoritesAction($(this).attr('data-id')); | |
}); | |
}); | |
}); | |
return that; | |
}, | |
isItemInFavorites: function (product_id){ | |
let elements = this.getUserFavorites(); | |
if(jQuery.inArray(parseInt(product_id), elements) !== -1){ | |
return true; | |
} | |
return false; | |
}, | |
setUserFavorites: function (product_id){ | |
product_id = parseInt(product_id); | |
if(!!product_id){ | |
this.AJAX_FAVORITES.push(product_id); | |
window.FAVORITES.render(product_id); | |
this.makeSaveUserAjaxFavorites(); | |
} | |
}, | |
setUserUnFavorites: function (product_id){ | |
let that = this; | |
product_id = parseInt(product_id); | |
if(!!product_id){ | |
var toRemove = [product_id]; | |
this.AJAX_FAVORITES = this.AJAX_FAVORITES.filter(function(el){ | |
return toRemove.indexOf( el ) < 0; | |
}); | |
window.FAVORITES.render(product_id); | |
if(window.location.pathname == that.FAVORITES_PAGE){ | |
$('.js_favorite[data-id='+product_id+']').closest('[data-entity="item"]').fadeOut(); | |
} | |
this.makeSaveUserAjaxFavorites(); | |
} | |
}, | |
makeUserFavoritesAction:function (product_id){ | |
let that = this; | |
if(that.isItemInFavorites(product_id)){ | |
that.setUserUnFavorites(product_id); | |
}else{ | |
that.setUserFavorites(product_id); | |
} | |
}, | |
getUserFavorites: function (){ | |
return this.AJAX_FAVORITES; | |
}, | |
makeGetUserAjaxFavorites: function (callback){ | |
let that = this; | |
$.ajax({ | |
url: '/ajax/index.php', | |
type: "post", | |
dataType: "json", | |
data: {'module':'favorites',"action": "get_user_favorites"}, | |
cache : false, | |
}).done(function(json){ | |
that.AJAX_FAVORITES = json; | |
$(document).ready(function(){ | |
if(!!callback){ | |
callback.apply(that); | |
} | |
}); | |
}).fail(function( jqXHR, textStatus, errorThrown){ | |
}).always(function( jqXHR, textStatus, errorThrown){ | |
}); | |
}, | |
debounce: function(callback, waitTimeMS) { | |
let that = this; | |
return function(...args){ | |
clearTimeout(that.__debounce_fn_timer); | |
that.__debounce_fn_timer = setTimeout(() => { | |
callback(...args); | |
}, waitTimeMS); | |
}; | |
}, | |
makeSetUserAjaxFavorites: function (callback){ | |
let that = window.FAVORITES; | |
let $a = $.ajax({ | |
url: '/ajax/index.php', | |
type: "post", | |
dataType: "json", | |
data: {'module':'favorites', "action": "set_user_favorites", 'ids':that.AJAX_FAVORITES }, | |
cache : false, | |
}).done(function(json){ | |
//that.AJAX_FAVORITES = json; | |
var count = window.FAVORITES.AJAX_FAVORITES.length | |
$('.js_favorite_count').html(count); | |
$(document).ready(function(){ | |
if(!!callback){ | |
callback.apply(that); | |
} | |
}); | |
}).fail(function( jqXHR, textStatus, errorThrown){ | |
}).always(function( jqXHR, textStatus, errorThrown){ | |
}); | |
}, | |
makeSaveUserAjaxFavorites: function (){ | |
let that = this; | |
that.debounce(that.makeSetUserAjaxFavorites ,500).call(that); | |
}, | |
render: function(product){ | |
let that = this; | |
let selector = ".js_favorite"; | |
if(!!product){ | |
selector = ".js_favorite[data-id='"+product+"']"; | |
} | |
$(selector).each(function(){ | |
let product_id = $(this).attr('data-id'); | |
if(!!product_id){ | |
if(that.isItemInFavorites(product_id)){ | |
$(this).addClass('active'); | |
}else{ | |
$(this).removeClass('active'); | |
} | |
} | |
}) | |
} | |
} | |
if(!window.FAVORITES){ | |
window.FAVORITES = __favorites.init(); | |
BX.addCustomEvent('onCatalogSectionChangeOffer', function(eventData, offer, element){ | |
if(!!element){ | |
$('#'+element.visual.ID).find('.js_favorite').attr('data-id',eventData.newId); | |
setTimeout(function(){ | |
window.FAVORITES.render(eventData.newId); | |
},10); | |
} | |
}); | |
BX.addCustomEvent('onCatalogElementChangeOffer', function(eventData, offer, element){ | |
if(!!element){ | |
$('#'+element.visual.ID).find('.js_favorite').attr('data-id',eventData.newId); | |
setTimeout(function(){ | |
window.FAVORITES.render(eventData.newId); | |
},10); | |
} | |
}); | |
} | |
})(window); | |
</script><? | |
$HTML = ob_get_contents(); | |
ob_end_clean(); | |
\Bitrix\Main\Page\Asset::getInstance()->addString( | |
$HTML, | |
true, | |
\Bitrix\Main\Page\AssetLocation::AFTER_JS, | |
null | |
); | |
/* | |
changeInfo: function() | |
{ | |
var index = -1, | |
j = 0, | |
boolOneSearch = true, | |
------add--------- | |
eventData = { | |
currentId: (this.offerNum > -1 ? this.offers[this.offerNum].ID : 0), | |
newId: 0 | |
}; | |
------add end--------- | |
..... | |
this.offerNum = index; | |
------add--------- | |
eventData.newId = this.offers[this.offerNum].ID; | |
// only for compatible catalog.store.amount custom templates | |
BX.onCustomEvent('onCatalogStoreProductChange', [this.offers[this.offerNum].ID]); | |
// new event | |
BX.onCustomEvent('onCatalogElementChangeOffer', [eventData, this.offers[this.offerNum],this]); | |
BX.onCustomEvent('onCatalogSectionChangeOffer', [eventData, this.offers[this.offerNum],this]); | |
eventData = null; | |
------add end--------- | |
*/ | |
} | |
AddEventHandler('main', 'OnAjaxPageActionExec', 'favoritesActions'); | |
function favoritesActions($module, $ajax_action, $action, $obRequest, $arRequest){ | |
global $APPLICATION; | |
if($module == "favorites"){ | |
if($action == "get_user_favorites"){ | |
$favorites = getFavorites('UF_FAVORITES','favorites'); | |
header('Content-Type: application/json'); | |
echo json_encode($favorites); | |
}elseif($action == "set_user_favorites"){ | |
global $USER; | |
$IDs = $arRequest['ids']; | |
if(empty($IDs)){ | |
$IDs = array(); | |
} | |
if(!$USER->IsAuthorized()) { | |
$context = Bitrix\Main\Application::getInstance()->getContext(); | |
$cookie = new \Bitrix\Main\Web\Cookie("favorites" , json_encode($IDs), time()+86400*30); | |
$cookie->setPath("/"); // путь | |
$context->getResponse()->addCookie($cookie); | |
}else{ | |
$idUser = $USER->GetID(); | |
$USER->Update($idUser, ["UF_FAVORITES" => $IDs]); | |
clearActiveFavoritesCache(); | |
} | |
$addResult = array('STATUS' => 'OK'); | |
header('Content-Type: application/json'); | |
echo json_encode($addResult); | |
} | |
} | |
} | |
// данные из сессии в бд | |
AddEventHandler("main", "OnAfterUserAuthorize", "favoriteFromCookiesToDB"); | |
function favoriteFromCookiesToDB($arFields){ | |
$arUser = $arFields['user_fields']; | |
if($arUser['ID']>0){ | |
global $USER; | |
$user_id = $arUser['ID']; | |
$codeUser='UF_FAVORITES'; | |
$codeCookie='favorites'; | |
$favorites_cook = json_decode(Bitrix\Main\Application::getInstance()->getContext()->getRequest()->getCookie($codeCookie),1); | |
if (!$favorites_cook) $favorites_cook = []; | |
$rsUser = CUser::GetByID($user_id); | |
$arUser = $rsUser->Fetch(); | |
$favorites = $arUser[$codeUser]; | |
if (!$favorites) $favorites = []; | |
$favorites = array_merge($favorites,$favorites_cook); | |
$favorites = array_unique($favorites); | |
$USER->Update($user_id, [$codeUser => $favorites]); | |
// удалить куки | |
$context = Bitrix\Main\Application::getInstance()->getContext(); | |
$cookie = new \Bitrix\Main\Web\Cookie("favorites" , json_encode(array()), time()-86400*30); | |
$cookie->setPath("/"); // путь | |
$context->getResponse()->addCookie($cookie); | |
} | |
} | |
if(!function_exists('getFavorites')){ | |
function getFavorites($codeUser='UF_FAVORITES', $codeCookie='favorites',$withOutActiveCheck = false) | |
{ | |
global $USER; | |
$favorites = []; | |
if(!$USER->IsAuthorized()) { | |
$favorites = json_decode(Bitrix\Main\Application::getInstance()->getContext()->getRequest()->getCookie($codeCookie),1); | |
} else { | |
$idUser = $USER->GetID(); | |
$rsUser = CUser::GetByID($idUser); | |
$arUser = $rsUser->Fetch(); | |
$favorites = $arUser[$codeUser]; | |
} | |
if (!$favorites) $favorites = []; | |
if(!$withOutActiveCheck){ | |
$favorites = getActiveFavorites($favorites); | |
} | |
$favorites = array_map('intval', $favorites); | |
return $favorites; | |
} | |
} | |
if(!function_exists('getActiveFavorites')){ | |
function getActiveFavorites($favorites) | |
{ | |
global $USER; | |
$user_id = $USER->GetID(); | |
$IBLOCK_ID = MAIN_CATALOG__PRODUCTS; | |
return wrapPhpCache( | |
array( | |
'name'=>'getActiveFavorites', | |
'tag'=>array( | |
"user_".$user_id."__active_favorites_".SITE_ID, | |
$IBLOCK_ID, | |
), | |
'time'=>24*3600, | |
), | |
function($favorites, $IBLOCK_ID){ | |
if(count($favorites)>0){ | |
$ar_active_favorites = array(); | |
$arOffersId = array(); | |
CModule::IncludeModule('catalog'); | |
CModule::IncludeModule('iblock'); | |
$arProductsIds = array(); | |
$arFavorites = array_combine($favorites,$favorites); | |
$favWithProducts = $favorites; | |
$catalogInfo = CCatalogSku::GetInfoByIBlock($IBLOCK_ID); | |
$SKU_IBLOCK_ID = $catalogInfo['IBLOCK_ID']; | |
$PRODUCT_IBLOCK_ID = $catalogInfo['PRODUCT_IBLOCK_ID']; | |
$arOfferToProduct = CCatalogSku::getProductList($favorites); | |
foreach($arOfferToProduct as $offer_id=>$arData){ | |
$favWithProducts[] = $arData['ID']; | |
} | |
$arResult = array(); | |
$res = \Bitrix\Iblock\ElementTable::getList(array( | |
'select'=>array('ID','ACTIVE', "CATALOG_TYPE"=>'CATALOG.TYPE'), | |
'filter'=>array('ID'=>$favWithProducts, "IBLOCK_ID"=>array($SKU_IBLOCK_ID,$PRODUCT_IBLOCK_ID)), | |
'runtime'=>array( | |
'CATALOG' => array( | |
'data_type' => 'Bitrix\Catalog\ProductTable', | |
'reference' => array('=this.ID' => 'ref.ID'), | |
) | |
), | |
'cache' => array( | |
'ttl' => 24*60*60, | |
'cache_joins' => true, | |
) | |
)); | |
while($ar = $res->fetch()){ | |
if($ar['CATALOG_TYPE'] == \Bitrix\Catalog\ProductTable::TYPE_OFFER){ | |
$arOffers[$ar['ID']] = $ar; | |
}else{ | |
if($ar['ACTIVE'] == "Y"){ | |
$arProducts[$ar['ID']] = $ar; | |
} | |
} | |
} | |
// если нет товара, значит он неактивный, значит убираем ТП | |
foreach($arOfferToProduct as $offer_id=>$arData){ | |
$product_id = $arData['ID']; | |
if(!$arProducts[$product_id]){ | |
unset($arFavorites[$offer_id]); | |
} | |
} | |
foreach($arFavorites as $offer_or_product_id){ | |
if(!$arOffers[$offer_or_product_id] && !$arProducts[$offer_or_product_id]){ | |
unset($arFavorites[$offer_or_product_id]); | |
} | |
} | |
$favorites = array_values($arFavorites); | |
} | |
return $favorites; | |
}, | |
array($favorites, $IBLOCK_ID) | |
); | |
} | |
} | |
if(!function_exists('clearActiveFavoritesCache')){ | |
function clearActiveFavoritesCache(){ | |
global $USER; | |
$user_id = $USER->GetID(); | |
$taggedCache = \Bitrix\Main\Application::getInstance()->getTaggedCache(); | |
$taggedCache->clearByTag("user_".$user_id."__active_favorites_".SITE_ID); | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment