使用Symfony2在控制器中重构代码

时间:2012-12-13 21:47:20

标签: php symfony controller

我在两个方法(创建和更新)中有这个代码。每次我需要更新或创建新用户时,我都需要使用salt对用户密码进行编码。

$factory = $this->get('security.encoder_factory');
$encoder = $factory->getEncoder($entity);
$password = $encoder->encodePassword($entity->getPassword(), $entity->getSalt());
$entity->setPassword($password);

为避免代码重复,我该怎么办?

  • 在控制器getEncondedPassword($entity) : return $encodedPassword
  • 中创建新方法
  • 使用DI注入$encoder作为必填字段
  • ,将此逻辑添加到表单中
  • 将此逻辑添加到模型中,并在实体对象的构造函数中传递$encoder

谢谢!

3 个答案:

答案 0 :(得分:0)

如果您的创建和编辑非常简单且完全相同,则可以将其组合到一个实际生成并验证表单的函数中。
一些代码:

class ProductController extends Controller
{
    /**
     * @Route("/create", name="_product_create")
     */
    public function createAction()
    {
        $product = new Product();

        return $this->productForm($product, $this->getRequest(), 'create');
    }

    /**
     * @Route("/edit/{product_id}", name="_product_edit_id")
     */
    public function editIdAction($product_id)
    {
        $entity_manager = $this->getDoctrine()->getEntityManager();
        $product_repository = $entity_manager->getRepository('VendorBundle:Product');

        $product = $product_repository->findOneBy(
            array('id' => $product_id)
        );

        return $this->productForm($product, $this->getRequest(), 'editId');
    }

    protected function productForm(Product $product, Request $request, $twig_name)
    {
        $form = $this->createForm(new ProductType(), $product);

        if ($request->getMethod() == 'POST') {
            $form->bindRequest($request);

            if ($form->isValid()) {
                // Do whatever we want before persisting/flushing

                return $this->redirect($redirect_url);
            }
        }

        $twig_params = array(

        );

        return $this->render(
            'VendorBundle:Product:' . $twig_name . '.html.twig', $twig_params
        );
    }

}

这将根据路线呈现create.html.twigeditId.html.twig 如果$product->getId() === null我们正在创建一个新实体,否则我们正在编辑。

答案 1 :(得分:0)

我认为正确的选择是模型/实体方法。 所以,我在这里留下我的解决方案:

public function hashPassword($container)
{
    $factory = $container->get('security.encoder_factory');

    $encoder = $factory->getEncoder($this);
    $password = $encoder->encodePassword($this->getPassword(), $this->getSalt());
    return $password;
}

在控制器中:

//hash user password
$userEntity->setPassword($userEntity->hashPassword($this->container));

答案 2 :(得分:0)

现在我已经改进了(我至少认为......)这个问题的答案。

我创建了一个类,它将从DI

接收$ encoderFactory
#services.yml 
parameters:
    password_encoder.class: Beubi\SignatureBundle\Handler\PasswordEncoder
services:
    password_encoder:
            class: %password_encoder.class%
            arguments: [@security.encoder_factory]

因此,我创建了一个将在Service容器中使用的类:

class PasswordEncoder
{
    protected $encoderFactory;

    public function __construct(EncoderFactory $encoderFactory)
    {
        $this->encoderFactory = $encoderFactory;
    }

    public function encodePassword($entity){
        $encoder = $this->encoderFactory->getEncoder($entity);
        return $encoder->encodePassword($entity->getPassword(), $entity->getSalt());
    }
}

然后在我的控制器中:

$password = $this->get('password_encoder')->encodePassword($entity);
$entity->setPassword($password);

这样,我的User对象就不知道$ factoryEncoder或如何编码密码。 我期待更多关于这个问题的评论......