Pull to refresh
2
0
Николаев Андрей @gromdron

PHP-программист (Bitrix)

Send message

Но мне очень интересно как вы будут работать со Смарт-процессами через старое АПИ. Не приведете пример?

Нет никакого старого api при работе со смарт-процессами, есть низкоуровневое api (использование datamanager). Есть старое API по работе со сделками/контактами/компаниями/лидами и новое api для crm. Не надо путать одно и другое.


Вы в вашей статье подаете метод $class::update как единственный способ по обновлению нескольких полей за одну операцию - это ошибка. Нет, если бы вы рассказали про обновление нескольких полей через массив используя compatible-функцию вопросов бы не было, но вы полезли в низкоуровневый update.

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

Вы не написали в статье что рассматриваете все способы (ни одного слова), но вы явно написали что рассматриваете "Базовые операции" - в заголовке статьи. Низкоуровневый update я никак не могут называть "базовым" методом. Отсюда считаю что это - ошибка.

Я не думаю что вы создаете задачи через internal tasktable add и не думаю что вы обновляете рабочие группы через workgrouptable, так почему здесь вы это допускаете?

Честно больше похоже на самопиар

Если честно - ваша статья больше похоже на "мне сказали написать, ну вот и написал" или "напишу что бы было". Мне не нужен пиар - кто захочет что-то найти по битриксу и так меня найдет. Здесь я выступаю в качестве noname с одной единственной целью - если вы хотите доносить реальные знания и наносить пользу сообществу разработчиков Битрикс24 - вы должны по крайней мере не наносить вред.

История из жизни. Сегодня (какое крутое совпадение) - я с коллегой разбирал случай - один из разработчиков использовал подход с $item->save(), а нам вернули задачу с ошибкой - элемент не ищется в фильтре по свойству с типом адрес. Проблема была в том, что поисковый индекс обновляется через операцию (либо кастомным кодом) и когда он выполнил $item->save() элемент добавился, а поиск не обновился. Пришлось переписывать решение и дописывать отдельный механизм индексации существующих элементов. Это был проиграммист с опытом работы, который почитал документацию, а тут вы выдаете это в статье за чистую монету без примечаний да еще и для новичков

Я не могу расценить эту статью за нанесение пользы, ведь после нее будут еще люди которые пойдут в техническую поддержку, на форум, в чаты по битрикс24 с невнятным описанием "битрикс г...но потому что не ищется".

А вот то что элемент обновляется а связи нет и это ой боже как плохо. Это спорно и то что это "плохо" - я не согласен. Не оптимально - да, чтобы все связи обновились нужно дополнительные приседания делать - да. Но это не "неправильно".

Плохо ли, что элемент обновляется, а связи нет? Нет, это не плохо.
Но подавать это как "базовый метод", не написав про ограничения и последствия что будет после этого - это плохо.

Я хочу чтобы моя позиция была максимально корректно изложена, поэтому несколько тезисов перед прочтением:

  1. Статья про что-то что ранее не описывалось - это ок.

  2. Статья про технологические подходы - это ок.

  3. Статья с примерами плохого кода и описанием почему они плохие - это ок.

  4. Статья с рекламными вставками аля "почему плохо" или "можно ли иначе" узнаете на курсах - это тоже ок.

  5. Я не против нового api и сам его использую, но я знаю его ограничения и я сам (без помощи техподдержки) смогу его отдебажить в случае проблем.

Но писать статью где показывать плохие подходы, а потом не говорить что они плохие, ссылаться на "разработчик должен ... дойти сам" и тут же говорить про "начинающего разработчика" (в рамках образовательного курса), заявлять заведомо ложную информацию (про бесконечное количество) - это НЕ ок.

Если вы искренне не видите проблемы, давайте разбираться с каждым случаем в отдельности.

