我可以在 Sonata Admin 控制器中使用 prePersist/preUpdate 来保存多个对象吗?

2024-01-03

我有这个Alias entity:

use Gedmo\Timestampable\Traits\TimestampableEntity;

class Alias
{
    use IdentifierAutogeneratedTrait;
    use TimestampableEntity;
    use ActiveTrait;

    /**
     * @var string
     * @ORM\Column(type="string", length=150)
     */
    private $name;

    /**
     * Command associated to the alias.
     *
     * @var Command[]
     * @ORM\ManyToMany(targetEntity="Command", mappedBy="aliases", cascade={"persist"})
     */
    private $commands;

    ...
}

我有这个管理控制器:

class AliasAdmin extends Admin
{
    protected function configureFormFields(FormMapper $formMapper)
    {
        $formMapper
            ->add('name', null, array('required' => true))
            ->add('active', null, array('required' => false));
    }

    ...

    public function prePersist($alias)
    {
        // remove extra white spaces
        $noWhiteSpaces = str_replace(' ', '', $alias->getName());
        // split into several names
        $aliasArr = explode(',', $noWhiteSpaces);
    }

    public function preUpdate($alias)
    {
        ...
    }
}

当我添加新的Alias在视图上 - 意思是表单本身 - 我可以在上面写一个值name输入字段例如:value1或者我可以写多个值,以逗号分隔:value1, value2, value3, value4。如果我只有一个值name当我提交表单时,字段不会有问题,但如果我有多个逗号分隔作为第二个示例,那么我应该检查它们prePersist/preUpdate方法以拆分它们并创建一个Alias per name,我该怎么做?如果你看一下prePersist方法你会看到我正在谈论的内容,更清楚地了解如何在新的名称中为每个名称创建新的别名$aliasArr,有什么帮助吗?

Update:TimestampableEntity 没有被处理,为什么?

在尝试了 @m-khalid-junaid 的解决方案后,由于以下原因,我以以下错误结束NOT NULL约束,但我不知道为什么。看一下代码:

