Appearance
Data
Одна из центральных философий разработки в runway состоит в том, чтобы избавиться от работы с массивами данных и работать только с объектами.
Работа с массивами
Работа с массивами данных неудобна прежде всего тем, что программисту необходимо точно знать структуру массива. При этом также необходимо контролировать и доступ к "ключам" массива. Если при обращении к элементу массива допущена ошибка - программист может это узнать только в процессе тестирования.
Пример
php
$arData = array(
'name'=>'test',
'picture_src'=>'/upload/some-path/image.jpg',
'description'=>'<b>Some html text</b>',
'price'=>3000
);
.....
echo $arData['discription']; //Допущена ошибка в ключе массиваРабота с объектами
"Перевод" массивов данных (В общем случае получаемых из БД) в объекты данных позволяет контролировать обращения к полям сущности
Пример
php
namespace Realweb\Api\Module\Test\Model;
/**
* Class \Realweb\Api\Module\Test\Model\Entity
*
* @method string getName()
* @method string getPictureSrc()
* @method string getDescription()
* @method int getPrice()
*/
class Entity extends \Realweb\Api\Model\Data\Data
{
public function __construct(array $arData = array())
{
$this->_data = $arData;
}
public function getData(): array
{
return $this->_data;
}
}
$obEntity = new \Realweb\Api\Module\Test\Model\Entity(array(
'name'=>'test',
'picture_src'=>'/upload/some-path/image.jpg',
'description'=>'<b>Some html text</b>',
'price'=>3000
));
.....
echo $obEntity->getDescription(); //Ошибку допустить невозможно, т.к вызов несуществующего метода вызовет остановку работы приложенияОсновной контейнер данных
Основным контейнером данных для всех сущностей realweb.api является класс \Realweb\Api\Model\Data\Data. В конструктор подается массив данных, который впоследствии сформирует поля объекта.
Для доступа к полям объекта имеет встроенные магические методы по названиям полей (ключи массива)
get*- получение значения поля, если оно естьset*- установка значения поля (даже если поле не существует изначально - это не вызовет ошибку)has*- проверка на существование поляis*- проверка поля на истину
Пример
php
class Entity extends \Realweb\Api\Model\Data\Data
{
public function __construct(array $arData = array())
{
$this->_data = $arData;
}
public function getData(): array
{
return $this->_data;
}
}
$obSomeEntity = new Entity(array(
'name'=>'test',
'picture_src'=>'/upload/some-path/image.jpg',
'description'=>'<b>Some html text</b>',
'price'=>3000,
'is_product'=>1,
));
$obSomeEntity->getName(); //Получение значения поля name
$obSomeEntity->getTitle(); //Вызовет Exception - такого поля нет
$obSomeEntity->setName('New Name'); //Установка значения поля name
$obSomeEntity->setTitle('New Title'); //Установка значения поля title
$obSomeEntity->getPictureSrc('New Name'); //нижнее подчеркивание превращается в camelCase
$obSomeEntity->hasSubTitle(); //Проверка на наличие поля sub_title
$obSomeEntity->isProduct(); //true/falseДля вывода сущности на фронтенд рекомендуется использовать метод toJson()
Сущность БД
Все сущности, которые хранятся в БД "оборачиваются" в экземпляр класса \Realweb\Api\Model\Data\Entity, который наследуется от \Realweb\Api\Model\Data\Data.
Имеет встроенный метод сохранения в БД. Сохраняются поля, возвращаемые статическим методом getFields класса Базы Данных этой сущности.
Наследуемый класс должен реализовывать метод _getDatabase (Необходимо для сохранения сущности в БД).
Класс имеет ряд часто используемых методов:
public static function cleanFromAliases(array &$arData, string $strAlias = "UALIAS_"): void- очищение данных сущностей от алиасов запроса. Полезно, если сущность сохраняется в кеш (меньше полей - меньше размер кеша)public static function getByAlias(array &$arData, string $strAlias): array- получение (и очищение) данных, не относящихся к сущности.public function setRefreshData(bool $bRefresh = true): self- полезно вызвать перед сохранением сущности, если дальнейшая работа с сущностью не планируется и данные в ней уже не нужныpublic function save(): bool- сохранение сущности в БД (Существующая сущность обновится, новая - добавится)public function delete(): bool- удаление сущности из БДpublic function isExist(): bool- проверка на существование записи в БД
Пример
php
class Database extends \Realweb\Api\Model\User\Database
{
....
public static function getQuery(?Pagination $obNav = null): Query
{
//В запросе будут содержаться поля другой таблицы
$obQuery = parent::getQuery()
->setSelect(self::getFields())
->addSelect("PHONE_AUTH.PHONE_NUMBER", "PHONE_NUMBER")
->registerRuntimeField(
"SOME_FIELD",
(new \Bitrix\Main\ORM\Fields\Relations\Reference(
"SOME_FIELD",
\Bitrix\Sale\Internals\FuserTable::class,
\Bitrix\Main\ORM\Query\Join::on('this.ID', 'ref.USER_ID')
))->configureJoinType(\Bitrix\Main\ORM\Query\Join::TYPE_LEFT),
)
->addSelect($strFUserIdField . '.ID', 'F_USER_ID')
->addSelect($strFUserIdField . '.CODE', 'F_USER_CODE')
->addSelect($strFUserIdField . '.DATE_INSERT', 'F_USER_DATE_INSERT')
->addSelect($strFUserIdField . '.*', 'F_USER_')//Получение вообще всех полей с префиксом F_USER_
;
return $obQuery;
}
}
class Entity extends \Realweb\Api\Model\User\Entity
{
private ?\Realweb\Api\Module\User\Model\Fuser\Entity $_f_user = null;
public function setData(?array $arData = null): self
{
//Очищаем от лишних данных, если они там есть
self::cleanFromAliases($arData);
//В $arData содержатся поля F_USER_ID, F_USER_CODE, F_USER_DATE_INSERT
$arFuser = self::getByAlias($arData,"F_USER_");
//Теперь в $arFuser содержатся поля ID, CODE, DATE_INSERT, а в $arData теперь их нет
$this->fuser = new \Realweb\Api\Module\User\Model\Fuser\Entity($arFuser);
return parent::setData($arData);
}
}