小编Ser*_*gri的帖子

在Doctrine Entity Listener的preUpdate中保留其他实体

为了清楚我在这里继续讨论开始在这里.

Doctrine Entity Listener中,在preUpdate方法中(我可以访问实体任何字段的旧值和新值)我试图保持与焦点实体无关的实体.

基本上我有实体A,当我在我想要写的一个字段中更改一个值时,在project_notification表中,字段oldValue,newValue加上其他字段.

如果我没有在preUpdate方法中刷新,则新通知实体不会存储在DB中.如果我冲洗它,我进入一个无限循环.

这是preUpdate方法:

public function preUpdate(ProjectTolerances $tolerances, PreUpdateEventArgs $event)
{
    if ($event->hasChangedField('riskToleranceFlag')) {
    $project = $tolerances->getProject();                
    $em = $event->getEntityManager();
    $notification = new ProjectNotification();
    $notification->setValueFrom($event->getOldValue('riskToleranceFlag'));
    $notification->setValueTo($event->getNewValue('riskToleranceFlag'));
    $notification->setEntity('Entity'); //TODO substitute with the real one
    $notification->setField('riskToleranceFlag');
    $notification->setProject($project);
    $em->persist($notification);


    // $em->flush(); // gives infinite loop
    }
}
Run Code Online (Sandbox Code Playgroud)

谷歌搜索了一下我发现你不能在监听器内调用flush,这里建议将这些东西存放在一个数组中,以便稍后在onFlush中进行刷新.尽管如此它不起作用(并且它可能不起作用,因为在调用preUpdate之后,侦听器类的实例会被破坏,因此当您稍后调用onFlush时,无论您在类级别保存为protected属性都会丢失或者我错过了什么?).

以下是监听器的更新版本:

class ProjectTolerancesListener
{
    protected $toBePersisted = [];

    public function preUpdate(ProjectTolerances $tolerances, PreUpdateEventArgs $event)
    {
        $uow = $event->getEntityManager()->getUnitOfWork();
//        $hasChanged = false;

        if ($event->hasChangedField('riskToleranceFlag')) {
        $project …
Run Code Online (Sandbox Code Playgroud)

symfony doctrine-orm

18
推荐指数
3
解决办法
1万
查看次数

Symfony2授权:选民比.ACL

我即将开始一个项目,需要几种具有不同"权力"的用户.

为了给出一些上下文,我期待1000到10000个用户.

我至少有3个"层":A,B,C

"A"可以是"咨询公司",每个公司都有不同的客户"B",每个客户都有几个项目"C".

一个用户可能需要查看其公司"A"管理的所有项目的概述.另一个只是其中一个公司"B".另一个项目"A".某些用户可能会在每个级别上被授予更细粒度的细节(可能用户在"B"级别上具有细粒度级别但在"A"级别上看不到任何内容).某些用户可能只有读取权限,其他用户可以阅读和修改,有些用户可以阅读,修改和创建.

最后,我可能会得到100000或100万个"对象",我必须向其授予读/写/删除/修改权限.

我必须在相对简单的选民系统或完整的ACL之间做出选择.虽然看起来非常强大,但我注意到ACL并没有很好地记录在案.我几乎丢弃了选民,但后来我读到了这篇让我改变主意的文章.从文章引用:

这通常是您在谈论ACL时所能想到的:能够说"此用户"可以"编辑"某些"对象".在Symfony2中,您可以利用自定义选民来使用您拥有的任何复杂业务逻辑来确定这一点.

根据这篇文章你可以使用选民作为:

isGranted的另一个常见未知属性是第二个参数,它是任何类型的"对象"

所以这是我的问题,考虑到我暴露的背景:

1)选民选项是否会授予我所需的所有灵活性?

2)性能明智(ACL特别指出,即使有数百万个对象也没有性能衰退,我对选民有疑虑)

3)如果我选择选民,我可以安全地使用FOSUserBundle,尽管指定了与Symfony 1.2相关的东西吗?

security authorization multi-user symfony

6
推荐指数
1
解决办法
1872
查看次数

Symfony2 custom Voter:无法从Voter内部访问getDoctrine

我正在尝试实现自定义选民.

从控制器我这样称呼它:

$prj = $this->getDoctrine()->getRepository('AppBundle:Project')->findOneById($id);
if (false === $this->get('security.authorization_checker')->isGranted('responsible', $prj)) {
    throw new AccessDeniedException('Unauthorised access!');
}
Run Code Online (Sandbox Code Playgroud)

第一行正确检索Project对象(我使用转储检查).

这个问题发生在选民内部

<?php
namespace AppBundle\Security\Authorization\Voter;

use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\User\UserInterface;


class ProjectVoter implements VoterInterface
{
    const RESPONSIBLE = 'responsible';
    const ACCOUNTABLE = 'accountable';
    const SUPPORT = 'support';
    const CONSULTED = 'consulted';
    const INFORMED = 'informed';

    public function supportsAttribute($attribute)
    {
        return in_array($attribute, array(
            self::RESPONSIBLE,
            self::ACCOUNTABLE,
            self::SUPPORT,
            self::CONSULTED,
            self::INFORMED,
        ));
    }

