Полный цикл в digital

ORM в новом ядре

Реализация ORM в ядре D7 призвана абстрагировать разработчика от механики работы с таблицами на уровне запросов к БД, введя понятие сущности и поля сущности.

  • Cущность в терминах битрикса, это таблица
  • Поля сущности столбцы или ссылки на другие сущности
  • Датаменеджер система управления данными

Нужно понимать, работа в ORM возможна только если есть класс описывающий таблицу, с которой нужно работать. Класс может быть сгенерирован и находиться в ядре, а может и отсутствовать. Всё зависит от таблицы данных с которой нужно работать. Работу можно разделить на следующие этапы:

  1. В папочке bitrix пытаемся найти класс, если класс удалось найти значит продолжаем работать с файлом в котором он описан
  2. Если в папочке bitrix не удалось найти класс, значит его нужно сгенерировать, как это сделать автоматически написано ниже в статье
  3. Нужно убедиться что система видит класс, если класс не подключен его нужно подключить, есть три варианта:
  4. Пишем необходимые запросы используя API bitrix и обрабатываем их

Из чего состоит класс

В классе обязательно должны быть два метода:

  • getMap() перечисляются все поля таблицы
  • getTableName() указывается название базы данных

Пример класса через который можно работать с таблицей b_iblock:

/bitrix/modules/iblock/lib/element.php<?
namespace Bitrix\Iblock;

use Bitrix\Main\Localization\Loc,
 Bitrix\Main\ORM\Data\DataManager,
 Bitrix\Main\ORM\Fields,
 Bitrix\Main\Type;

Loc::loadMessages(__FILE__);

/**
* Class IblockTable
* 
* Fields:
* <ul>
* <li> ID int mandatory
* <li> TIMESTAMP_X datetime optional default current datetime
* <li> IBLOCK_TYPE_ID string(50) mandatory
* <li> LID string(2) mandatory
* <li> CODE string(50) optional
* <li> API_CODE string(50) optional
* <li> REST_ON bool ('N', 'Y') optional default 'N'
* <li> NAME string(255) mandatory
* <li> ACTIVE bool ('N', 'Y') optional default 'Y'
* <li> SORT int optional default 500
* <li> LIST_PAGE_URL string(255) optional
* <li> DETAIL_PAGE_URL string(255) optional
* <li> SECTION_PAGE_URL string(255) optional
* <li> CANONICAL_PAGE_URL string(255) optional
* <li> PICTURE int optional
* <li> DESCRIPTION text optional
* <li> DESCRIPTION_TYPE enum ('text', 'html') optional default 'text'
* <li> RSS_TTL int optional default 24
* <li> RSS_ACTIVE bool ('N', 'Y') optional default 'Y'
* <li> RSS_FILE_ACTIVE bool ('N', 'Y') optional default 'N'
* <li> RSS_FILE_LIMIT int optional
* <li> RSS_FILE_DAYS int optional
* <li> RSS_YANDEX_ACTIVE bool ('N', 'Y') optional default 'N'
* <li> XML_ID string(255) optional
* <li> TMP_ID string(40) optional
* <li> INDEX_ELEMENT bool ('N', 'Y') optional default 'Y'
* <li> INDEX_SECTION bool ('N', 'Y') optional default 'N'
* <li> WORKFLOW bool ('N', 'Y') optional default 'Y'
* <li> BIZPROC bool ('N', 'Y') optional default 'N'
* <li> SECTION_CHOOSER string(1) optional
* <li> LIST_MODE string(1) optional
* <li> RIGHTS_MODE string(1) optional
* <li> SECTION_PROPERTY string(1) optional
* <li> PROPERTY_INDEX string(1) optional
* <li> VERSION int optional default 1
* <li> LAST_CONV_ELEMENT int optional default 0
* <li> SOCNET_GROUP_ID int optional
* <li> EDIT_FILE_BEFORE string(255) optional
* <li> EDIT_FILE_AFTER string(255) optional
* <li> SECTIONS_NAME string(100) optional
* <li> SECTION_NAME string(100) optional
* <li> ELEMENTS_NAME string(100) optional
* <li> ELEMENT_NAME string(100) optional
* <li> PICTURE reference to {@link \Bitrix\File\FileTable}
* <li> IBLOCK_TYPE_ID reference to {@link \Bitrix\Iblock\IblockTypeTable}
* <li> LID reference to {@link \Bitrix\Lang\LangTable}
* <li> SOCNET_GROUP_ID reference to {@link \Bitrix\Sonet\SonetGroupTable}
* </ul>
*
* @package Bitrix\Iblock
**/