Почему смарт-процессов может быть только 64?
Исторически идентификаторы типов сущностей (entity type id) задаются константами класса CCrmOwnerType и именно он отвечает за валидацию этих типов.
Если мы откроем класс CCrmOwnerType мы увидим у константы: DynamicTypeStart = 128 и DynamicTypeEnd = 192 они используются как границы (меньшая и большая) в проверке методом isPossibleDynamicTypeId. Т.е. если это смарт-процесс должен вернуться true и в случае использования числа большего чем это значение - вернется false. Соответственно смарт-процесс должен иметь entity type id в пределах этих чисел. Об этом говорил разработчик года 2 назад (точно не помню, у него было пара выступлений), но ссылку на вебинар сейчас не найду.

Почему я говорю об экспериментальности?

На странице документации указано что часть сущностей (на которые я ссылаюсь) все-таки доступна, но там так же сказано что для сущности Компания поддерживается только режим чтения. И вроде бы можно было бы на этом остановиться, но если мы провалимся в CCrmDeal::Add (или любой другой метод), то можно увидеть следующий фрагмент кода:

if ($this->isUseOperation())
{
	return $this->getCompatibilityAdapter()->performAdd($arFields, $options);
}

Отсюда можно сделать вывод, что в будущем код CCrmDeal::Add будет использовать тот же механизм, но нас интересует метод isUseOperation.
Если вы посмотрите что он возвращает у вас на рабочей установке, то скорее всего увидите false (если вы найдете уже следующее видео от Антона (разработчика), то он там как раз говорит что можно, но на свой страх и риск). Т.е. этот механизм как бы есть, но сам битрикс в коробке его не активирует. По какой причине - не ясно. Возможно они не уверены в его корректной работе, возможно оно не стабилизировано или какие-то другие причины - сейчас не важно.

Ответвление на ваш выпад про D7

С тем же успехом некоторое время назад были "окрики" что D7 это экспериментальный режим и писать про него не стоит - используйте CIBlockElement::GetList и будет вам счастье :)

Раз уж вы все новое api называете d7 (хотя новое название подкапотного фреймворка нельзя отнести к api отдельно взятого модуля) и сами затронули тему про CIblockElement, то я вам так скажу: на текущий момент ORM для инфоблоков не покрывает всех возможностей которые предоставляют старые методы и об этом пишут в документации, если не верите попробуйте поискать по SECTION_GLOBAL_ACTIVE или отфильтровать с учетом прав доступа, и тут ссылаться на "начинающий разработчик сам догадается" уже не профессионально.
Но да ладно, CIBlockElement::GetList затронули вы и в статье про него речь не идет, так что вернемся к обсуждению.

Критика вашего подхода работы со смарт-процессами через Datamanager

Чтобы не потерялось в памяти, мы рассматриваем ваш код по "изменению нескольких полей за одну операцию":

use Bitrix\Crm\Service\Container;

$factory = Container::getInstance()->getFactory($entityTypeId);

$class = $factory->getDataClass();

 $saveResult = $class::update($id, $arUpdate);

Рассмотрим код со стороны идеологии нового ядра.
Если мы обратимся к документации то увидим ряд недостатков старого ядра (здесь речь не про d7, а про старое api модуля построенное на оперирование "массивом"), а статья об операциях расскажет нам что любое действие над смарт-процессами это не просто какое-то действие, а набор действий.

И что же вы предлагаете в данном случае?
Выполнить низкоуровневую операцию (фактически очень легкую обертку над SQL) для того чтобы записать исключительно данные обьекта. А какие последствия такого выполнения?

Заметили противоречие предыдущему тезису про CIblockElement?

  1. При выполнении обновления не будут пересчитаны права. Если менялся ответственный, то новый ответственный при определенных обстоятельствах не увидит элемента.

  2. Не будут запущены бизнес-процессы и автоматизации, а значит часть бизнес-логики может не отработать

  3. Не будут выполнены действия по операциям, а значит часть клиентской заложенной битриксом логики останется за бортом.

  4. Не будут провалидированы системные поля, а значит ничего не помешает вам записать неконсистентные данные (например направление одно, а статус от другого или поменять birthday sort в обход birthday).

  5. Элемент не будет проиндексирован

  6. Продолжать можно еще долго...

Я уже не говорю о PARENT полях... Теперь я надеюсь не нужно пояснять почему CUD операции не должны использоваться?

