digitalwand / digitalwand.admin_helper Goto Github PK
View Code? Open in Web Editor NEWAPI для сборки кастомных админок в Битриксе
License: MIT License
API для сборки кастомных админок в Битриксе
License: MIT License
доброго дня, собственно вопрос в топике
что с поддержкой? проект еще живой? будут ли какие то подвижки для поддержки php 8.1 ?
Т.к. OrmElementWidget наследуется от NumberWidget, а в режиме режиме Multiple функция getValue() возвращает массив, а не число, то валидация не проходит.
public function processEditAction()
{
if (!$this->checkRequired()) {
$this->addError('DIGITALWAND_AH_REQUIRED_FIELD_ERROR');
} else if (!$this->isNumber($this->getValue())) {
$this->addError('VALUE_IS_NOT_NUMERIC');
}
}
Покажите пример как реализовать виджет многие к многим
class CourseAdminInterface extends AdminInterface {
public function fields() {
return array(
'MAIN' => array(
'FIELDS' => array(
"UF_DATE_LESSON" => array(
'WIDGET' => new HLIBlockFieldWidget()
)
))
);
}
public function helpers() {
return array(
'\Pam\HLcourse\Course\AdminInterface\CourseListHelper',
'\Pam\HLcourse\Course\AdminInterface\CourseEditHelper'
);
}
}
UF_DATE_LESSON является типом Дата со временем в HighLoad ИБ, множественным и не объязательным. При сохранение нового элемента в сгнерированной админке появляется сообщение Значение поля «UF_DATE_LESSON» не является корректной датой/временем.
При этом само поле может быть пустым или заполеным датой из календаря. Я только смог понять что не србатывает CheckFields
Если нет связанных данных, функция getOrmElementData
$rsMultEntity = $entityName::getList(array(
'select' => array('REFERENCE_' => $this->getCode() . '.*'),
'filter' => array('=ID' => $this->data['ID'])
));
выводит пустые поля ['REFERENCE_ID'=>NULL, 'REFERENCE_VALUE'=>NULL], которые затем записываются в список значений
while ($multEntity = $rsMultEntity->fetch()) {
$valueList[$multEntity['REFERENCE_VALUE']] = $multEntity['REFERENCE_VALUE'];
}
сформированный массив ["" => NULL] попадает в ОRM и возникает ошибка
$rsEntity = $linkedModel::getList(array(
'filter' => array('ID' => $valueList)
));
Есть ли возможность отображать только страницу списка элементов, без страницы редактирования?
Попробовал просто не создавать AdminEditHelper. Не получилось, ругается.
Если имя поля задано в getMap() в классе модели, то при задании поля NAME в настройках виджета оно должно переопределяться. Но этого не происходит.
Если в сущности присутствует ReferenceField, то происходит ошибка в виджете CheckboxWidget.
В методе getCheckboxType виджета CheckboxWidget в цикле foreach для $field вызывается метод getColumnName(), который отсутствует у ReferenceField и у его родителя Field.
Call to undefined method Bitrix\Main\Entity\ReferenceField::getColumnName() in /home/bitrix/www/bitrix/modules/digitalwand.admin_helper/lib/widget/CheckboxWidget.php on line 209
модуль main 16.5.7
digitalwand.admin_helper 2.0.0
Временное решение проблемы - перемещение описания поля reference на последнее по порядку место в методе getMap сущности. Тогда цикл просто до него не добирается (при условии что искомое поле будет найдено раньше). Ну а по хорошему надо перед вызовом getColumnName сделать проверку $field на тип и если это ReferenceField - пропускать его.
Фиксится добавления if для проверки $this->getValue() в методы getEditHtml, generateRow и processEditAction
При попытке группового удаления возникает исключение вида:
[Bitrix\Main\ArgumentException]
Unknown primary `0` found when trying to query Poi row. (100)
/home/bitrix/www/bitrix/modules/main/lib/entity/datamanager.php:350
#0: Bitrix\Main\Entity\DataManager::validatePrimary(array)
/home/bitrix/www/bitrix/modules/highloadblock/lib/datamanager.php:297
#1: Bitrix\Highloadblock\DataManager::delete(array)
/home/bitrix/www/local/modules/digitalwand.admin_helper/lib/EntityManager.php:248
#2: DigitalWand\AdminHelper\EntityManager->delete()
/home/bitrix/www/local/modules/digitalwand.admin_helper/lib/helper/AdminListHelper.php:529
#3: DigitalWand\AdminHelper\Helper\AdminListHelper->groupActions(array, string)
/home/bitrix/www/local/modules/digitalwand.admin_helper/lib/helper/AdminListHelper.php:224
#4: DigitalWand\AdminHelper\Helper\AdminListHelper->__construct(array, boolean)
/home/bitrix/www/local/vendor/nav/adminhelper/AdminListHelper.php:11
#5: nav\AdminHelper\AdminListHelper->__construct(array, boolean)
/home/bitrix/www/local/vendor/nav/adminhelper/admin/admin_interface_route.php:117
#6: require(string)
/home/bitrix/www/bitrix/admin/nav_admin_helper_route.php:2
В \DigitalWand\AdminHelper\EntityManager::delete() идёт вызов:
$result = $model::delete($this->helper->getPk());
а в аргументах у него идёт не айди конкретной записи, а массив всех айдишников, которые надо удалить. Возможно, надо использовать $this->itemId. А может и где-то в другом месте исправить, чтобы не сломать логики.
При создании нового элемента не бросает на листинг при нажатии "Сохранить"
В AdminEditHelper используется getById при выборке элемента. Нужно заменить это на getList и выбирать только те поля которые используются при редактировании элемента, потому что не всегда нужны все поля из записи, например в случае с модификаторами значения которые тянут что-то из АПИ.
Уидает исключение
Unknown primary 0
found when trying to query OrderStatus row.
$this->helper->getPk()
возвращает массив и в ключе 0 вмето ID
Доброго дня!
Есть ли в модуле возможность создавать взаимосвязанные поля? Например есть выпадашка ComboBoxWidget со списком инфоблоков и чтобы при выборе инфоблока в другом поле отображался список разделов выбранного инфоблока?
Если да, то подскажите, пожалуйста, как подобное реализовать)
Авторы! Отметьте в Packagist , что ваш пакет является заброшенным, если вы не реагируете и не исправляете его ошибки!!!
Разработчики-пользователи данного пакета: никогда его не используйте!
Причины:
1 Очень низкое качество кода: почти всё на статических методах :(
2 Для управления своей табличкой нужно делать свой модуль Битрикс. (это я попытался обойти, написав свой контроллер https://github.com/webarchitect609/bitrix-admin-helper-controller )
3 В модуле полным полно ошибок. Например, не работает массовое удаление записей.
4 Модуль по факту является брошенным: примерно с января 2017 года сообщения об ошибках (issue) плодятся, но никто их не исправляет.
В getCheckboxType() тип чекбокса определяется по типу поля в модели. Однако в битриксе часто существует следующая конструкция (пример из bitrix\modules\main\lib\user.php):
'ACTIVE' => array( 'data_type' => 'boolean', 'values' => array('N','Y') ),
тип чекбокса будет определен как TYPE_BOOLEAN, хотя на самом деле он TYPE_STRING
Если у виджета нет настройки VARIANTS, строки из связанной таблицы не удалятся. Заметил при использовании FileWidget в режиме MULTIPLE.
В методе \DigitalWand\AdminHelper\EntityManager::processReferencesData:
$variantsField = $fieldWidget->getSettings('VARIANTS');
...
if($result->isSuccess()){ // Удаление записей, которые не были созданы или обновлены
foreach ($referenceStaleDataSet as $referenceData) {
if (
!in_array($referenceData[$fieldWidget->getMultipleField('ID')], $processedDataIds) &&
array_key_exists($referenceData[$fieldWidget->getMultipleField('VALUE')], $variantsField)
) {
$result = $this->deleteReferenceData($reference,
$referenceData[$fieldWidget->getMultipleField('ID')]);
if(!$result->isSuccess()) {
break; // ошибка, прерываем удаление данных
}
}
}
}
До конца не понимаю архитектуру, поэтому не знаю как лучше исправить, добавить проверку на тип виджета или реализовать настройку VARIANTS у FileWidget?
Если перейти на страницу списка записей с установленными в URL параметрами сортировки, то битрикс на бекенде генерирует корректный вариант списка. Однако после того, как загрузился js, битрикс пытается применить фильтр, и вот он уже выставляет дефолтную сортировку.
Для исправления этого поведения добавил ПР #63
Можно воспроизвести на demo.adminhelper:
При любом изменении элемента, значения для множественного поля ComboBoxWidget создаются заново.
Т.к. данный виджет не передаёт id текущего значения в таблице, и мы всегда попадаем в блок создания связанных данных.
public function processEditAction()
{
if ($this->getSettings('MULTIPLE')) {
$sphere = $this->data[$this->getCode()];
unset($this->data[$this->getCode()]);
foreach ($sphere as $sphereKey) {
$this->data[$this->getCode()][] = array('VALUE' => $sphereKey);
}
}
parent::processEditAction();
}
Т.е. empty($referenceData['ID']) всегда true.
foreach ($referenceDataSet as $referenceData) {
if (empty($referenceData[$fieldWidget->getMultipleField('ID')])) {
// Создание связанных данных
if (!empty($referenceData[$fieldWidget->getMultipleField('VALUE')])) {
$result = $this->createReferenceData($reference, $referenceData);
if ($result->isSuccess()) {
$processedDataIds[] = $result->getId();
} else {
break; // ошибка, прерываем обработку данных
}
}
} else {
// Обновление связанных данных
$result = $this->updateReferenceData($reference, $referenceData, $referenceStaleDataSet);
if ($result->isSuccess()) {
$processedDataIds[] = $referenceData[$fieldWidget->getMultipleField('ID')];
} else {
break; // ошибка, прерываем обработку данных
}
}
}
Нужно сделать так, что бы модуль автоматически загружался в админке, без необходимости вызова \Bitrix\Main\Loader. Таки образом, не будет необходимости прописывать в своих модулях подключение Админ-хелпера.
Дабы не лишать разработчиков возможности применения ООП, нужно реализовать описание интерфейса админки на классах. Пример: https://gist.github.com/niksamokhvalov/315252f6b3ca22f77745
При удалении записи через контекстное меню не передаются в запрос $additionalUrlParams
В теле функции getUrl при передаче параметра k=>'{{field_id}}' происходит экраниранирование значения, из-за чего шаблонизатор не делает замену и на выходе некорректная ссылка $popupUrl.
public function getMultipleEditHtml()
{
.....
$popupUrl = $linkedHelper::getUrl(array_merge(
array(
'popup' => 'Y',
'eltitle' => $this->getSettings('TITLE_FIELD_NAME'),
'n' => $name,
'k' => '{{field_id}}'
),
$this->getSettings('ADDITIONAL_URL_PARAMS')
));
Можно воспроизвести на demo.adminhelper:
&popup=Y
Дальше два варианта ошибочного поведения:
В попапах для ссылок на подразделы используется url от AdminSectionListHelper, для чего — не очень понятно. @lithium-li, можешь пояснить, твой код вроде бы?
Уже был Pull Request (#62).
Не хватает конфигов, которые бы позволяли:
Думаю, большую часть из перечисленного лучше настраивать через Interface.php. Но после выполнения задачи #1.
При удалении разделов удаление дочерних элементов остается на совести модели. Даже если это все таки реализовано в модели, то если этих элементов будет слишком много, то удаление может упасть по таймауту.
При загрузке элемента замена полей не происходит, при сохранении не вставляется ID элемента! Или это только у меня? При сохранении тоже значения пишутся в VALUE, а не в поле замены.
Пример из жизни:
Надо, чтобы было LIMIT 0, 20 в конце такого запроса.
Пытаюсь установить модуль программно примерно таким способом:
require_once( './bitrix/modules/digitalwand.admin_helper/install/index.php');
(new digitalwand_admin_helper())->DoInstall();
В конце метода DoInstall() подключается файл, который выводит форму с предложением вернуться назад в список модулей после установки. Файл с этой кнопкой подключается с помощью инструкции $APPLICATION->IncludeAdminFile(). Однако эта инструкция после выполнения подключения файла вызывает внутри себя die(), в связи с чем работа программы, выполняющей установку, становится невозможной.
Предлагаю 2 варианта решения проблемы:
Как я понял, чтобы ваше решение работало модуль должен быть вида aloha.adminhelper
Могу ли я это отключить?
С версии 17.0.11
главного модуля появился новый класс CAdminUiList на замену старому. Неплохо было бы научить admin_helper использовать его.
В модели создаю поле FILE_ID, свойство multiple =>true.
new Entity\IntegerField('FILE_ID',['multiple'=>true]),
создаю поле связку, указывающую на \Bitrix\Main\FileTable
new Entity\ReferenceField('FILES','\Bitrix\Main\FileTable',['=this.FILE_ID' => 'ref.ID'])
В классе админ интерфейса
'FILES'=>[
'WIDGET'=>new Widget\FileWidget(),
'IMAGE'=>true,
'MULTIPLE'=>true
]
После этого пытаюсь создать новую запись в админке, загружаю один/несколько файлов и получаю битриксовый Exception
[Bitrix\Main\NotImplementedException]
Use CFile class. (140)
/home/bitrix/www/bitrix/modules/main/lib/file.php:191
#0: Bitrix\Main\FileTable::add(array)
/home/bitrix/www/bitrix/modules/digitalwand.admin_helper/lib/EntityManager.php:468
#1: DigitalWand\AdminHelper\EntityManager->createReferenceData(object, array)
/home/bitrix/www/bitrix/modules/digitalwand.admin_helper/lib/EntityManager.php:379
#2: DigitalWand\AdminHelper\EntityManager->processReferencesData()
/home/bitrix/www/bitrix/modules/digitalwand.admin_helper/lib/EntityManager.php:213
#3: DigitalWand\AdminHelper\EntityManager->save()
/home/bitrix/www/bitrix/modules/digitalwand.admin_helper/lib/helper/AdminEditHelper.php:527
#4: DigitalWand\AdminHelper\Helper\AdminEditHelper->saveElement()
/home/bitrix/www/bitrix/modules/digitalwand.admin_helper/lib/helper/AdminEditHelper.php:453
#5: DigitalWand\AdminHelper\Helper\AdminEditHelper->editAction()
/home/bitrix/www/bitrix/modules/digitalwand.admin_helper/lib/helper/AdminEditHelper.php:126
#6: DigitalWand\AdminHelper\Helper\AdminEditHelper->__construct(array, array)
/home/bitrix/www/bitrix/modules/digitalwand.admin_helper/admin/route.php:101
#7: include_once(string)
/home/bitrix/www/bitrix/admin/admin_helper_route.php:2
Вопрос: есть ли пример использования CFile или надо сделать свою таблицу и туда сохранять данные файлов?
Не хватает концептуального описания устройства АХ и принципов работы с ним. За неимением оного, новым разработчикам приходится объяснять, что такое хелперы, виджеты, Interface.php, как они взаимодействуют и т. д.
Это можно прописать для начала хотя бы в том же README.md.
Можно воспроизвести на demo.adminhelper:
При этом имя параметра с ID
текущего раздела в URL меняется с ID
на SECTION_ID
.
в AdminEditHelper.php в
else {
unset($this->data);
$this->data = $_REQUEST['FIELDS']; //Заполняем, чтобы в случае ошибки сохранения поля не были пустыми
}
нало поправить т.к. например при сохранение с виджетом HL ИБ, веденные значения не хранятся в FIELDS. Или вообще убрать
Если к примеру HTTPS настроен не на 443-й порт, то при групповом удалении или удалении из контекстного меню строки (да и при любых действиях на странице списка) список не обновляется, т.к. браузер ругается на смешанное содержимое HTTPS.
Причина банальна: в классе AdminListHelper
после указанных выше операций прописан LocalRedirect($listHelperClass::getUrl($params))
с относительным URL.
Т.к. HTTPS работает не на стандартном порту, LocalRedirect()
криво определяет протокол и возвращает данные по HTTP, на что и ругается браузер.
Решение не менее банально: убираем эти LocalRedirect()
.
Понятно, что корень проблемы в настройках сервера, но по-моему эти LocalRedirect()
в любом случае лишние, т.к. js-метод битрикса, отвечающий за операции на странице списка, сам обновляет блок с таблицей с учетом всех изменений.
Речь идет про LocalRedirect()
в конструкторе и методе groupActions
класса DigitalWand\AdminHelper\Helper\AdminListHelper
.
CheckboxWidget::getCheckboxType()
имеет две проблемы:
При переходе в раздел сохраняется номер текущей страницы в постраничной навигации. При этом целевой раздел может содержать м̀еньшее количество страниц, и список окажется пустым.
Наблюдается как при переходе по ссылке на раздел в списке, так и по кнопке На раздел выше.
Можно воспроизвести на demo.adminhelper, набив текстовые данные с помощью этого скрипта.
При использовании множественного удаления на листинге получаем ошибку:
[Bitrix\Main\ArgumentException] Unknown primary
0 found when trying to query News row. (100) /home/bitrix/www/bitrix/modules/main/lib/entity/datamanager.php:373 #0: Bitrix\Main\Entity\DataManager::validatePrimary(array) /home/bitrix/www/bitrix/modules/main/lib/entity/datamanager.php:116 #1: Bitrix\Main\Entity\DataManager::getByPrimary(array) /home/bitrix/www/bitrix/modules/main/lib/entity/datamanager.php:145 #2: Bitrix\Main\Entity\DataManager::getById(array) /home/bitrix/www/bitrix/modules/digitalwand.admin_helper/lib/helper/AdminListHelper.php:519 #3: DigitalWand\AdminHelper\Helper\AdminListHelper->groupActions(array, string) /home/bitrix/www/bitrix/modules/digitalwand.admin_helper/lib/helper/AdminListHelper.php:224 #4: DigitalWand\AdminHelper\Helper\AdminListHelper->__construct(array, boolean) /home/bitrix/www/bitrix/modules/digitalwand.admin_helper/admin/route.php:108 #5: include_once(string) /home/bitrix/www/bitrix/admin/admin_helper_route.php:2
Метод виджета changeGetListOptions должен влиять на аргументы, передаваемые в GetList()
.
Изменение $select
сейчас не влияет на выборку полей элементов (без разделов).
В changeGetListOptions передается переменная $visibleColumns, но её изменение не влияет на $listSelect
, которая используется при выборке.
Добрый день.
Подскажите, пожалуйста, поддерживает ли данный модуль из коробки возможность редактирования связи многий ко многим для OrmElementWidget?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.