class IblockTable extends DataManager
{
 /**
  * Returns DB table name for entity.
  *
  * @return string
  */
 public static function getTableName()
 {
   return 'b_iblock';
 }

 /**
  * Returns entity map definition.
  *
  * @return array
  */
 public static function getMap()
 {
   return [
     new Fields\IntegerField(
       'ID',
       [
         'primary' => true,
         'autocomplete' => true,
         'title' => Loc::getMessage('IBLOCK_ENTITY_ID_FIELD')
       ]
     ),
     new Fields\DatetimeField(
       'TIMESTAMP_X',
       [
         'default' => function()
         {
           return new Type\DateTime();
         },
         'title' => Loc::getMessage('IBLOCK_ENTITY_TIMESTAMP_X_FIELD')
       ]
     ),
     new Fields\StringField(
       'IBLOCK_TYPE_ID',
       [
         'required' => true,
         'validation' => [__CLASS__, 'validateIblockTypeId'],
         'title' => Loc::getMessage('IBLOCK_ENTITY_IBLOCK_TYPE_ID_FIELD')
       ]
     ),
     new Fields\StringField(
       'LID',
       [
         'required' => true,
         'validation' => [__CLASS__, 'validateLid'],
         'title' => Loc::getMessage('IBLOCK_ENTITY_LID_FIELD')
       ]
     ),
     new Fields\StringField(
       'CODE',
       [
         'validation' => [__CLASS__, 'validateCode'],
         'title' => Loc::getMessage('IBLOCK_ENTITY_CODE_FIELD')
       ]
     ),
     new Fields\StringField(
       'API_CODE',
       [
         'validation' => [__CLASS__, 'validateApiCode'],
         'title' => Loc::getMessage('IBLOCK_ENTITY_API_CODE_FIELD')
       ]
     ),
     new Fields\BooleanField(
       'REST_ON',
       [
         'values' => array('N', 'Y'),
         'default' => 'N',
         'title' => Loc::getMessage('IBLOCK_ENTITY_REST_ON_FIELD')
       ]
     ),
     new Fields\StringField(
       'NAME',
       [
         'required' => true,
         'validation' => [__CLASS__, 'validateName'],
         'title' => Loc::getMessage('IBLOCK_ENTITY_NAME_FIELD')
       ]
     ),
     new Fields\BooleanField(
       'ACTIVE',
       [
         'values' => array('N', 'Y'),
         'default' => 'Y',
         'title' => Loc::getMessage('IBLOCK_ENTITY_ACTIVE_FIELD')
       ]
     ),
     new Fields\IntegerField(
       'SORT',
       [
         'default' => 500,
         'title' => Loc::getMessage('IBLOCK_ENTITY_SORT_FIELD')
       ]
     ),
     new Fields\StringField(
       'LIST_PAGE_URL',
       [
         'validation' => [__CLASS__, 'validateListPageUrl'],
         'title' => Loc::getMessage('IBLOCK_ENTITY_LIST_PAGE_URL_FIELD')
       ]
     ),
     new Fields\StringField(
       'DETAIL_PAGE_URL',
       [
         'validation' => [__CLASS__, 'validateDetailPageUrl'],
         'title' => Loc::getMessage('IBLOCK_ENTITY_DETAIL_PAGE_URL_FIELD')
       ]
     ),
     new Fields\StringField(
       'SECTION_PAGE_URL',
       [
         'validation' => [__CLASS__, 'validateSectionPageUrl'],
         'title' => Loc::getMessage('IBLOCK_ENTITY_SECTION_PAGE_URL_FIELD')
       ]
     ),
     new Fields\StringField(
       'CANONICAL_PAGE_URL',
       [
         'validation' => [__CLASS__, 'validateCanonicalPageUrl'],
         'title' => Loc::getMessage('IBLOCK_ENTITY_CANONICAL_PAGE_URL_FIELD')
       ]
     ),
     new Fields\IntegerField(
       'PICTURE',
       [
         'title' => Loc::getMessage('IBLOCK_ENTITY_PICTURE_FIELD')
       ]
     ),
     new Fields\TextField(
       'DESCRIPTION',
       [
         'title' => Loc::getMessage('IBLOCK_ENTITY_DESCRIPTION_FIELD')
       ]
     ),
     new Fields\StringField(
       'DESCRIPTION_TYPE',
       [
         'values' => array('text', 'html'),
         'default' => 'text',
         'title' => Loc::getMessage('IBLOCK_ENTITY_DESCRIPTION_TYPE_FIELD')
       ]
     ),
     new Fields\IntegerField(
       'RSS_TTL',
       [
         'default' => 24,
         'title' => Loc::getMessage('IBLOCK_ENTITY_RSS_TTL_FIELD')
       ]
     ),
     new Fields\BooleanField(
       'RSS_ACTIVE',
       [
         'values' => array('N', 'Y'),
         'default' => 'Y',
         'title' => Loc::getMessage('IBLOCK_ENTITY_RSS_ACTIVE_FIELD')
       ]
     ),
     new Fields\BooleanField(
       'RSS_FILE_ACTIVE',
       [
         'values' => array('N', 'Y'),
         'default' => 'N',
         'title' => Loc::getMessage('IBLOCK_ENTITY_RSS_FILE_ACTIVE_FIELD')
       ]
     ),
     new Fields\IntegerField(
       'RSS_FILE_LIMIT',
       [
         'title' => Loc::getMessage('IBLOCK_ENTITY_RSS_FILE_LIMIT_FIELD')
       ]
     ),
     new Fields\IntegerField(
       'RSS_FILE_DAYS',
       [
         'title' => Loc::getMessage('IBLOCK_ENTITY_RSS_FILE_DAYS_FIELD')
       ]
     ),
     new Fields\BooleanField(
       'RSS_YANDEX_ACTIVE',
       [
         'values' => array('N', 'Y'),
         'default' => 'N',
         'title' => Loc::getMessage('IBLOCK_ENTITY_RSS_YANDEX_ACTIVE_FIELD')
       ]
     ),
     new Fields\StringField(
       'XML_ID',
       [
         'validation' => [__CLASS__, 'validateXmlId'],
         'title' => Loc::getMessage('IBLOCK_ENTITY_XML_ID_FIELD')
       ]
     ),
     new Fields\StringField(
       'TMP_ID',
       [
         'validation' => [__CLASS__, 'validateTmpId'],
         'title' => Loc::getMessage('IBLOCK_ENTITY_TMP_ID_FIELD')
       ]
     ),
     new Fields\BooleanField(
       'INDEX_ELEMENT',
       [
         'values' => array('N', 'Y'),
         'default' => 'Y',
         'title' => Loc::getMessage('IBLOCK_ENTITY_INDEX_ELEMENT_FIELD')
       ]
     ),
     new Fields\BooleanField(
       'INDEX_SECTION',
       [
         'values' => array('N', 'Y'),
         'default' => 'N',
         'title' => Loc::getMessage('IBLOCK_ENTITY_INDEX_SECTION_FIELD')
       ]
     ),
     new Fields\BooleanField(
       'WORKFLOW',
       [
         'values' => array('N', 'Y'),
         'default' => 'Y',
         'title' => Loc::getMessage('IBLOCK_ENTITY_WORKFLOW_FIELD')
       ]
     ),
     new Fields\BooleanField(
       'BIZPROC',
       [
         'values' => array('N', 'Y'),
         'default' => 'N',
         'title' => Loc::getMessage('IBLOCK_ENTITY_BIZPROC_FIELD')
       ]
     ),
     new Fields\StringField(
       'SECTION_CHOOSER',
       [
         'validation' => [__CLASS__, 'validateSectionChooser'],
         'title' => Loc::getMessage('IBLOCK_ENTITY_SECTION_CHOOSER_FIELD')
       ]
     ),
     new Fields\StringField(
       'LIST_MODE',
       [
         'validation' => [__CLASS__, 'validateListMode'],
         'title' => Loc::getMessage('IBLOCK_ENTITY_LIST_MODE_FIELD')
       ]
     ),
     new Fields\StringField(
       'RIGHTS_MODE',
       [
         'validation' => [__CLASS__, 'validateRightsMode'],
         'title' => Loc::getMessage('IBLOCK_ENTITY_RIGHTS_MODE_FIELD')
       ]
     ),
     new Fields\StringField(
       'SECTION_PROPERTY',
       [
         'validation' => [__CLASS__, 'validateSectionProperty'],
         'title' => Loc::getMessage('IBLOCK_ENTITY_SECTION_PROPERTY_FIELD')
       ]
     ),
     new Fields\StringField(
       'PROPERTY_INDEX',
       [
         'validation' => [__CLASS__, 'validatePropertyIndex'],
         'title' => Loc::getMessage('IBLOCK_ENTITY_PROPERTY_INDEX_FIELD')
       ]
     ),
     new Fields\IntegerField(
       'VERSION',
       [
         'default' => 1,
         'title' => Loc::getMessage('IBLOCK_ENTITY_VERSION_FIELD')
       ]
     ),
     new Fields\IntegerField(
       'LAST_CONV_ELEMENT',
       [
         'default' => 0,
         'title' => Loc::getMessage('IBLOCK_ENTITY_LAST_CONV_ELEMENT_FIELD')
       ]
     ),
     new Fields\IntegerField(
       'SOCNET_GROUP_ID',
       [
         'title' => Loc::getMessage('IBLOCK_ENTITY_SOCNET_GROUP_ID_FIELD')
       ]
     ),
     new Fields\StringField(
       'EDIT_FILE_BEFORE',
       [
         'validation' => [__CLASS__, 'validateEditFileBefore'],
         'title' => Loc::getMessage('IBLOCK_ENTITY_EDIT_FILE_BEFORE_FIELD')
       ]
     ),
     new Fields\StringField(
       'EDIT_FILE_AFTER',
       [
         'validation' => [__CLASS__, 'validateEditFileAfter'],
         'title' => Loc::getMessage('IBLOCK_ENTITY_EDIT_FILE_AFTER_FIELD')
       ]
     ),
     new Fields\StringField(
       'SECTIONS_NAME',
       [
         'validation' => [__CLASS__, 'validateSectionsName'],
         'title' => Loc::getMessage('IBLOCK_ENTITY_SECTIONS_NAME_FIELD')
       ]
     ),
     new Fields\StringField(
       'SECTION_NAME',
       [
         'validation' => [__CLASS__, 'validateSectionName'],
         'title' => Loc::getMessage('IBLOCK_ENTITY_SECTION_NAME_FIELD')
       ]
     ),
     new Fields\StringField(
       'ELEMENTS_NAME',
       [
         'validation' => [__CLASS__, 'validateElementsName'],
         'title' => Loc::getMessage('IBLOCK_ENTITY_ELEMENTS_NAME_FIELD')
       ]
     ),
     new Fields\StringField(
       'ELEMENT_NAME',
       [
         'validation' => [__CLASS__, 'validateElementName'],
         'title' => Loc::getMessage('IBLOCK_ENTITY_ELEMENT_NAME_FIELD')
       ]
     ),
     new Fields\Relations\Reference(
       'FILE',
       '\Bitrix\File\File',
       ['=this.PICTURE' => 'ref.ID'],
       ['join_type' => 'LEFT']
     ),
     new Fields\Relations\Reference(
       'IBLOCK_TYPE',
       '\Bitrix\Iblock\IblockType',
       ['=this.IBLOCK_TYPE_ID' => 'ref.ID'],
       ['join_type' => 'LEFT']
     ),
     new Fields\Relations\Reference(
       'LANG',
       '\Bitrix\Lang\Lang',
       ['=this.LID' => 'ref.LID'],
       ['join_type' => 'LEFT']
     ),
     new Fields\Relations\Reference(
       'SOCNET_GROUP',
       '\Bitrix\Sonet\SonetGroup',
       ['=this.SOCNET_GROUP_ID' => 'ref.ID'],
       ['join_type' => 'LEFT']
     ),
   ];
 }

