Symfony:在控制器中发布后更改表单数据,然后将其保存到数据库

时间:2017-01-16 09:12:46

标签: php forms symfony

我正在研究Symfony,我遇到了一个问题如下: -

OrderAdminController:

<?php
namespace AppBundle\Controller;

use Symfony\Component\HttpFoundation\Request;
use Sonata\AdminBundle\Controller\CRUDController as Controller;
use AppBundle\Entity\Order;
use AppBundle\Entity\Month;

class OrderAdminController extends Controller
{

//overriding Default CRUD create action
    public function createAction()
    {

        $request = $this->getRequest();
         // this is the code where i am trying to change the coming values of ofrm fileds
         if(!empty($_POST)){
            $key =array_keys($_POST)[0];
            $date_to_floor = $_POST[$key]["date_to_floor"];
            $user_id = $_POST[$key]["assigned"];
            $hours_to_complete = $_POST[$key]["estimate"];
            $final_data = $this->adjust_working_hours($date_to_floor,$user_id,$hours_to_complete);
            $request->request->set('start_datetime', date('n/j/Y H:i',strtotime($final_data['start_date'])));
            $request->request->set('end_datetime', date('n/j/Y H:i',strtotime($final_data['end_date'])));
            $request->request->set('hours_remaining', $final_data['hours_remaining']);
        }
        // the key used to lookup the template
        $templateKey = 'edit';

        $this->admin->checkAccess('create');

        $class = new \ReflectionClass($this->admin->hasActiveSubClass() ? $this->admin->getActiveSubClass() : $this->admin->getClass());

        if ($class->isAbstract()) {
            return $this->render(
                'SonataAdminBundle:CRUD:select_subclass.html.twig',
                array(
                    'base_template' => $this->getBaseTemplate(),
                    'admin' => $this->admin,
                    'action' => 'create',
                ),
                null,
                $request
            );
        }

        $object = $this->admin->getNewInstance();

        $preResponse = $this->preCreate($request, $object);
        if ($preResponse !== null) {
            return $preResponse;
        }

        $this->admin->setSubject($object);

        /** @var $form \Symfony\Component\Form\Form */
        $form = $this->admin->getForm();
        $form->setData($object);
        $form->handleRequest($request);

        if ($form->isSubmitted()) {
            //TODO: remove this check for 4.0
            if (method_exists($this->admin, 'preValidate')) {
                $this->admin->preValidate($object);
            }
            $isFormValid = $form->isValid();

            // persist if the form was valid and if in preview mode the preview was approved
            if ($isFormValid && (!$this->isInPreviewMode($request) || $this->isPreviewApproved($request))) {
                $this->admin->checkAccess('create', $object);

                try {
                    $object = $this->admin->create($object);

                    if ($this->isXmlHttpRequest()) {
                        return $this->renderJson(array(
                            'result' => 'ok',
                            'objectId' => $this->admin->getNormalizedIdentifier($object),
                        ), 200, array());
                    }

                    $this->addFlash(
                        'sonata_flash_success',
                        $this->admin->trans(
                            'flash_create_success',
                            array('%name%' => $this->escapeHtml($this->admin->toString($object))),
                            'SonataAdminBundle'
                        )
                    );

                    // redirect to edit mode
                    return $this->redirectTo($object);
                } catch (ModelManagerException $e) {
                    $this->handleModelManagerException($e);

                    $isFormValid = false;
                }
            }

            // show an error message if the form failed validation
            if (!$isFormValid) {
                if (!$this->isXmlHttpRequest()) {
                    $this->addFlash(
                        'sonata_flash_error',
                        $this->admin->trans(
                            'flash_create_error',
                            array('%name%' => $this->escapeHtml($this->admin->toString($object))),
                            'SonataAdminBundle'
                        )
                    );
                }
            } elseif ($this->isPreviewRequested()) {
                // pick the preview template if the form was valid and preview was requested
                $templateKey = 'preview';
                $this->admin->getShow();
            }
        }

        $view = $form->createView();

        // set the theme for the current Admin Form
        $this->get('twig')->getExtension('form')->renderer->setTheme($view, $this->admin->getFormTheme());

        return $this->render($this->admin->getTemplate($templateKey), array(
            'action' => 'create',
            'form' => $view,
            'object' => $object,
        ), null);
    }
}

现在我正在尝试的是提交表单时,我需要根据adjust_working_hours()更改一些表单字段值。

问题是:

如果我添加了此代码:

        $key =array_keys($_POST)[0];
        $date_to_floor = $_POST[$key]["date_to_floor"];
        $user_id = $_POST[$key]["assigned"];
        $hours_to_complete = $_POST[$key]["estimate"];
        $final_data = $this->adjust_working_hours($date_to_floor,$user_id,$hours_to_complete);
        $request->request->set('start_datetime', date('n/j/Y H:i',strtotime($final_data['start_date'])));
        $request->request->set('end_datetime', date('n/j/Y H:i',strtotime($final_data['end_date'])));
        $request->request->set('hours_remaining', $final_data['hours_remaining']);

之前:if ($form->isSubmitted()) {

将原始表单值保存到db而不是已更改的表单。

如果我在if ($form->isSubmitted()) { 之后添加相同的代码

然后它说错误:

  

您无法更改已提交表单的数据

那么如何更改这些字段值以便我保存更改的值?

3 个答案:

答案 0 :(得分:2)

在持久保存对象数据之前修改对象数据的最佳方法是覆盖管理类的prePersist()挂钩(此方法完全出于此目的),如下所示:

public function prePersist($object)
{
    $this->changeFields($object);
}

如果您想在编辑对象时执行相同操作,只需覆盖preUdpate

此处有更详细的信息:https://sonata-project.org/bundles/admin/master/doc/reference/saving_hooks.html

无论您在使用Sonata管理员时想做什么,在尝试覆盖控制器之前,都应该尝试通过管理类进行操作。

答案 1 :(得分:1)

我想我理解你的需求和imho,你这样做是错误的。

要在提交之前或之后对提交的表单进行操作,请查看文档中的Symfony Form事件主题:https://symfony.com/doc/2.8/form/events.html。花点时间了解完整的symfony Forms流程,因为一开始并不容易。

然后,您将能够根据几件事情调整您的表格。值。

另外,试着让你的控制器更轻更清晰,因为tbh,它太混乱了。将您的代码分离到服务中的较小函数或控制器上的私有方法中。

答案 2 :(得分:1)

最后,我自己得到了解决方法: -

实际上它是$query = "SELECT * FROM users WHERE username LIKE whateveryouwanthere"; $run = mysqli_query($connectionvariable,$query); $row = mysqli_fetch_array($run); $variable = $row['column name of the item u want to retrieve']; //for example $username = $row['username']; 使用的。所以在上面的代码中这一行: -

Symfony Sonata-Admin-Bundle

保存提交的表单数据,$object = $this->admin->create($object); 是保存表单数据的变量,所以我在它之前添加了自定义代码,现在一切正常了

$object