    public function supportsClass($class)
    {
        $supportedClass = 'AppBundle\Entity\Project';

        return $supportedClass === $class || is_subclass_of($class, $supportedClass); …
Run Code Online (Sandbox Code Playgroud)

doctrine symfony symfony-security

6
推荐指数
1
解决办法
2249
查看次数

对Popovers的Bootstrap XSS攻击

我在这里读到我可以在弹出窗口中启用HTML,这可能是XSS攻击的潜在问题.

在我的情况下,弹出窗口将不包含任何形式等,但只包含文本或链接或表格或图像.

我可以安全地使用它们而不会引起XSS攻击吗?

谢谢!

SN

xss twitter-bootstrap

6
推荐指数
1
解决办法
860
查看次数

在Symfony2(Doctrine)和MySQL中启用微秒

我有一个实体,其中有一列"datetime"类型来存储时间戳.

/**
 * @ORM\Column(type="datetime")
 */
protected $timestamp;
Run Code Online (Sandbox Code Playgroud)

我有MySQL 5.5.40,我发现它不存储微秒.所以我切换到5.6.21并导入了所有表格和数据.

我试图将类型声明为

 * @ORM\Column(type="datetime(6)")
Run Code Online (Sandbox Code Playgroud)

但它给了我一个错误.所以我通过以下方式直接在DB中更改了它:

ALTER TABLE symfony.hrmgmt MODIFY timestamp DATETIME(6);
Run Code Online (Sandbox Code Playgroud)

在我的控制器中我这样做:

  $dt = new \DateTime('now');
  $newHREvent->setTimestamp($dt);
Run Code Online (Sandbox Code Playgroud)

但是,时间戳存储的时间没有秒.

我可以(现在)通过SQL手动输入带小数值的datetime,但是当我通过我的控制器执行它时,它总是以.000000存储

我想这是因为Doctrine不知道它也可以存储微秒.

我的PHP版本仍然是5.4.34.

谢谢!

php mysql datetime symfony doctrine-orm

5
推荐指数
1
解决办法
2412
查看次数

提交后,Symfony2表单刷新同一页面

我有一个表单,其内容是从数据库创建的.

在我的控制器中我有:

/**
 * @Route("/HR/manage/{projectID}", name="hr_manage")
 */
public function manageHRAction(Request $request, $projectID)
{
//here I get all the data from DB and create the form
if ($form->isValid()) 
    {
    //here I do all the relevant changes in the DB
    return $this->render('HR/show.html.twig', array('hrlist' => $HRsInMyDomain, 'form' => $form->createView(), 'HRs' => $HRsInThisProject, 'project' => $prj, ));
    }
return $this->render('HR/show.html.twig', array('hrlist' => $HRsInMyDomain, 'form' => $form->createView(), 'HRs' => $HRsInThisProject, 'project' => $prj, ));
}
Run Code Online (Sandbox Code Playgroud)

它正确地更新了DB上的信息,但它不会再次构建具有更新数据的表单.而不是"isValid()"内部的返回,我只需要在当前页面上刷新.

我认为这是可能的,也很容易实现,但我没有找到如何做到:/

编辑 - 这里有更相关的代码:

/**
 * @Route("/HR/manage/{projectID}", name="hr_manage")
 */ …
Run Code Online (Sandbox Code Playgroud)

forms page-refresh symfony

4
推荐指数
2
解决办法
2万
查看次数

Symfony2最佳实践,业务逻辑和单元测试

我想用单元测试创​​建一个高度可维护的代码.

我已经阅读了最佳实践,因此根据最佳实践组织目录,只有一个名为AppBundle的包,我正在使用注释.

我有业务逻辑问题.我读过我不应该把业务逻辑放在控制器中.由于绝大多数代码都不是要重用,我把逻辑放在控制器中.昨天我在这里读到"逻辑应该存在于控制器中,除非你要对它进行单元测试或直到你需要重新使用它"这让我晕了:如果把逻辑放在里面,我不会进行单元测试控制器?

据我所知,"控制器应尽可能精简,只需很少的代码就可以将各种东西粘合在一起".但形式怎么样?表单通常具有类似"显示表单,如果它有效并执行某些操作并显示另一页"的逻辑.现在,如果我要将表单创建和逻辑放在服务(或模型?)中,我必须将页面渲染命令放在其中,所以基本上控制器将是1行,所有其余的都在服务,以及显示哪个页面的实际决定将在服务内部完成,而不是控制器本身...那么控制器的重点是什么,只是路由?

我真的需要在继续之前理解这一点(我已经开发了3个月,我必须做很多工作,但现在比从来没有好过)......

谢谢!

编辑:一些额外的考虑因素,以解决下面的一些评论.

我清楚地了解了表单在Symfony中的工作原理,创建了表单,并在同一个地方使用"isValid()"进行管理.

让我们假设以下控制器执行以下操作:

get the current customer from security context
queries the DB to get the field $user->getIsBillable()
if the user is not billable
    queries the DB to find if someone else is paying for him
else //the user is billable
    create and manage form1
if the user is not billable but there is someone who is paying for him
    check if the license is active (I have to call an external …
Run Code Online (Sandbox Code Playgroud)

unit-testing symfony-forms symfony

4
推荐指数
1
解决办法
707
查看次数

Symfony2/Doctrine:获取"Loggable"实体更改后更改的字段

在Symfony2项目中,我正在使用Loggable Doctrine Extension.

看到有一个LoggableListener.

当可记录实体中的(可记录)字段发生变化时,确实会触发事件吗?如果是这样,有没有办法获得触发它的字段列表?

我想象一个实体的情况,比方说10个字段,其中3个可记录.对于3中的每一个,如果它们改变了值,我想执行一些操作,因此如果它们中的3个改变,将执行3个动作.

任何的想法?

谢谢!

编辑

阅读下面的评论并阅读关于学说的事件的文档,我理解有3个选项:

1)如果我使用的是doctrine> 2.4,那么即使使用参数,可以直接在实体级使用生命周期回调

2)我可以收听并订阅Lifecycle Events,但在这种情况下,文档会说"Lifecycle events are triggered for all entities. It is the responsibility of the listeners and subscribers to check if the entity is of a type it wants to handle."

3)做你建议的,使用实体监听器,你可以在实体级别定义哪个是将"附加"到类的监听器.

