Development of the 1C-Bitrix Favorites module

Our company is engaged in the development, support and maintenance of Bitrix and Bitrix24 solutions of any complexity. From simple one-page sites to complex online stores, CRM systems with 1C and telephony integration. The experience of developers is confirmed by certificates from the vendor.
Our competencies:
Development stages
Latest works
  • image_website-b2b-advance_0.png
    B2B ADVANCE company website development
    1175
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Website development for FIXPER company
    811
  • image_bitrix-bitrix-24-1c_development_of_an_online_appointment_booking_widget_for_a_medical_center_594_0.webp
    Development based on Bitrix, Bitrix24, 1C for the company Development of an Online Appointment Booking Widget for a Medical Center
    564
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Development based on 1C Enterprise for MIRSANBEL
    747
  • image_crm_dolbimby_434_0.webp
    Website development on CRM Bitrix24 for DOLBIMBY
    655
  • image_crm_technotorgcomplex_453_0.webp
    Development based on Bitrix24 for the company TECHNOTORGKOMPLEKS
    976

Development of Wishlist Module for 1C-Bitrix

Standard Bitrix does not have a ready-made wishlist module for the catalog. There is the sale module with "delayed items" — they go into the cart with status Y in the DELAY field. This is not a wishlist: products are mixed with the cart logically and technically, there's no ability to create multiple lists, no support for guests with synchronization on login. Full-fledged wishlist is implemented as a separate module.

Data Storage

The module is located in local/modules/vendor.wishlist/. Two main tables:

Table b_wishlist — wishlist collections (a user can have multiple: "Want to buy", "Gifts", "Pending"):

Field Type Purpose
ID int auto_increment Primary key
USER_ID int User ID (NULL for guests)
SESSION_ID varchar(64) Guest session hash
TITLE varchar(255) List title
IS_PUBLIC tinyint(1) Can be shared by link
PUBLIC_HASH varchar(32) Unique hash for public URL
CREATED_AT datetime

Table b_wishlist_item:

Field Type Purpose
ID int auto_increment
LIST_ID int FK to b_wishlist
PRODUCT_ID int Product offer ID
ELEMENT_ID int Iblock element ID (parent product)
ADDED_AT datetime
NOTE text User's personal note about the product

Guest to Authenticated User Synchronization

When a user logs in, the OnAfterUserLogin event handler runs:

\Bitrix\Main\EventManager::getInstance()->addEventHandler(
    'main',
    'OnAfterUserLogin',
    [WishlistMerger::class, 'merge']
);

The merge method finds the anonymous list by SESSION_ID, transfers products from it to the user's main list (with duplicate check via SELECT before INSERT), then deletes the anonymous list. If the user doesn't have any list yet, the anonymous list is simply reassigned via UPDATE b_wishlist SET USER_ID = ?, SESSION_ID = NULL WHERE SESSION_ID = ?.

"Add to Wishlist" Button on Product Card

The button sends AJAX request to the vendor:wishlist.button component. The component accepts PRODUCT_ID and ACTION (add/remove/toggle), performs the operation and returns JSON with new state.

On catalog page, button states are initialized once: on page load, a single request returns array of PRODUCT_ID that current user already has in wishlist. JavaScript marks corresponding buttons without repeated server requests.

// Getting all product IDs in wishlist for current user
$items = WishlistItemTable::getList([
    'filter' => ['=LIST_ID' => $listId],
    'select' => ['PRODUCT_ID'],
])->fetchAll();

$productIds = array_column($items, 'PRODUCT_ID');

Public Lists and Sharing

Each list can be made public. In this case, PUBLIC_HASH is generated via \Bitrix\Main\Security\Random::getString(32). URL like /wishlist/share/abc123/ opens the list for any visitor in view mode. The viewer can add individual items to their cart, but cannot edit someone else's list.

The feature is useful for gift lists: a user compiles a desired gifts list and sends the link to relatives.

Price Drop Notifications

An optional but popular feature: if a product in wishlist gets cheaper, the user receives an email notification. Implemented via agent (\Bitrix\Main\Agent) or cron task:

  1. Agent runs daily, iterates unique PRODUCT_ID from b_wishlist_item.
  2. For each, gets current price via \CCatalogProduct::GetByID() or Price::getList().
  3. Compares with price saved in LAST_PRICE field (added to b_wishlist_item table).
  4. On price drop, sends email event WISHLIST_PRICE_DROP.

Counter in Header

Product count in wishlist is displayed in header. To avoid heavy query on every page load, counter is cached in $_SESSION['WISHLIST_COUNT'] and invalidated on each list change. Header component reads value from session — single PHP call without DB access.

Development Timeline

Scale Content Duration
Basic One list, DB storage, AJAX button, header counter 4–5 days
Standard + Guest/user merge, wishlist page in cabinet, multiple lists 7–10 days
Extended + Public lists, price drop notifications, list export 12–15 days