【问题标题】:symfony sfDoctrineGuardPlugin generator.yml filtering by user_idsymfony sfDoctrineGuardPlugin generator.yml 按 user_id 过滤
【发布时间】:2010-09-10 14:18:03
【问题描述】:

我知道在前端使用 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()
                    );
            }
        }
    }

监听器的代码是删除时间表和布尔检查的软删除代码。不过,这条线并没有出现在开发栏中。

【问题讨论】:

    标签: symfony1 doctrine


    【解决方案1】:

    如果您需要在整个应用程序范围内执行此操作,我会使用原则行为,而不是在操作级别执行。

    看看 SoftDelete 行为的工作原理(它的两个文件,一个模板和一个侦听器,位于 lib/vendor/symfony/lib/plugins/sfDoctrinePlugin/lib/vendor/Doctrine/Template 中,以及其中的 Listener 子文件夹) - 您应该能够对其进行调整以始终添加一个 user_id = x 子句而不是它目前所做的,然后将其添加到您的 schema.yml 以获取相关类。

    然后你需要把 user_id 拿到教义。您可以在 config/ProjectConfiguration.class.php 中添加一个名为“configureDoctrine”的方法,如果学说存在,它将被调用。不确定在原则中最好将其传递到哪里,但您应该在此方法中将当前用户的用户 ID 传递给原则 - sfContext::getInstance()->getUser()->getGuardUser()->getId()为拿到它,为实现它。然后行为应该从这里提取值。如果不出意外,监听器或模板类上的静态属性应该可以工作。

    您可以通过从模板中调用 sfContext::getInstance 来使行为直接选择用户 ID,但不建议这样做,因为它会在学说/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
    

    【讨论】:

    • 谢谢本。我已将我编写的代码添加到帖子中。虽然模板接缝正在工作并将列正确添加到数据库中,但侦听器却没有。
    • 非常感谢本。没有你的帮助,我不会对 symfony 有任何了解。
    【解决方案2】:

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

    的结果

    【讨论】:

    • 还会考虑默认过滤器吗?
    • 应该的。如果没有,请告诉我;)
    • 唯一的问题是,目前没有 listSuccess 因为它使用的是 yaml 文件。我将如何编写一个获取它将要执行的查询以添加 addWhere('user_id = ?',$userID);
    • 这种方式会做很多工作,除非你想离开它,你可以编辑 url 中的 id,它需要应用于编辑/删除等以及只是列表。跨度>
    猜你喜欢
    • 2011-05-29
    • 1970-01-01
    • 1970-01-01
    • 2011-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多