Symfony: как получить доступ к пользовательскому объекту на ранней стадии выполнения

У меня есть собственный класс маршрутизации, который проверяет версию объекта, чтобы можно было создавать черновые версии страниц, которые не будут отображаться на действующем сайте. Когда администратор щелкает для предварительного просмотра черновой версии страницы, мой класс PublishingHelper на внешнем интерфейсе (вызываемый из класса маршрутизации) проверяет разрешения пользователя, чтобы узнать, разрешено ли ему просматривать черновую версию этой страницы.

Я использую этот код:

$context = sfContext::getInstance();
$user = $context->getUser();

Но $user равен NULL.

У кого-нибудь есть идеи? Все мои поиски говорят, что это правильный способ получить пользовательский объект.

Спасибо,

Том


person Tom    schedule 26.08.2010    source источник
comment
Возможно, sfContext еще не инициализирован. Вы можете взглянуть на initialize() и loadFactories() (или аналогичные).   -  person Till    schedule 26.08.2010
comment
sfContext инициализируется (я проверял с помощью $context->hasInstance()). Я попробовал if ($user === null) $context-›loadFactories(), но это отправило его в рекурсивный цикл, поэтому, должно быть, loadFactories запускает процесс маршрутизации.   -  person Tom    schedule 26.08.2010
comment
Я нашел сгенерированный файл кеша для включения фабрик — config_factories.yml.php. Если я отредактирую этот файл и поставлю бит factory['user'] над битом factory['routing'], тогда пользовательский объект будет инициализирован! ... Теперь проблема в том, что у него нет ни идентификатора, ни деталей...   -  person Tom    schedule 26.08.2010
comment
@ Джон - да, я. Однако пользовательский объект, который я получил (из предыдущего комментария), возвращает null в $user->getGuardUser()   -  person Tom    schedule 26.08.2010
comment
Пробовали ли вы следующее после исправления ваших фабрик... sfContext::getInstance()->getUser()->getGuardUser()->getId()   -  person jgallant    schedule 26.08.2010


Ответы (2)


Спасибо за комментарии, Тилль/Джон, теперь мне удалось это исправить. Исправление фабрик не сработало, потому что при создании экземпляра пользовательского класса ни один из фильтров не запускался, поэтому у меня остался бесполезный пользовательский объект.

Я решил свои проблемы, просто взяв почти весь код функцииmatchUrl() моего пользовательского класса маршрутизации и добавив новую функцию doRouting() в тот же класс. matchUrl() теперь выглядит так:

public function matchesUrl($url, $context = array())
{
  if (false === $parameters = parent::matchesUrl($url, $context))
  {
    return false;
  }

  $parameters['module'] = 'content';
  $parameters['action'] = 'route';

  $this->url            = $url;
  $this->context        = $context;

  return $parameters;
}

и маршрутизация откладывается после фабрик и фильтров с помощью моего модуля/контроллера «контента»:

class contentActions extends sfActions
{
  public function executeRoute(sfWebRequest $request)
  {
    $router = $this->getRoute();
    $router->doRouting($router->url, $router->context);
  }

И функция doRouting() теперь перенаправляет прямо в соответствующий модуль/действие (правильно учитывая права пользователя).

person Tom    schedule 26.08.2010

Я думаю, что такие ограничения было бы проще реализовать в виде фильтра: http://www.symfony-project.org/reference/1_4/en/12-Filters

person Jakub Zalas    schedule 27.08.2010
comment
Я думаю, вы, наверное, правы. Этот способ работает нормально (как своего рода хакерский фильтр), поэтому я не буду его менять, но буду иметь в виду в следующий раз. - person Tom; 15.09.2010