Под “скрытыми” записями сегодня будут пониматься “unapproved”-записи в таблице. Кому лень ходить по сылкам: иногда не все записи какой-нибудь таблицы нужно показывать пользователю, например - если я не хочу показывать некоторые посты в блоге. Обычно для этого я делаю поле, например, is_hidden, а затем выбираю все записи, где is_hidden = 0. Проблема состоит в том, что я обычный человек и могу забыть поставить нужное мне условие. Поэтому я хочу получить какое-нибудь простое, но очень эффективное решение такой проблемы. В ActiveRecord этим решением является default_scope. А я вам сегодня расскажу, как этого добиться в Doctrine.
Итак, представим, что у нас есть табличка Post:
Post:
actAs:
Timestampable: ~
columns:
title: { type: string(128), notnull: true }
text: { type: text, notnull: true }
is_hidden: { type: boolean, notnull: true, default: 0 }
Самый простой, на первый взгляд, подход - переопределять PostTable::createQuery(), чтобы этот метод возвращал уже Query с нужным нам “WHERE is_hidden = 0″. К сожалению, не всегда это помогает. Например, при выборке постов для какой-либо категории через $category->Posts этот метод не сработает.
Есть гораздо более простой способ сделать то, что нам нужно - использовать listener-ы. В Doctrine есть довольно много событий, которые мы можем “слушать” и на которые мы можем реагировать. В данном случае нам подходит событие “preDqlSelect”, которое входит в группу “DQL Hooks“, и которое вызывается перед выполнением запроса на выборку записей. Как нам нужно прореагировать на событие: взять Doctrine_Query из Doctrine_Event и добавить в него дополнительные условия выборки.
Самый простой способ - переопределить метод preDqlSelect в самой записи:
class Post extends BasePost
{
public function preDqlSelect(Doctrine_Event $event)
{
$params = $event->getParams();
$event->getQuery()->addWhere("{$params['alias']}.is_hidden = 0");
}
}
В первой строке метода мы получаем параметры запроса, из которых нам нужен alias - можете считать это обычным alias-ом таблицы из SQL (в данном случае это alias таблицы в DQL), т.е. при таком DQL:
FROM Post p
alias-ом будет “p”.
Во второй строке мы получаем текущую query и добавляем в неё условие “is_hidden = 0″.
Мы не можем использовать ->where(), т.к. этот метод сотрет все имеющиеся части WHERE в запросе. В то же время ->addWhere и ->andWhere ведут себя так же, как и ->where при отсутствии where-части запроса.
Собственно, вот и всё - тепер у нас будут выбираться только “видимые” посты.
Во второй части будет показано, как сделать созданный в этом посте код более реюзабельным, а также как сделать так, чтобы в backend-е посты показывались полностью.
written by fxposter
\\ tags: Doctrine, Symfony
Последние комментарии