About us Guides Projects Contacts
Админка
please wait

Bitrix is a powerful enterprise CMS platform popular in Russia and Eastern Europe for building corporate websites, e-commerce platforms, and intranet solutions. While its learning curve is steep, mastering Bitrix development opens doors to enterprise projects with complex requirements. This guide covers essential Bitrix development patterns from a senior developer's perspective.

Why Bitrix

Bitrix offers compelling features for enterprise environments:

  1. All-in-One Platform: CMS, CRM, e-commerce in one system
  2. Information Blocks: Flexible content management structure
  3. Built-in Modules: Forums, blogs, e-commerce, workflows
  4. Enterprise Features: Clustering, caching, multi-site support
  5. Russian Market: Dominant CMS for the Russian enterprise sector

Understanding Information Blocks (Infoblocks)

Infoblocks are Bitrix's core data structure—think of them as configurable content types with properties, sections, and elements.

Structure Overview

Infoblock Type
└── Infoblock
├── Sections (categories)
└── Elements (content items)
└── Properties (custom fields)

Working with Infoblocks via API

<?php
// Include the Bitrix kernel
require_once($_SERVER["DOCUMENT_ROOT"] . "/bitrix/modules/main/include/prolog_before.php");
// Load the iblock module
CModule::IncludeModule("iblock");
// Get elements from the infoblock
$arFilter = array(
"IBLOCK_ID" => 5,
"ACTIVE" => "Y",
"SECTION_ID" => 10
);
$arSelect = array(
"ID",
"NAME",
"DETAIL_TEXT",
"PROPERTY_PRICE",
"PROPERTY_BRAND"
);
$res = CIBlockElement::GetList(
array("SORT" => "ASC"), // Order
$arFilter, // Filter
false, // Group
false, // Navigation
$arSelect // Select fields
);
while ($element = $res->GetNextElement()) {
$fields = $element->GetFields();
$props = $element->GetProperties();
echo $fields["NAME"] . ": " . $props["PRICE"]["VALUE"] . "<br>";
}
?>

Creating Infoblock Elements

<?php
CModule::IncludeModule("iblock");
$element = new CIBlockElement;
$arFields = array(
"IBLOCK_ID" => 5,
"IBLOCK_SECTION_ID" => 10,
"NAME" => "New Product",
"ACTIVE" => "Y",
"PREVIEW_TEXT" => "Short description",
"DETAIL_TEXT" => "Full product description",
"PROPERTY_VALUES" => array(
"PRICE" => 1999,
"BRAND" => "Samsung",
"FEATURES" => array("Feature 1", "Feature 2")
)
);
if ($elementId = $element->Add($arFields)) {
echo "Element created with ID: " . $elementId;
} else {
echo "Error: " . $element->LAST_ERROR;
}
?>

Copying Infoblock Properties and Forms

When you have multiple infoblocks of the same type and need to copy form configurations:

