sfContext :: getInstance() - > getUser()在验证器的createQuery中不起作用

时间:2011-07-28 23:02:59

标签: symfony1 model doctrine validation

现在:已解决 - 再也无法再现

对于某些特定的应用程序安全性,我在表上有以下createQuery函数,即,如果您具有“管理员”凭据,或者您是存储在MembershipDelegate关系中的用户,则只能访问表记录。 / p>

class OrganisationTable extends Doctrine_Table
function createQuery($alias = ''){

    if (!$alias){
        $alias = 'o';
    }

    $query = parent::createQuery($alias);
    try {
        $user = sfContext::getInstance()->getUser();
    }catch(Exception $e){
        if ($e->getMessage() == 'The "default" context does not exist.'){
            return $query;
        }else{
            throw $e;
        }
    }

    if ($user->hasCredential('Administrator')){
        //all good

    }else{


        $userId = $user->getAttribute('userId');
        print "<!--testaa ".print_r($user->getCredentials(),1).'-->';
        $query->
        leftJoin("$alias.MembershipDelegate mdelsec")->
        addWhere ("mdelsec.joomla_user_id=$userId");
    }

    return $query;
}

这似乎在所有级别都可以正常工作,但是有一个选项验证器,$ user对象似乎空了

    /**
     * Person form base class.
     *
     */
     ...
    abstract class BasePersonForm extends BaseFormDoctrine
    {
      public function setup()
      {
        $this->setWidgets(array(

    ...
          'organisation_id'                          => new sfWidgetFormDoctrineChoice(array('model' => $this->getRelatedModelName('Organisation'), 'add_empty' => true)),


    class PersonForm extends BasePersonForm{

        public function configure(){

            $this->widgetSchema['organisation_id']->setOption('renderer_class', 'sfWidgetFormDoctrineJQueryAutocompleter');
            $this->widgetSchema['organisation_id']->setOption('renderer_options', array(
            'model' => 'Organisation',
            'url' => NZGBCTools::makeUriJoomlaCompatible(
                    sfContext::getInstance()->getController()->genUrl('organisation/jsonList'))
            ));
            $this->validatorSchema['organisation_id']->setOption('required',false);

有没有其他方法可以在模型中获取用户对象?

这种行级安全性方法可能不是MVC,但IMO比在操作中实现相同的安全性概念更安全和更优越:

  • 它可以与开箱即用的管理生成器模块一起使用
  • 忘记在某处实施它更加困难
  • 有时可能不需要任何凭据,只有超级管理员访问

3 个答案:

答案 0 :(得分:0)

我不知道在模型中获取会话用户的另一种方法(我认为没有),但如果你能够,你应该将用户对象传递给模型。

答案 1 :(得分:0)

我认为你在这里遗漏了一些东西,你已经把MVC层混合了很多。我的建议是使模型独立于Controller(委托给Controller特定于Context的情况),并且验证也应由Controller完成(应该有一个接收请求的动作,绑定表单并验证它。你必须在那里定义上下文的特定情况。这就是我要做的事情:

  1. OrganisationTable类应该有两个方法:createQueryForAdministrator和createQueryForMembershipDelegate。每个人都做它应该做的事情,现在你应该更改Controller(处理它的动作)并执行以下操作:

    public function executeAction(sfWebRequest $request)
    {
      if ($this->getUser()->hasCredential('administrator'))
      {
        //call the administrator method
       } else {
        //call the other method
       }
     }
    
  2. 表单实例的操作还应检查用户凭据并执行以下操作:

    If ($user->hasCredential("administrator"))
    {
       sfContext::getInstance()->getConfiguration()->loadHelper("Url");
       $form->getValidator("organization_id")->setOption("url",url_for("@action"));
       [..]
    } else {
       [..]
    }
    
  3. 检查url helper reference,您可以考虑在操作等上加载帮助程序,也可以创建自己的帮助程序。希望这有帮助!

    已编辑:请查看有关sfContext class and alternatives

    的帖子

答案 2 :(得分:0)

现在看来这个问题是一个侥幸,因为我在修复用户身份验证的其他问题后无法重现问题。