Давненько я не ругал Битрикс, наверное, с тех пор, как уволился из ТАИСа. С тех пор прошло много времени, и уже более полугода я работаю в студии Гринсайт и имею дело с Битриксом. Я достаточно уже натерпелся, но молчал. Правда, один раз я всё же высказал:
- Будь проклят тот день, когда я согласился делать «РосЯму» на Битриксе!
Это связано с тем, что часть данных сессии пользователя не обновляются до тех пор, пока пользователь не разлогинится и не залогинится снова. В частности, если администратор забанил пользователя, то, пока сессия пользователя жива, он не чувствует себя забаненным. Если он разлогинится то, конечно, потом залогинится не сможет, но, пока он залогинен, он может продолжать вовсю безобразничать, несмотря на то, что уже в БД стоит пометка, что он забанен. А проверка его сессии показывает, что он активен; лазать же на каждый пук пользователя в БД и проверять, не забанен ли он, часом, чтоб разрешить ему пукнуть, приходится разработчикам сторонних компонентов — во время проверки валидности сессии этого сделать, оказывается, ну никак нельзя, лишний запрос к базе данных ведь, кошмар и ужас! Я забыл про эту особенность битрикса (хотя, конечно, я бы назвал это критической прорехой в безопасности и разогнал бы ссаными тряпками коллектив разработчиков и менеджеров, который уже столько лет не может ничего придумать, чтоб её заткнуть), и когда на «РосЯму» навалились боты, постящие сиськи и прочую зоонекропедофилию, приходилось делать следующее:
1) смотреть, под каким логином ходит бот,
2) удалять пользователя с таким логином,
3) очень быстро, в соседней вкладке, чтоб бот не успел зарегистрироваться по-новой, создавать пользователя с таким же логином и емейлом. Теперь сессия бота слетала, а зарегистрироваться по-новой он не мог.
И теперь снова здорово! Битрикс подкладывает очередную свинью, на сей раз — в своём гениальном творении под названием «инфоблоки». Тормозной и неудобный в силу своей универсальности механизм хранения каких-нибудь данных, эдакая реализация реляционной БД в админке. Как вы думаете, что делает следующий код:
foreach($_models as $manufacturer => $_cars)
{
$id = $cibs->Add
(
array
(
'IBLOCK_ID' => $_iblocks['CAR_MODELS'],
'ACTIVE' => 'Y',
'NAME' => iconv('cp1251', 'utf8', $manufacturer),
'SORT' => 100
)
);
foreach($_cars as $car)
{
$cibe->Add
(
array
(
'NAME' => iconv('cp1251', 'utf8', $car),
'ACTIVE' => 'Y',
'IBLOCK_SECTION_ID' => $id,
'IBLOCK_ID' => $_iblocks['CAR_MODELS']
)
);
}
}
Я тоже некоторое время думал, что он создаёт секции инфоблоков и в каждой создаёт элементы. В принципе, на первый взгляд так и есть, но есть нюанс. Оказывается, этот кусочек кода не создал новый элемент в том случае, если уже есть в соседней категории элемент с таким же названием, а пометил его входящим и во вторую категорию тоже. Таким образом, элемент с названием «3» входит одновременно в категории «BMW» и «Mazda». Это на самом деле не очень удобно и не очень хорошо. Экономия на спичках получается, если вспомнить, что запросы к БД, чтоб выбрать элемент инфоблока, очень громоздкие с кучей джойнов. А с той таблицей ещё один джойн получается дополнительный, так что экономией даже и не пахнет, вообще-то. С трудом могу предположить причину такой особенности инфоблоков.
У самого элемента инфоблока есть поле IBLOCK_SECTION_ID, в котором проставлена одна категория. Оказывается, есть ещё одна таблица с названием b_iblock_section_element, в которой дополнительно указана привязка элементов к секциям. К сожалению, в официальной документации этот момент как-то не особо хорошо освещён, поэтому дальше — только моё предположение: если при создании элемента инфоблока передавать не $id, а array($id), то привязка будет осуществлена только к одной желаемой категории.
Хочется выругаться на разработчиков Битрикса и их технических писаталей как-нибудь вроде «ёбаная пидарасня». Пойду придумывать, как исправить.