Двинемся дальше и рассмотрим методsave ($item->save()), в котором мы обнаружим что он по факту является оберткой над EntityObject::save и выполняет те же самые add/update, которые как мы уже выяснили не выполняют много важных бизнес-функций.

Новое api - объектное и все строится от \Bitrix\Crm\Item, а вы не смотря на то что упрекаете меня "старым ядром" все равно сами на него же и опираетесь предлагая вернуться к массиву.

Вы сами указываете что цель статья "дать начинающему разработчику базовое понимание инструментов" и что вы не хотите писать "Войну и Мир", так почему вместо того чтобы хорошо рассмотреть один единственный способ работы с смарт-процессами (работу через операции) вы показываете несколько способов которые изначально имеют ограничения? И почему вы ничего об ограничениях них не говорите? Ведь именно операция - это тот самый базовый инструмент по изменению.

Друзья, а вы вообще статьи проверяете? Почему так много ошибок?
Если у вас и курс так написан, то я боюсь представить какого уровня специалисты выйдут после такого обучения...

Подробности под катом.

Недочеты статьи

Гибкость модуля, по сути позволяющая создавать новые сущности CRM в неограниченном количестве,

"Неограниченное количество" на момент написания комментария составляет 64 смарт-процесса и не больше.

теперь для любой сущности CRM Битрикс24

В настоящий момент времени фабрики для старых сущностей (Лид, Сделка, Контакт, Компания) работают в экспериментальном режиме и не смотря на то, что на текущий момент существует возможность работать с ними через фабрики, обратиться в техподдержку с ошибками по такой работе вряд ли получиться.

Прямое сохранение и работа с самим объектом Bitrix\Crm\Item (т.е. то что вы делаете в самом первом способе сохранения элемента) через:

$item = $factory ->createItem($data); 
$item->save();

Вообще не рекомендовано! Этот способ не проверяет права, не запускает бизнес-процессы/автоматизацию, не производит валидацию бизнес-логики пользовательских полей и очень важно - не пересчитывает права для видимости элемента.

И в следующем примере вы вроде как исправились и указали фабрику (но тут же встретили копипасту в виде fabrika), но совсем никак не обработали успешность операции и оставили просто переменную $operationResult.
Вы пишете статью из которых многие будут копипастить код, копипасть подходы и копипастить ошибки. Зачем?

Далее вы показываете замечательный антипример "Если нужно изменить несколько полей за одну операцию, код приобретает вид".
Нет, не приобретает и так как вы делаете вообще делать не стоит. Ваш код будет выглядеть например так:

// ... 
$factory = Container::getInstance()->getFactory($entityTypeId);

$item = $factory->getItem($entityId);

// Вот прямо так через `set` мы можем поменять другие поля
$item->set('UF_CRM_1_FIELD_1', $value1)
	->set('UF_CRM_1_FIELD_2', $value2)
    ->setUfCrm1Field3($value3) // или вот так например
	;

$operation = $factory->getAddOperation($item);

$operationResult = $operation->launch();

if ( !$operationResult->isSuccess() )
{
	/**
	 * Что-то пошло не так, обработаем ошибки из:
	 *
	 *
	 * @operationResult->getErrors();
	 *
	 * Или из
	 *
	 * @operationResult->getErrorMessages();
	 */
}

Если нужно кастомизировать операцию изменения

Смотря что вы вкладываете в понятие кастомизировать. Указанный код я бы назвал сменой контекста выполнения, а конкретно пользователя, чьи права будут проверяться и чье имя будет использоваться при записи в историю и автоматизации.

Под кастомизацией обычно понимается изменение поведение или дополнительные действия — например отправить уведомление при создании элемента смарт‑процесса (это можно сделать и автоматизацией, но иногда все же и так нужно)

Удаление элемента Смарт-процесса

Вы пишите про удаление (delete), а сами используете операцию "изменения" (update).

