Метод
wakeUp достаточно полезен в различных сценариях работы.
Вот несколько примеров его использования:
1. Использование в целях тестирования.
Предположим у вас есть некоторый класс объекта
Record, который является объектом для RecordTable.
Вы написали некоторую функицю, которая выполняет сложную проверку (например что дата записи не в прошедшем времени, что указанный пользователь является активным и т.п.).
Допустим вот такая:
{
public function isAcceptable( Record $record): bool
{
if ( $this->container()->getDateSerivce()->isEarlyDate($record->getDate()) )
{
return false;
}
if ( !$this->container()->getUserRepository()->isActiveUser($record->getUserId()))
{
return false;
}
// ...
return true;
}
}
Как вам ее протестировать?
Наверное нужно получить объект класса Record из БД и отправить в функцию, но что делать если такой записи нет? Создать ее? Но это же тест, а создание это запись в БД, которая может отразиться над ругих тестах.
Решение - wakeUp:
// Now - 20.03.2025
$earlyDateObject = Record::wakeUp([
'ID' => -1,
'DATE' => DateTime::createFromTimestamp(strtotime("10.03.2025"))
]);
assertFalse( $checker->isAcceptable($earlyDateObject) );
$unexistedUserRecord = Record::wakeUp([
'ID' => -1,
'DATE' => DateTime::createFromTimestamp(strtotime("21.03.2025")),
'USER_ID' => -1
]);
assertFalse( $checker->isAcceptable($earlyDateObject) );
$normalRecord = Record::wakeUp([
'ID' => -1,
'DATE' => DateTime::createFromTimestamp(strtotime("21.03.2025")),
'USER_ID' => 1
]);
assertTrue( $checker->isAcceptable($earlyDateObject) );
Таким образмо мы написали псевдо-юнит тест который покрывает нашу функцию и при этом не создает и не использует ничего лишнего из БД.
2. Восстановление данных из кеша.
Предположим, заходя на страницу вы закешировали ID ресурсов отображаемых на ней, но есть некоторая произвольная величина закешировать которую вы ну никак не можете.
Механизм вычисления этой величины описан в функции
calculatePriority, но она принимает объект
Record, а у вас массив из кеша.
Таким образом получается некоторый такой код:
$myCachedIds = Container::getInstance()->getCacheService()->get('MY_SUPER_KEY');
$records = RecordTable::createCollection();
foreach($myCachedIds as $recordId)
{
$records->add(
Record::wakeUp([
'ID' => $recordId
])
);
}
$records->fill();
foreach( $records as $record )
{
$arResult['RECORDS'][] = [
'ID' => $record->getId(),
'PRIORITY' => getPriority($record)
];
}
3. Получение данных из других источников.
Допустим у нас есть несколько табилц: Автор и Книга.
Автор содержит:
- ID
- ФИО (NAME)
- Город (CITY)
Книга содержит:
- ID
- ID автора
- Название
Предположим мы делаем постраничную навигацию для каталога книг и нам нужно вывести ФИО автора.
$authorCollection = AuthorTable::createCollection();
$books = BookTable::getList()->fetchCollection();
foreach( $books as $book)
{
$authorCollection->add(
Author::wakeUp([
'ID' => $book->getAuthorId()
])
);
}
$authorCollection->fill(['CITY', 'NAME']);
Согласен, здесь пример кажется немного отстраненным, ведь для связи 1:n можно было бы просто дозапросить данные из БД в 1 запрос, но если у вас таких таблиц уже не 2, а скажем 4-6, то последовательные запросы на получение только необходимой информации серьезно сократят время на получение данных.