 /**
  * Returns validators for IBLOCK_TYPE_ID field.
  *
  * @return array
  */
 public static function validateIblockTypeId()
 {
   return [
     new Fields\Validators\LengthValidator(null, 50),
   ];
 }

 /**
  * Returns validators for LID field.
  *
  * @return array
  */
 public static function validateLid()
 {
   return [
     new Fields\Validators\LengthValidator(null, 2),
   ];
 }

 /**
  * Returns validators for CODE field.
  *
  * @return array
  */
 public static function validateCode()
 {
   return [
     new Fields\Validators\LengthValidator(null, 50),
   ];
 }

 /**
  * Returns validators for API_CODE field.
  *
  * @return array
  */
 public static function validateApiCode()
 {
   return [
     new Fields\Validators\LengthValidator(null, 50),
   ];
 }

 /**
  * Returns validators for NAME field.
  *
  * @return array
  */
 public static function validateName()
 {
   return [
     new Fields\Validators\LengthValidator(null, 255),
   ];
 }

 /**
  * Returns validators for LIST_PAGE_URL field.
  *
  * @return array
  */
 public static function validateListPageUrl()
 {
   return [
     new Fields\Validators\LengthValidator(null, 255),
   ];
 }

 /**
  * Returns validators for DETAIL_PAGE_URL field.
  *
  * @return array
  */
 public static function validateDetailPageUrl()
 {
   return [
     new Fields\Validators\LengthValidator(null, 255),
   ];
 }

