Продолжая тему магических операций с xPDO-объектами, рассмотрим новый пример.
Дано: две таблицы. Одна содержит данные актуальных данных, вторая содержит исторические записи (когда заявка обновляется, перед сохранением запись переносится в историческую таблицу с сохранением ID на текущую). Это позволяет и всю историю изменений хранить, и не текущую таблицу актуальных данных не перегружать. Структуры таблиц идентичные, только что во второй таблице есть еще колонка orderid, хранящая ключ на первоисточник записи. В результате мы имеем возможность выдернуть и актуальную запись, и всю ее историю.
Задача: получить объект заявки и все исторические записи этой заявки одним массивом, и чтобы все объекты были инстансами одного и того же класса. Этот момент разъясню подробней:
Класс заявки — JKHOrder. Его таблица orders.
Класс исторических записей — JKHOrderHistory. Таблица — orders_history.
JKHOrderHistory не расширяет класс JKHOrder, так как у него совершенно другая логика, то есть это полностью самостоятельный объект.
Но у меня большая логика в админке завязана на ExtJS, и при выводе одной специфической странице, мне надо, чтобы объект исторической записи вел себя так, как будто это не историческая запись, а именно заявка (нужны специфические методы класса JKHOrder).
Вот как раз задача стоит такая: методом $modx->getCollection() из таблицы исторических записей (JKHOrderHistory) получить массив объектов JKHOrder.
Для реализации этого запрос будет выглядеть так:
// Указываем именно JkhOrderHistory, чтобы xPDO в запросе
использовал как источник именно таблицу исторических записей
$c = $this->modx->newQuery('JkhOrderHistory');
// Устанавливаем алиас
// В случае с подменой объектов обязательно, и должно совпадать с именем получаемых объектов и class_key,
чтобы не возникало xPDO-ошибок и в логи не разрастались.
// Так же этот алиас будет использоваться в конструкциях innerJoin и leftJoin
// Используйте ее сразу после ->newQuery
$c->setClassAlias('JkhOrder');
$c->select(array(
'JkhOrder.*',
// class_key обязательно, так как именно по этой колонке xPDO понимает
// какой именно объект надо вернуть
"'JkhOrder' as class_key",
));
// В конструкции where и т.п. очень советую использовать алиас
// то есть явно указывать принадлежность колонок
// иначе могут возникнуть SQL-ошибки
$c->where(array(
'JkhOrder.orderid' => 45
));
// а вот здесь уже указываем не JkhOrder
$orders = $modx->getCollection('JkhOrder', $c);
Вот и все. Получаем массив других объектов.