class AliasAdminController extends Controller
{
    /**
     * {@inheritdoc}
     */
    public function createAction(Request $request = null)
    {
        // the key used to lookup the template
        $templateKey = 'edit';

        if (false === $this->admin->isGranted('CREATE')) {
            throw new AccessDeniedException();
        }

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

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

        if ($this->getRestMethod() == 'POST') {
            $form->submit($this->get('request'));
            $isFormValid = $form->isValid();

            // persist if the form was valid and if in preview mode the preview was approved
            if ($isFormValid && (!$this->isInPreviewMode() || $this->isPreviewApproved())) {
                if (false === $this->admin->isGranted('CREATE', $object)) {
                    throw new AccessDeniedException();
                }

                try {
                    $aliasArr = $this->toStrings($object->getName());

                    if (count($aliasArr) > 1) {
                        $object->setName($aliasArr[0]);
                        $object = $this->admin->create($object);
                        unset($aliasArr[0]);
                        $entityManager = $this->getDoctrine()->getManager();

                        foreach ($aliasArr as $alias) {
                            $newAlias = new Alias();
                            $newAlias->setName($alias);
                            $entityManager->persist($newAlias);
                        }

                        $entityManager->flush();
                    } else {
                        $object = $this->admin->create($object);
                    }

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

                    $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->logModelManagerException($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,
        ));
    }

    /**
     * {@inheritdoc}
     */
    public function editAction($id = null)
    {
        // the key used to lookup the template
        $templateKey = 'edit';

        $id = $this->get('request')->get($this->admin->getIdParameter());
        $object = $this->admin->getObject($id);

        if (!$object) {
            throw new NotFoundHttpException(sprintf('unable to find the object with id : %s', $id));
        }

        if (false === $this->admin->isGranted('EDIT', $object)) {
            throw new AccessDeniedException();
        }

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

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

        if ($this->getRestMethod() == 'POST') {
            $form->submit($this->get('request'));

            $isFormValid = $form->isValid();

            // persist if the form was valid and if in preview mode the preview was approved
            if ($isFormValid && (!$this->isInPreviewMode() || $this->isPreviewApproved())) {
                try {
                    $aliasArr = $this->toStrings($object->getName());

                    if (count($aliasArr) > 1) {
                        $object->setName($aliasArr[0]);
                        $object = $this->admin->update($object);
                        unset($aliasArr[0]);
                        $entityManager = $this->getDoctrine()->getManager();

                        foreach ($aliasArr as $alias) {
                            $newAlias = new Alias();
                            $newAlias->setName($alias);
                            $entityManager->persist($newAlias);
                        }

                        $entityManager->flush();
                    } else {
                        $object = $this->admin->update($object);
                    }

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

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

                    // redirect to edit mode
                    return $this->redirectTo($object);
                } catch (ModelManagerException $e) {
                    $this->logModelManagerException($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_edit_error',
                            array('%name%' => $this->escapeHtml($this->admin->toString($object))),
                            'SonataAdminBundle'
                        )
                    );
                }
            } elseif ($this->isPreviewRequested()) {
                // enable 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' => 'edit',
            'form' => $view,
            'object' => $object,
        ));
    }

    private function logModelManagerException($e)
    {
        $context = array('exception' => $e);
        if ($e->getPrevious()) {
            $context['previous_exception_message'] = $e->getPrevious()->getMessage();
        }
        $this->getLogger()->error($e->getMessage(), $context);
    }

    private function toStrings($string)
    {
        $noWhiteSpaces = str_replace(' ', '', $string);
        return explode(',', $noWhiteSpaces);
    }
}

这是错误:

[2016-02-28 11:10:36] doctrine.DEBUG: "START TRANSACTION" [] []
[2016-02-28 11:10:36] doctrine.DEBUG: INSERT INTO cm_alias (name, created_at, updated_at, active) VALUES (?, ?, ?, ?) {"1":"alias1","2":null,"3":null,"4":true} []
[2016-02-28 11:10:36] doctrine.DEBUG: "ROLLBACK" [] []
[2016-02-28 11:10:36] app.ERROR: Failed to create object: PlatformAdminBundle\Entity\Alias {"exception":"[object] (Sonata\\AdminBundle\\Exception\\ModelManagerException(code: 0): Failed to create object: PlatformAdminBundle\\Entity\\Alias at /var/www/html/platform.sonata/vendor/sonata-project/doctrine-orm-admin-bundle/Model/ModelManager.php:142, Doctrine\\DBAL\\Exception\\NotNullConstraintViolationException(code: 0): An exception occurred while executing 'INSERT INTO cm_alias (name, created_at, updated_at, active) VALUES (?, ?, ?, ?)' with params [\"alias1\", null, null, 1]:\n\nSQLSTATE[23000]: Integrity constraint violation: 1048 Column 'created_at' cannot be null at /var/www/html/platform.sonata/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/AbstractMySQLDriver.php:112, Doctrine\\DBAL\\Driver\\PDOException(code: 23000): SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'created_at' cannot be null at /var/www/html/platform.sonata/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOStatement.php:93, PDOException(code: 23000): SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'created_at' cannot be null at /var/www/html/platform.sonata/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOStatement.php:91)","previous_exception_message":"An exception occurred while executing 'INSERT INTO cm_alias (name, created_at, updated_at, active) VALUES (?, ?, ?, ?)' with params [\"alias1\", null, null, 1]:\n\nSQLSTATE[23000]: Integrity constraint violation: 1048 Column 'created_at' cannot be null"} []

Why TimestampableEntity新的管理控制器未处理特征?我在这里缺少什么?


如果您想添加具有不同别名的同一对象,最好创建一个CRUDController您的管理类的控制器,一旦您拥有 CRUDController,您就可以覆盖createAction & editAction基类并在此处实现您当前对象的逻辑 prePresist/preUpdate 事件,以便使用控制器为具有不同信息的对象创建副本。我在下面只提到了必要的代码,您可以从奏鸣曲的 CRUDController 复制并在中实现相同的逻辑editAction

public function createAction(Request $request = null)
{
    // .. some code here copy from base class
    try {
        $noWhiteSpaces = str_replace(' ', '', $object->getName());
        // split into several names
        $aliases = explode(',', $noWhiteSpaces);
        if (count($aliases) > 1) {
            $object->setName($aliases[0]);
            $object = $this->admin->create($object);
            unset($aliases[0]);
            $DM = $this->getDoctrine()->getManager();
            foreach ($aliases as $alias) {
                $newAlias = new Alias();
                $newAlias->setName($alias);
                $DM->persist($newAlias);
            }
            $DM->flush();
        } else {
            $object = $this->admin->create($object);
        }
    } catch (ModelManagerException $e) {
        $this->handleModelManagerException($e);

        $isFormValid = false;
    }
    // .. some code here copy from base class
}

编辑为created_at不为空错误

您需要在别名实体中定义一个构造函数,然后初始化您的createdAt财产与DateTime object

/**
 * Constructor
 */
public function __construct()
{
    $this->createdAt = new \DateTime('now');
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

我可以在 Sonata Admin 控制器中使用 prePersist/preUpdate 来保存多个对象吗? 的相关文章

  • 如何配置 nginx 重写规则以使 CakePHP 在 CentOS 上运行?

    大家好 请帮帮我 我正在尝试在运行 Nginx 和 Fact CGI 的 Centos 服务器上设置 cakephp 环境 我已经在服务器上运行了一个 WordPress 站点和一个 phpmyadmin 站点 因此我已经正确配置了 PHP
  • 从 freshdesk api 获取所有用户时获取curl_error(): 2 不是有效的 cURL 句柄资源

    我正在创建自己的系统来管理通过其 API 来自 freshdesk com 的所有票证 我正在发出curl 请求以从freshdesk com 获取数据 通过获取与股票相关的数据 它的工作正常 但是当我通过curl请求请求所有用户时 它会给
  • 没有生成缩略图

    我在我的项目中使用 Sonata Media Bundle 和 Symfony2 3 当我覆盖 YouTube 提供商时奏鸣曲 media provider youtube 一切工作正常 没有错误或任何其他内容 但在 Web uploads
  • PHP 读取使用 setcookie() 创建的 cookie

    来自manual https www php net setcookie 直到下一次加载 Cookie 应该可见的页面之前 Cookie 才会变得可见 这意味着创建的 cookiesetcookie将无法访问 COOKIE直到下一页加载 有
  • PHP 删除字符最后一个实例之前的所有内容

    有没有办法删除某个字符之前的所有内容 包括最后一个实例 我有多个字符串 其中包含 gt e g the gt cat gt sat gt on gt the gt mat welcome gt home 我需要对字符串进行格式化 以便它们变
  • Laravel 5.4 将json保存到数据库

    帮我将 json 保存到数据库 表字段类型 文本 我有带有强制转换数组的模型 class Salesteam extends Model protected casts team members gt array 我想要像这样 index
  • 使用 PHP 更新 XML 节点

    我有一个 XML 文件 test xml
  • 在php中获取大于2GB的文件大小的最佳方法?

    我想检查本地驱动器上的文件大小windows OS 但是PHP原生函数filesize 仅当文件大小小于时才有效2GB 大于的文件2GB将返回错误的数字 那么 是否有其他方法来获取大于的文件大小2GB 非常感谢 您始终可以使用系统的文件大小
  • 查明具有特定 ID 的会话是否已过期

    我正在创建一个上传功能 将用户上传的文件存储在服务器上 并以用户的会话 ID 作为名称 现在 我只想将此文件保留在服务器上 直到该会话处于活动状态 所以 我的问题是 如何根据会话 ID 确定会话是活动的还是过期的 以便在后一种情况下我可以安
  • Laravel 读写连接不同步

    我在 Laravel 5 2 应用程序中使用读写 MySQL 连接设置 mysql gt write gt host gt env DB HOST WRITE localhost read gt host gt env DB HOST RE
  • PHP 中的静态类初始值设定项

    我有一个带有一些静态函数的辅助类 类中的所有函数都需要一个 重 初始化函数来运行一次 就好像它是一个构造函数 有实现这一目标的良好实践吗 我唯一想到的就是打电话init函数 如果它已经运行过一次 使用静态 initialized变种 问题是
  • 写入 xml 文件时允许的内存大小已耗尽(尝试分配 4459414 字节)[重复] 67108864 字节

    这个问题在这里已经有答案了 可能的重复 php 中允许的内存大小已耗尽 尝试分配 43148176 字节 33554432 字节 https stackoverflow com questions 415801 allowed memory
  • localhost/live - 通过 HTTP_HOST 检测

    假设我在本地开发并在实时服务器上调试小东西 在我的代码中添加这样的内容是个好主意吗 is local strpos SERVER HTTP HOST localhost false define DEBUG is local 然后在设置内容
  • 优雅地退出 Laravel 作用域

    我有一个范围 它根据用户角色以限制方式起作用 您可以将一组规则转发到限制数据库最终输出的范围 一个非常简化的角色限制示例 first name foo 只会返回其记录first name开始于foo 这实际上意味着我已禁止具有该角色的用户查
  • 将 Cloudinary 与 spatie/media-library Laravel 包一起使用

    有人使用 Laravel 包 spatie media library 和 Cloudinary 吗 我认为用 Flysystem 来实现它是微不足道的 我实际上使用 Cloudinary 作为带有 silvanite nova field
  • Gearman,php 扩展问题:使用终端在 .. 中找不到类“GearmanWorker”,但可以在浏览器上使用

    我最近在 ubuntu 10 04 上安装了 gearman 并安装了它的 pecl 扩展 现在 当我在浏览器中运行一个 php 文件时 其中包含 client new GearmanWorker die var Dump client I
  • Yii 未检测到骆驼案例操作

    伊伊正在给我404 Error如果我声明这样的操作 站点控制器 php public function actionRegisterUser 这就是我在main php label gt Register User url gt site
  • PHP-如何根据条件配对数组中的项目

    如何将数组中的项目配对 假设我有一个数组Fighters 我想根据他们的情况将他们配对Weights 体重最接近的拳手应作为配对最佳匹配 但如果他们是在同一个团队中 他们不应该配对 团队 1 战斗机A体重为60 战斗机B体重为65 2队 战
  • WordPress - 类别和子类别的嵌套列表

    我正在尝试显示带有嵌套子类别的 WordPress 类别列表 到目前为止 我只能获取父类别列表或不包括父类别的子类别列表 但我无法将两者连接在一起 这是我想要创建的结果 Parent Category 子类别 子类别 Parent Cate
  • Mysql加密/存储敏感数据,

    我的 PHP 网站有以下内容 启用 SSL 饼干 session set cookie params cookieParams lifetime cookieParams path cookieParams domain secure ht

随机推荐