 /**
  * Returns validators for SECTION_PAGE_URL field.
  *
  * @return array
  */
 public static function validateSectionPageUrl()
 {
   return [
     new Fields\Validators\LengthValidator(null, 255),
   ];
 }

 /**
  * Returns validators for CANONICAL_PAGE_URL field.
  *
  * @return array
  */
 public static function validateCanonicalPageUrl()
 {
   return [
     new Fields\Validators\LengthValidator(null, 255),
   ];
 }

 /**
  * Returns validators for XML_ID field.
  *
  * @return array
  */
 public static function validateXmlId()
 {
   return [
     new Fields\Validators\LengthValidator(null, 255),
   ];
 }

 /**
  * Returns validators for TMP_ID field.
  *
  * @return array
  */
 public static function validateTmpId()
 {
   return [
     new Fields\Validators\LengthValidator(null, 40),
   ];
 }

 /**
  * Returns validators for SECTION_CHOOSER field.
  *
  * @return array
  */
 public static function validateSectionChooser()
 {
   return [
     new Fields\Validators\LengthValidator(null, 1),
   ];
 }

 /**
  * Returns validators for LIST_MODE field.
  *
  * @return array
  */
 public static function validateListMode()
 {
   return [
     new Fields\Validators\LengthValidator(null, 1),
   ];
 }

