我正在开发一个Symfony项目(我的第一个),我必须从我的Widget
类中检索一组属于Page
的小部件。但是,在返回结果之前,我需要验证 - 对于外部服务 - 用户有权查看每个小部件。如果没有,当然,我需要从结果集中删除小部件。
使用CakePHP或Rails,我会使用回调,但我没有找到类似Symfony的东西。我看到事件,但如果我正确地阅读事物(这总是需要讨论),那些似乎与控制器/操作更相关。我的后备解决方案是覆盖WidgetPeer
类中的各种检索方法,转移它们通过执行授权的自定义方法并适当地修改结果集。但是,这感觉就像是大规模的过度杀伤,因为我必须覆盖每个选择方法,以确保授权完成,而未来的开发人员不必考虑它。
看起来行为对此有用(特别是因为它可能是可想象的,我将来可能需要授权其他类实例),但我找不到任何关于它们的正确文档做出合格的评估。
我错过了什么吗?似乎必须有更好的方法,但我还没有找到它。
答案 0 :(得分:1)
首先,我认为基于行为的方法是错误的,因为它增加了模型层耦合水平。
有sfEventDispatcher::filter()
方法,允许您分别过滤传递给它的参数。
因此,草案代码如下:
<somewhere>/actions.class.php
public function executeBlabla(sfWebRequest $request)
{
//...skip...
$widgets = WidgetPeer::getWidgetsYouNeedTo();
$widgets = $this->getEventDispatcher()->filter(new sfEvent($this, 'widgets.filter'), $widgets));
//...skip...
}
apps/<appname>/config/<appname>Configuration.class.php
//...skip...
public function configure()
{
$this->registerHandlers();
}
public function registerHandlers()
{
$this->getEventDispatcher()->connect('widgets.filter', array('WidgetFilter', 'filter'));
}
//...skip
lib/utility/WidgetFilter.class.php
class WidgetFilter
{
public static function filter(sfEvent $evt, $value)
{
$result = array();
foreach ($value as $v)
{
if (!Something::isWrong($v))
{
$result[] = $v;
}
}
}
}
希望你有个主意。
答案 1 :(得分:0)
以下是有关Symfony 1.2 Propel行为的一些文档:http://www.symfony-project.org/cookbook/1_2/en/behaviors。
为什么不在您的Page对象上设置'getAllowedWidgets'来执行您要查找的检查?类似的东西:
public function getAllowedWidgets($criteria = null, PropelPDO $con = null) {
$widgets = $this->getWidgets($criteria, $con);
$allowed = array();
// get access rights from remote service
foreach($widgets as $widget) {
// widget allowed?
$allowed[] = $widget;
}
return $allowed;
}
但是,如果始终希望在选择Page的Widgets时执行此检查,那么Propel的行为是您最好的选择。
答案 2 :(得分:0)
虽然,至少在理论上,我仍然认为行为是正确的方法,我找不到足够的关于他们在Symfony 1.4.x中的实现的文档,给我一个温暖和模糊,它可以是如果有的话,完成没有很多胃灼热。即使查看Propel自己的行为文档,我也看不到触发前或后检索钩子来触发我需要采取的操作。
结果,我采取了我的后备路径。但是,经过一些源代码筛选后,我意识到它并不像我最初想的那么费力。每种检索方法都经过BasePeer
模型的doSelect()
方法,所以我只是在可自定义的Peer
模型中覆盖了那个:
static public function doSelect( Criteria $criteria, PropelPDO $con = null ) {
$all_widgets = parent::doSelect( $criteria, $con );
$widgets = array();
foreach ( $widgets as $i => $widget ) {
#if( authorized ) {
# array_push( $widgets, $widget );
#}
}
return $widgets;
}
我还没有连接服务调用以进行授权,但这似乎可以按预期方式用于修改结果集。当我必须为其他模型实例提供授权时,我将不得不重新审视行为以保持DRY,但看起来这样就足够了。