А что делать с тегами, где 100 баллов нет ни у кого? Например, сейчас в теге Битрикс24 физически нет ни у кого столько баллов, думаю есть и другие теги.
Включил на ~последней версии Битрикс24 коробочного режим отладки:
400 Notice
26 Strict Standart

1 Warning погоды не сделает, а учитывая то, что они поддержку 7.1 сделают не раньше середины 2018 года, то я бы не стал из-за этого переживать.
Спасибо за статью!

От себя хотелось бы отметить пару моментов:
1) Я бы на вашем месте не доверял стандартному тесту на нагрузку — лучше использовать средства вроде фантома или jmeter.
На примере: 2GB RAM, 1vCPU (2.4) с установленным коробочным битрикс24 — держат максимум 50 пользователей.

2) Цифры по СУБД практически не влияют на работу битрикса. Он может нормально работать и при такой нагрузке, однако для б24 в коробке такие цифры свидетельствую о проблемах. Реальный кейс: 30 человек на портале, 150 запросов на запись по битриксу, падения портала каждые 2-3 часа (зависания на уровне субд, дедлоки в тех местах где их быть не должно).

3) Ваш подход вписывается (и довольно органично) в парадигму БУС (битрикс управление сайтом), но для Битрикс24 в коробке он совершенно не подходит — придется хорошенько повозится с конфигурациями nginx и apache для стабильной работы.

Кстати про работу последнего (Битрикс24) в GCP было бы интересно почитать :)
Не исключено, что ZF3 позаимствовал компонентный подход у Symfony, но это же не делает его менее привлекательным, правда?
В конце концов, даже не особо популярный в России ZF3 иногда сделан куда лучше своих 'битриксовых' аналогов.
Хочется Laravel, Symfony, Yii, Phalcon, Zend… а на практике — Битрикс и NoNameShitFramework
Я может быть неправильно выразился, извините, попробую исправиться.

В ТЗ есть фраза которая неявно трактуется (ничего не поделаешь, ТЗ подписано). Фича оценивается в X человеко-часов, но представитель со стороны клиента описывая функциональность детализирует ее так, что формально она подходит под описание в ТЗ, но оценивается в 3*X человеко-часов. На уверения и доказательства что это не то что написано в ТЗ не реагирует и отказывается урезать другие части проекта (даже те, что особо не влияют работу продукта — рюшечки). Грозиться отменить приемку проекта, если это не будет реализовано и подать в суд за срыв сроков.

Вот о какой ситуации я говорил.

Скажите, а бывали ли в Вашей практике случаи, когда клиент дополняет проект фичей, но урезать проект не может (не хочет и всячески противится). Как Вы справлялись с таким ?

Результаты таблицы показывают, что для повышения эффективности взаимодействия пользователя с паркетным меню наиболее часто выбираемые элементы должны быть расположены под №2 и №4.


Простите, а разве не 2 и 5? Это я чего-то не понял, или опечатались?
Спасибо, исправлено.
Простите за украденное время и спасибо за оценку перевода и ошибочку.

А насчет __invoke(), по крайней мере более вразумительный пример в документации.
Спасибо за наиболее развернутый ответ. И прошу прощенья, вспылил.
Да, согласен, ценность статьи можно поставить под сомнение, но ведь ведь и изначально статья Филиппа Брауна не была расчитана на профессионалов. Скорее на новичков или немного более продвинутых, кому было бы неплохо закрепить свои навыки.

А насчет ценности статьи, то для меня наиболее обьективный показатель ценности — это количество добавления в закладки, а их уже, ни много ни мало, 35 человек, что уже о чем-то да говорит.
Вы видимо не читали. Целью автора была не скопировать мануал, а дополнить его примерами не искусственными, которые помогут понять смысл. Я не сомневаюсь в вашей компетенции как разработчика, но все ли смогут привести пример использования метода __invoke()?

И да, новичкам оно тоже подойдет, иначе зачем бы я поставил флаг tutorial?

P.S. Печально видеть осуждение от пользователя, который не потрудился написать ни одного полезного поста или комментария.

Information

Rating
Does not participate
Location
Химки, Москва и Московская обл., Россия
Date of birth
Registered
Activity