 /**
  * Returns validators for RIGHTS_MODE field.
  *
  * @return array
  */
 public static function validateRightsMode()
 {
   return [
     new Fields\Validators\LengthValidator(null, 1),
   ];
 }

 /**
  * Returns validators for SECTION_PROPERTY field.
  *
  * @return array
  */
 public static function validateSectionProperty()
 {
   return [
     new Fields\Validators\LengthValidator(null, 1),
   ];
 }

 /**
  * Returns validators for PROPERTY_INDEX field.
  *
  * @return array
  */
 public static function validatePropertyIndex()
 {
   return [
     new Fields\Validators\LengthValidator(null, 1),
   ];
 }

 /**
  * Returns validators for EDIT_FILE_BEFORE field.
  *
  * @return array
  */
 public static function validateEditFileBefore()
 {
   return [
     new Fields\Validators\LengthValidator(null, 255),
   ];
 }

 /**
  * Returns validators for EDIT_FILE_AFTER field.
  *
  * @return array
  */
 public static function validateEditFileAfter()
 {
   return [
     new Fields\Validators\LengthValidator(null, 255),
   ];
 }

 /**
  * Returns validators for SECTIONS_NAME field.
  *
  * @return array
  */
 public static function validateSectionsName()
 {
   return [
     new Fields\Validators\LengthValidator(null, 100),
   ];
 }