即使第一个解决方案看起来更容易,我也会读到"你也可以使用这个监听器来实现已经改变的所有字段的验证.当使用昂贵的验证来调用时,这比使用生命周期回调更有效".什么被认为是"昂贵的验证?".

在我的情况下,我必须执行的是"如果实体Y的字段X发生了变化,而不是在通知表上添加通知"用户Z将X(Y)的值从A更改为B"

哪个是最合适的方法,考虑到我有大约1000个这样的领域?

EDIT2

为了解决我的问题,我正在尝试在监听器中注入service_container服务,这样我就可以访问调度程序来调度一个新事件,该事件可以执行我需要的新实体的持久化.但是我该怎么做呢?

我尝试了通常的方法,我将以下内容添加到service.yml

app_bundle.project_tolereances_listener:
    class: AppBundle\EventListener\ProjectTolerancesListener
    arguments: [@service_container] 
Run Code Online (Sandbox Code Playgroud)

当然我向听众添加了以下内容:

protected $container;

public function __construct(ContainerInterface $container)
{
    $this->container = $container;
}
Run Code Online (Sandbox Code Playgroud)

但我得到以下内容:

Catchable …
Run Code Online (Sandbox Code Playgroud)

symfony doctrine-orm doctrine-extensions

3
推荐指数
1
解决办法
5599
查看次数

Symfony2 Doctrine2 UniqueEntity 验证指定一个值

我已经在时尚中使用 UniqueEntity ,例如:

/**
 * @ORM\Entity()
 * @ORM\Table(name="benefit_group_category")
 * @UniqueEntity(fields={"name", "project"}, ignoreNull=false, message="Duplicated group category for this project")
 */
Run Code Online (Sandbox Code Playgroud)

所以我已经知道如何使用它了。

在另一种情况下我需要做的是:

 * @UniqueEntity(fields={"entityId", "status"}, message="There is already a Quality Review Pending for this entity")
Run Code Online (Sandbox Code Playgroud)

但是我需要指定对于相同的entityIdif status == 1,我不能有重复的 if ,但是如果status == 0它应该通过验证。

基本上,例如,我可以有任意数量的记录entityId = 37status = 0,但只有一个记录status = 1

这可能吗?

编辑:请在这里找到它的更新版本,以进行仔细检查。在我最初的问题中,我忘了提及另一个参数(entityName),但它并没有改变它的本质。

存储库类

<?php

namespace AppBundle\Entity;

/**
 * QualityReviewRequestRepository
 *
 * This class was generated by the Doctrine ORM. …
Run Code Online (Sandbox Code Playgroud)

symfony doctrine-orm

3
推荐指数
1
解决办法
772
查看次数

Symfony2:登录尝试失败后获取"用户名"

我使用Symfony2和FOSUserBundle.

我想防止登录页面上的暴力攻击.

为此我在事件上创建了一个监听器:

AuthenticationEvents::AUTHENTICATION_FAILURE
Run Code Online (Sandbox Code Playgroud)

除了IP,我还想获得用户在尝试登录时传递的"用户名".通过这种方式,我可以获得一些黑客试图入侵该帐户的用户.同时考虑到同一个IP可以属于多个用户,我可以通过这种方式进行区分,如果我在一秒钟内获得5次尝试,如果我真的面临攻击,或者只是有5个用户大致同时无法进行身份验证(但也许是"背后"那个地址有150个用户,所以它可以发生;)).

有什么方法可以获得表单中传递的用户名吗?

当然,在记录IP,用户名和时间戳之后,我需要实现将可疑IP添加到黑名单表的部分.然后,我将决定是否实施选民,或禁止IP我的应用程序编写Apache配置文件.

谢谢!

brute-force symfony fosuserbundle

2
推荐指数
1
解决办法
970
查看次数