/**
  * Возвращает класс хелпера нужного типа из всех зарегистрированных хелперов в модуле и находящихся
  * в том же неймспейсе что класс хелпера из которого вызван этот метод
  *
  * Под типом понимается ближайший родитель из модуля AdminHelper.
  *
  * Например если нам нужно получить ListHelper для формирования ссылки на список из EditHelper,
  * то это будет вглядеть так $listHelperClass = static::getHelperClass(AdminListHelper::getClass())
  *
  * @param $class
  * 
  * @return string|bool
  */
 public function getHelperClass($class)
 {
     $interfaceSettings = self::$interfaceSettings[static::getModule()];
     foreach ($interfaceSettings as $viewName => $settings) {
         $parentClasses = class_parents($settings['helper']);
         array_pop($parentClasses);
         // AdminBaseHelper
         $parentClass = array_pop($parentClasses);
         $thirdClass = array_pop($parentClasses);
         if (in_array($thirdClass, array(AdminSectionListHelper::className(), AdminSectionEditHelper::className()))) {
             $parentClass = $thirdClass;
         }
         if ($parentClass == $class && class_exists($settings['helper'])) {
             $helperClassParts = explode('\\', $settings['helper']);
             array_pop($helperClassParts);
             $helperNamespace = implode('\\', $helperClassParts);
             $сlassParts = explode('\\', get_called_class());
             array_pop($сlassParts);
             $classNamespace = implode('\\', $сlassParts);
             if ($helperNamespace == $classNamespace) {
                 return $settings['helper'];
             }
         }
     }
     return false;
 }
 /**
  * Получение смешанного списка из разделов и элементов.
  *
  * @param $sectionsVisibleColumns
  * @param $elementVisibleColumns
  * @param $sort
  * @param $raw
  * @return array
  */
 protected function getMixedData($sectionsVisibleColumns, $elementVisibleColumns, $sort, $raw)
 {
     $sectionEditHelperClass = $this->getHelperClass(AdminSectionEditHelper::className());
     $elementEditHelperClass = $this->getHelperClass(AdminEditHelper::className());
     $sectionField = $sectionEditHelperClass::getSectionField();
     $sectionId = $_GET['SECTION_ID'] ? $_GET['SECTION_ID'] : $_GET['ID'];
     $returnData = array();
     /**
      * @var DataManager $sectionModel
      */
     $sectionModel = $sectionEditHelperClass::getModel();
     $sectionFilter = array();
     // добавляем из фильтра те поля которые есть у разделов
     foreach ($this->arFilter as $field => $value) {
         $fieldName = $this->escapeFilterFieldName($field);
         if (!empty($this->tableColumnsMap[$fieldName])) {
             $field = str_replace($fieldName, $this->tableColumnsMap[$fieldName], $field);
             $fieldName = $this->tableColumnsMap[$fieldName];
         }
         if (in_array($fieldName, $sectionsVisibleColumns)) {
             $sectionFilter[$field] = $value;
         }
     }
     $sectionFilter[$sectionField] = $sectionId;
     $raw['SELECT'] = array_unique($raw['SELECT']);
     // при использовании в качестве popup окна исключаем раздел из выборке
     // что бы не было возможности сделать раздел родителем самого себя
     if (!empty($_REQUEST['self_id'])) {
         $sectionFilter['!' . $this->sectionPk()] = $_REQUEST['self_id'];
     }
     $sectionSort = array();
     $limitData = $this->getLimits();
     // добавляем к общему количеству элементов количество разделов
     $this->totalRowsCount = $sectionModel::getCount($sectionFilter);
     foreach ($sort as $field => $direction) {
         if (in_array($field, $sectionsVisibleColumns)) {
             $sectionSort[$field] = $direction;
         }
     }
     // добавляем к выборке разделы
     $rsSections = $sectionModel::getList(array('filter' => $sectionFilter, 'select' => $sectionsVisibleColumns, 'order' => $sectionSort, 'limit' => $limitData[1], 'offset' => $limitData[0]));
     while ($section = $rsSections->fetch()) {
         $section['IS_SECTION'] = true;
         $returnData[] = $section;
     }
     // расчитываем offset и limit для элементов
     if (count($returnData) > 0) {
         $elementOffset = 0;
     } else {
         $elementOffset = $limitData[0] - $this->totalRowsCount;
     }
     // для списка разделов элементы не нужны
     if (static::getHelperClass(AdminSectionListHelper::className()) == static::className()) {
         return $returnData;
     }
     $elementLimit = $limitData[1] - count($returnData);
     $elementModel = static::$model;
     $elementFilter = $this->arFilter;
     $elementFilter[$elementEditHelperClass::getSectionField()] = $_GET['ID'];
     // добавляем к общему количеству элементов количество элементов
     $this->totalRowsCount += $elementModel::getCount($elementFilter);
     // возвращае данные без элементов если разделы занимают всю страницу выборки
     if (!empty($returnData) && $limitData[0] == 0 && $limitData[1] == $this->totalRowsCount) {
         return $returnData;
     }
     $elementSort = array();
     foreach ($sort as $field => $direction) {
         if (in_array($field, $elementVisibleColumns)) {
             $elementSort[$field] = $direction;
         }
     }
     $elementParams = array('filter' => $elementFilter, 'select' => $elementVisibleColumns, 'order' => $elementSort);
     if ($elementLimit > 0 && $elementOffset >= 0) {
         $elementParams['limit'] = $elementLimit;
         $elementParams['offset'] = $elementOffset;
         // добавляем к выборке элементы
         $rsSections = $elementModel::getList($elementParams);
         while ($element = $rsSections->fetch()) {
             $element['IS_SECTION'] = false;
             $returnData[] = $element;
         }
     }
     return $returnData;
 }