 /**
  * Returns validators for SECTION_NAME field.
  *
  * @return array
  */
 public static function validateSectionName()
 {
   return [
     new Fields\Validators\LengthValidator(null, 100),
   ];
 }

 /**
  * Returns validators for ELEMENTS_NAME field.
  *
  * @return array
  */
 public static function validateElementsName()
 {
   return [
     new Fields\Validators\LengthValidator(null, 100),
   ];
 }

 /**
  * Returns validators for ELEMENT_NAME field.
  *
  * @return array
  */
 public static function validateElementName()
 {
   return [
     new Fields\Validators\LengthValidator(null, 100),
   ];
 }
}

Автоматическая генерация класса

Для использования генератора ORM классов перейдите на страницу Настройки -> Настройки продукта -> Настройки модулей -> Монитор производительности модуль Монитор производительности должен быть установлен. На вкладке Генератор таблетов отметьте поле Разрешить генерацию таблетов для ORM.

Автоматически сгенерировать класс с описанием любой таблицы можно на странице Настройки -> Производительность -> Таблицы, в меню действий доступен пункт ORM

Операции с сущностями

Для работы с таблицей стандартными методами D7 доступны следующие методы:

  • getList выполняет запрос и возвращает отобранные по параметрам запроса данные
  • add добавляет новый элемент
  • update обновляет строку в таблице
  • delete удаляет строку в таблице сущности по первичному ключу

GetList

Пример запроса:

// подключаем модуль, через модуль подключается класс IblockTable
\Bitrix\Main\Loader::IncludeModule("iblock");
// делаем запрос на выборку данных getList
$res = \Bitrix\Iblock\IblockTable::getList(array(
'select' => array('ID')
));
// перебираем массив и выводим на экран
while ($arr = $res->fetch()) {
pp($arr);
}

Операторы:

IblockTable::getList(array(
// имена полей, которые необходимо получить
'select' => array('ISBN', 'TITLE', 'PUBLISH_DATE'), 
// описание фильтра для WHERE и HAVING
'filter' => array('=ID' => 1), 
// явное указание полей, по которым нужно группировать результат
'group' => array('PUBLISH_DATE'), 
// параметры сортировки
'order' => array('PUBLISH_DATE' => 'DESC', 'TITLE' => 'ASC'), 
// количество записей
'limit' => 10, 
// смещение для limit
'offset' => 80, 
// динамически определенные поля
'runtime' => 'runtime' => array(new Entity\ExpressionField('CNT', 'COUNT(*)')) 
));

select

array(
  'select' => array('ISBN', 'TITLE', 'PUBLISH_DATE')
)
// SELECT ISBN, TITLE, PUBLISH_DATE FROM my_book
array(
  'select' => array('ISBN', 'TITLE', 'PUBLICATION' => 'PUBLISH_DATE')
)
// SELECT ISBN, TITLE, PUBLISH_DATE AS PUBLICATION FROM my_book
array(
  'select' => array('*')
)
// SELECT *

filter

array(
  'filter' => array('=ID' => 1)
)
// WHERE ID = 1
array(
  'filter' => array('%=TITLE' => 'Patterns%')
)
// WHERE TITLE LIKE 'Patterns%'

Многоуровневые массивы со склейкой выражений AND/OR:

array(
  'filter' => array(
      '=ID' => 1,
      '=ISBN' => '9780321127426'
  )
)
// WHERE ID = 1 AND ISBN = '9780321127426'
array(
  'filter' => array(
    // по умолчанию элементы склеиваются через AND
    //'LOGIC' => 'AND', 
      'LOGIC' => 'OR',
      array(
          '=ID' => 1,
          '=ISBN' => '9780321127426'
      ),
      array(
          '=ID' => 2,
          '=ISBN' => '9781449314286'
      )
  )
)
// WHERE (ID=1 AND ISBN='9780321127426') OR (ID=2 AND ISBN='9781449314286')

