symfony sfDoctrineGuardPlugin generator.yml由user_id过滤

时间:2010-09-10 14:18:04

标签: symfony1 doctrine

我知道在前端使用admin generator.yml可能会有些奇怪,但每个页面都是列表或编辑页面,这绝对是最简单的事情。

在编写登录模块后,我已经安装了sfDoctrineGuardPlugin并使用关系将它们链接到我的主用户表。数据库中的所有内容都依赖于这一个表,并且数据已经在当前的实时站点上建立了8个多月,我需要保留它。

我目前的问题是,一旦有人登录并在防护系统中存储了ID,我需要所有页面按其过滤所有结果,包括列表和编辑。

有没有一种简单的方法可以做到这一点,还是我需要为每个列表使用table_method?

以上唯一的问题是ID出现在地址中,我需要它以确保人们无法查看不应该的数据。

此外,这很可能很快就会改变,目前表格是MyISAM以便使用更好的自动增量,可以让用户按比例增加,这样每个人都从一个人开始。但是它似乎没有做外键,因此当我编写代码将其转换为INNOBDB时,地址中的ID对于不能改变的人来说变得更加重要。

Owner:
  columns:
    id: { type: integer(4), primary: true, autoincrement: true }
    slname: { type: string(64), notnull: true }
    uuid: { type: string(36), notnull: true }
    e_mail: { type: string(64) }
    user: { type: string(16) }
    pass: { type: string(40), notnull: true }
    subscription: { type: integer(4), default: '0', notnull: true }
    registered: { type: integer(1), default: '0', notnull: true }
  relations:
    Subscription:  { local: subscription, foreign: id }
    User: { class: sfGuardUser, foreign: id, local: id, type: one, onDelete: cascade, foreignType: one, foreignAlias: Owner }

一旦插件工作正常,我打算从上表中删除密码并使用默认密码并强制每个人进行新的传递。

编辑:

感谢Ben我认为模板有效。它无论如何都要在数据库中添加。

 class Doctrine_Template_Owned extends Doctrine_Template
{
    protected $_options = array(
        'name'          =>  'owner_id',
        'type'          =>  'integer',
        'length'        =>  11,
        'options'       =>  array(
            'default' => 0,
            'notnull' => true
        )
    );

    public function setTableDefinition()
    {
        $this->hasColumn($this->_options['name'], $this->_options['type'], $this->_options['length'], $this->_options['options']);
        $this->addListener(new Doctrine_Template_Listener_Owned($this->_options));
    }
}

然而,听众没有接缝被召唤。

class Doctrine_Template_Listener_Owned extends Doctrine_Record_Listener
    {
        protected $_options = array();

        public function __construct(array $options)
        {
            $this->_options = $options;
        }

        public function preDqlSelect(Doctrine_Event $event)
        {
            $params = $event->getParams();
            $field = $params['alias'] . '.' . $this->_options['name'];
            $query = $event->getQuery();

            if (( ! $query->isSubquery() || ($query->isSubquery() && $query->contains(' ' . $params['alias'] . ' '))) && ! $query->contains($field)) {
                $query->addPendingJoinCondition(
                    $params['alias'], $field . ' = ' . sfContext::getInstance()->getUser()->getGuardUser()->getId()
                    );
            }
        }
    }

侦听器的代码是软删除的代码,其中删除了时间表和布尔检查。尽管如此,该线也不会出现在开发栏中。

2 个答案:

答案 0 :(得分:0)

只需更改actions.class.php文件中的函数即可。 例如,可以更改listSuccess函数以过滤ID = USERID

的结果

答案 1 :(得分:0)

如果你需要广泛应用这个应用程序,我会使用一个学说行为,而不是在行动层面上做。

看看SoftDelete行为是如何工作的(它的两个文件,一个模板和一个监听器,在lib / vendor / symfony / lib / plugins / sfDoctrinePlugin / lib / vendor / Doctrine / Template中,以及其中的Listener子文件夹) ) - 您应该能够调整它以始终添加user_id = x子句而不是它当前的内容,然后将其添加到schema.yml中以用于相关类。

然后你需要获得user_id到学说。您可以在config / ProjectConfiguration.class.php中添加一个名为“configureDoctrine”的方法,如果它存在于doctrine中,它将被调用。不确定将其传递给doctrine的最佳位置,但是您应该将当前用户的用户ID传递给此方法中的doctrine - sfContext :: getInstance() - > getUser() - > getGuardUser() - >得到它的getId()。然后该行为应从此处拉取值。如果没有别的,监听器或模板类上的静态属性应该可以工作。

你可以通过从模板中调用sfContext :: getInstance来直接选择用户id,但不建议,因为它在doctrine / symfony之间创建了额外的链接,这是针对整个依赖注入/没有全局状态的symfony,东西迟早会破裂。

如果由于任何原因这不起作用,我会考虑从生成器模板中覆盖相关文件(在lib / vendor / symfony / plugins / sfDoctrinePlugin / data / generator / sfDoctrineModule / admin /) 。您可以通过添加项目顶级数据文件夹下的任何文件来完成此操作。或者我认为管理员生成的模块也会抛出你可能听到的事件......

在回复有关它不起作用的评论时,如果您没有使用任何其他依赖回调的行为,请确保您的databases.yml具有use_dql_callbacks:true属性:

all:
  doctrine:
    class: sfDoctrineDatabase
    param:
      dsn:      mysql:host=localhost;dbname=mydb
      username: myuser
      password: mypassword
      attributes:
        use_dql_callbacks: true