<?php
require_once($_SERVER["DOCUMENT_ROOT"] . "/bitrix/modules/main/bx_root.php");
require_once($_SERVER["DOCUMENT_ROOT"] . BX_PERSONAL_ROOT . "/modules/main/include/prolog_before.php");
if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED !== true) die();
CModule::IncludeModule("iblock");
if (intval($_REQUEST["IBLOCK_ID_FORMS"]) > 0 && !empty($_REQUEST["IBLOCK_TYPE_ID"])) {
$masterIblockId = intval($_REQUEST["IBLOCK_ID_FORMS"]);
$iblockTypeId = $_REQUEST["IBLOCK_TYPE_ID"];
// Get master infoblock properties
$masterProperties = array();
$dbProperties = CIBlockProperty::GetList(
array("sort" => "asc", "name" => "asc"),
array("ACTIVE" => "Y", "IBLOCK_ID" => $masterIblockId)
);
while ($property = $dbProperties->GetNext()) {
$masterProperties[$property['CODE']] = 'PROPERTY_' . $property['ID'];
}
// Settings to copy
$settings = array(
array('name' => 'form_element_#ID#', 'group' => 'form'),
array('name' => 'form_section_#ID#', 'group' => 'form'),
array('name' => 'tbl_iblock_list_#MD5#', 'group' => 'list'),
array('name' => 'tbl_iblock_element_#MD5#', 'group' => 'list'),
);
// Get settings from master
foreach ($settings as $key => $value) {
$name = str_replace(
array('#ID#', '#MD5#'),
array($masterIblockId, md5($iblockTypeId . "." . $masterIblockId)),
$value['name']
);
$settings[$key]['value'] = CUserOptions::GetOption($value['group'], $name);
}
// Apply to all infoblocks of the same type
$dbResult = CIBlock::GetList(
array(),
array('=TYPE' => $iblockTypeId, '!ID' => $masterIblockId),
true
);
while ($iblock = $dbResult->Fetch()) {
// Map property IDs
$search = array();
$replacement = array();
$dbProps = CIBlockProperty::GetList(
array("sort" => "asc"),
array("ACTIVE" => "Y", "IBLOCK_ID" => $iblock['ID'])
);
while ($prop = $dbProps->GetNext()) {
if (!empty($masterProperties[$prop['CODE']])) {
$search[] = $masterProperties[$prop['CODE']];
$replacement[] = 'PROPERTY_' . $prop['ID'];
}
}
// Copy settings with property mapping
foreach ($settings as $value) {
$name = str_replace(
array('#ID#', '#MD5#'),
array($iblock['ID'], md5($iblock['IBLOCK_TYPE_ID'] . "." . $iblock['ID'])),
$value['name']
);
$newValue = array();
foreach ($value['value'] as $k => $string) {
$newValue[$k] = str_replace($search, $replacement, $string);
}
CUserOptions::DeleteOption($value['group'], $name);
CUserOptions::SetOption($value['group'], $name, $newValue, true);
}
}
echo "Forms copied successfully!";
}
?>

Forum Administration

Bitrix includes a built-in forum module. Here's how to manage forum content programmatically.

Delete All Messages from a User

Useful for removing spam:

<?php
// Configuration
$badUserId = 29541;
// Delete the user's messages
$deleteMessages = "DELETE FROM b_forum_message WHERE author_id = $badUserId";
// Update topic metadata after deletion
$updateTopics = "UPDATE b_forum_topic as t
LEFT JOIN (
SELECT
MAX(gm.id) as id,
gm.topic_id,
MAX(gm.post_date) as post_date
FROM b_forum_message as gm
GROUP BY topic_id
) as g ON t.id = g.topic_id
LEFT JOIN b_forum_message as m ON m.id = g.id
SET
t.last_message_id = g.id,
t.last_poster_id = m.author_id,
t.last_poster_name = m.author_name,
t.last_post_date = g.post_date,
t.abs_last_message_id = g.id,
t.abs_last_poster_id = m.author_id,
t.abs_last_poster_name = m.author_name,
t.abs_last_post_date = g.post_date
WHERE t.abs_last_message_id <> g.id";
// Connect using Bitrix configuration
include $_SERVER["DOCUMENT_ROOT"] . '/bitrix/php_interface/dbconn.php';
$db = mysqli_connect($DBHost, $DBLogin, $DBPassword, $DBName);
mysqli_set_charset($db, 'utf8');
mysqli_query($db, $deleteMessages);
mysqli_query($db, $updateTopics);
echo "Spam removed and topics updated.";
?>

Component Development

Bitrix uses components for reusable functionality.

Basic Component Structure

/local/components/mycompany/mycomponent/
├── .description.php # Component metadata
├── .parameters.php # Input parameters definition
├── component.php # Main logic
├── class.php # OOP component class
└── templates/
└── .default/
├── template.php
├── style.css
└── script.js

Component Class Example