Полный список операторов сравнения, которые можно использовать в filter:

'filter' => array('=ID' => 1)
  • = равно (работает и с массивами)
  • % подстрока
  • > больше
  • < меньше
  • @ IN (EXPR) в качестве значения передается массив или объект
  • !@ NOT IN (EXPR)в качестве значения передается массив или объект
  • != не равно
  • !% не подстрока
  • >< между, в качестве значения передается массив array(MIN, MAX)
  • >= больше или равно
  • <= меньше или равно
  • =% LIKE
  • %= LIKE
  • == булевое выражение для ExpressionField (например, для EXISTS() или NOT EXISTS())
  • !>< не между, в качестве значения передается массив array(MIN, MAX)
  • !=% NOT LIKE
  • !%= NOT LIKE
  • '==ID' => null условие, что поле ID равно NULL (в sql-запросе будет преобразовано в ID IS NULL)
  • '!==NAME' => null условие, что поле NAME не равно NULL (в sql-запросе будет преобразовано в NAME IS NOT NULL)

group

В параметре group перечисляются поля для группировки:

array(
  'group' => array('PUBLISH_DATE')
)

order

Параметр позволяет указать порядок сортировки:

array(
  'order' => array('PUBLISH_DATE' => 'DESC', 'TITLE' => 'ASC')
)
array(
  'order' => array('ID') // направление по умолчанию - ASC
)

offset/limit

Параметры помогут ограничить количество выбираемых записей или реализовать постраничную выборку:

array(
  'order' => array('ID' => 'DESC')
  'limit' => 10
)
// 10 последних записей
array(
  'order' => array('ID')
  'limit' => 20,
  'offset' => 80
)
// 5-я страница с записями, по 20 на страницу

Add

Метод для добавления записи принимает на вход массив со значениями, где ключи - имена полей сущности:

// подключаем модуль, через модуль подключается класс IblockTable
\Bitrix\Main\Loader::IncludeModule("iblock");
// делаем запрос на вставку данных add
$res = \Bitrix\Iblock\IblockTable::add(array(
'NAME' => 'Тест'
));

Update

Обновление записи происходит похожим образом, только к массиву значений в параметрах добавляется значение первичного ключа:

// подключаем модуль, через модуль подключается класс IblockTable
\Bitrix\Main\Loader::IncludeModule("iblock");
// делаем запрос на тзменение поля NAME в записи с ID 1
$res = \Bitrix\Iblock\IblockTable::update(1, array(
'NAME' => 'Тест'
));

Delete

Для удаления записи нужен только первичный ключ:

// подключаем модуль, через модуль подключается класс IblockTable
\Bitrix\Main\Loader::IncludeModule("iblock");
// делаем запрос на удаление записи с ID 1
$res = \Bitrix\Iblock\IblockTable::delete(1);

Вывод SQL запроса на экран

Чтобы понять причину «неправильно» работающей выборки, нужно посмотреть какой sql-запрос формируетя. Рассмотрим на примере выборок из ORM ядра D7 в битриксе:

// подключаем класс для вывода SQL запроса
\Bitrix\Main\Application::getConnection()->startTracker();
// подключаем модуль, через модуль подключается класс IblockTable
\Bitrix\Main\Loader::IncludeModule("iblock");
// делаем запрос на выборку данных getList
$res = \Bitrix\Iblock\IblockTable::getList(array(
'select' => array('ID')
));
// перебираем массив и выводим на экран
while ($arr = $res->fetch()) {
pp($arr);
}
// выводим на экран SQL запрос
echo '<pre>', $res->getTrackerQuery()->getSql(), '</pre>';
Заполните форму уже сегодня!
Для начала сотрудничества необходимо заполнить заявку или заказать обратный звонок. В ответ получите коммерческое предложение, которое будет содержать индивидуальную стратегию с учетом требований и поставленных задач
Работаем по будням с 9:00 до 18:00. Заявки, отправленные в выходные, обрабатываем в первый рабочий день до 12:00.
Спасибо, ваш запрос принят и будет обработан!
Эйч Маркетинг