<?php
// /local/components/mycompany/product.list/class.php
if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED !== true) die();
use Bitrix\Main\Loader;
class ProductListComponent extends CBitrixComponent
{
protected function checkModules()
{
if (!Loader::includeModule('iblock')) {
throw new \Exception('Module iblock not installed');
}
}
protected function getProducts()
{
$products = array();
$filter = array(
"IBLOCK_ID" => $this->arParams["IBLOCK_ID"],
"ACTIVE" => "Y"
);
if (!empty($this->arParams["SECTION_ID"])) {
$filter["SECTION_ID"] = $this->arParams["SECTION_ID"];
}
$res = \CIBlockElement::GetList(
array("SORT" => "ASC"),
$filter,
false,
array("nPageSize" => $this->arParams["PAGE_SIZE"]),
array("ID", "NAME", "PREVIEW_PICTURE", "DETAIL_PAGE_URL")
);
while ($element = $res->GetNextElement()) {
$fields = $element->GetFields();
$fields["PROPERTIES"] = $element->GetProperties();
$products[] = $fields;
}
return $products;
}
public function executeComponent()
{
try {
$this->checkModules();
$this->arResult["PRODUCTS"] = $this->getProducts();
$this->includeComponentTemplate();
} catch (\Exception $e) {
ShowError($e->getMessage());
}
}
}
?>

D7 (Modern API)

Bitrix D7 is the modern ORM-based API:

<?php
use Bitrix\Main\Loader;
use Bitrix\Iblock\ElementTable;
Loader::includeModule('iblock');
// Query with D7
$elements = ElementTable::getList(array(
'select' => array('ID', 'NAME', 'IBLOCK_ID'),
'filter' => array(
'=IBLOCK_ID' => 5,
'=ACTIVE' => 'Y'
),
'order' => array('SORT' => 'ASC'),
'limit' => 10
));
while ($element = $elements->fetch()) {
echo $element['NAME'] . "<br>";
}
// Use DataManager for custom tables
use Bitrix\Main\Entity;
class MyCustomTable extends Entity\DataManager
{
public static function getTableName()
{
return 'my_custom_table';
}
public static function getMap()
{
return array(
'ID' => new Entity\IntegerField('ID', array(
'primary' => true,
'autocomplete' => true
)),
'NAME' => new Entity\StringField('NAME', array(
'required' => true
)),
'CREATED_AT' => new Entity\DatetimeField('CREATED_AT')
);
}
}
?>

Event Handlers

Register handlers for Bitrix events:

<?php
// /local/php_interface/init.php
AddEventHandler("iblock", "OnBeforeIBlockElementAdd", "MyOnBeforeElementAdd");
AddEventHandler("iblock", "OnAfterIBlockElementAdd", "MyOnAfterElementAdd");
function MyOnBeforeElementAdd(&$arFields)
{
// Validate or modify before save
if (empty($arFields["NAME"])) {
global $APPLICATION;
$APPLICATION->ThrowException("Name is required");
return false;
}
// Auto-generate code from name
$arFields["CODE"] = CUtil::translit(
$arFields["NAME"],
"ru",
array("replace_space" => "-", "replace_other" => "-")
);
return true;
}
function MyOnAfterElementAdd(&$arFields)
{
// Log or notify after save
CEventLog::Add(array(
"SEVERITY" => "INFO",
"AUDIT_TYPE_ID" => "IBLOCK_ELEMENT_ADD",
"MODULE_ID" => "iblock",
"ITEM_ID" => $arFields["ID"],
"DESCRIPTION" => "Element added: " . $arFields["NAME"]
));
}
?>

Caching

Bitrix provides powerful caching mechanisms:

<?php
$cacheTime = 3600; // 1 hour
$cacheId = "my_cache_" . $IBLOCK_ID . "_" . $SECTION_ID;
$cachePath = "/my_component/";
$cache = new CPHPCache();
if ($cache->InitCache($cacheTime, $cacheId, $cachePath)) {
// Get from cache
$vars = $cache->GetVars();
$arResult = $vars["arResult"];
} elseif ($cache->StartDataCache()) {
// Generate data
$arResult = getExpensiveData();
// Save to cache
$cache->EndDataCache(array("arResult" => $arResult));
}
?>

Key Takeaways

  1. Learn Infoblocks: Core of Bitrix content management
  2. Use the D7 API: Modern, ORM-based approach
  3. Component architecture: Reusable functionality units
  4. Event-driven: Extend behavior via handlers
  5. Cache aggressively: Essential for performance
  6. Database knowledge: Direct SQL is sometimes necessary

Bitrix has a steep learning curve but rewards investment with powerful enterprise capabilities—master these fundamentals and you'll handle complex Bitrix projects confidently.

 
 
 
Языки
Темы
Copyright © 1999 — 2026
ZK Interactive