0

我正在尝试编写一个用于针对 MySQL DB 提交的表单,但我无法让它工作,我尝试了很多东西(单独的表单,创建->add('foo', new foo())一个字段,并尝试使用普通的解析普通 SQL HTML 表单是我唯一的解决方案,这显然不是最好的。

这是我的数据库结构:

![在此处输入图像描述][1]

如您所见,我需要将commentstextarea 插入到ticketcomments编写它的用户中,等等。

在球场上crmentitydescription

然后在ticketcf我需要从表单提交的字段上,是这样的(因为你不会知道我是否因为字段名称而没有告诉你):

tcf.cf594 AS Type,
tcf.cf675 AS Suscription,
tcf.cf770 AS ID_PRODUCT,
tcf.cf746 AS NotificationDate,
tcf.cf747 AS ResponseDate,
tcf.cf748 AS ResolutionDate,

而且,当然,每个表都需要具有相同的提交表单的ticketid id ,因此我们可以通过一个简单的查询来检索它。

使用纯 SQL 而不是使用 DQL 和 Symfony2 表单很容易,但这不是一个好方法。

编辑 这是我新创建的实体Ticket.php,它与上面的表格有关系...如果有人可以检查它并告诉我是否可以...

票证.php

<?php 
namespace WbsGo\clientsBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * VtigerTicketcomments
 *
 * @ORM\Table(name="vtiger_troubletickets")
 * @ORM\Entity(repositoryClass="WbsGo\clientsBundle\Entity\TicketsRepository")
 */

class Tickets
{
    /**
     * @var \WbsGo\clientsBundle\Entity\VtigerCrmentity
     *
     * @ORM\OneToOne(targetEntity="WbsGo\clientsBundle\Entity\VtigerCrmentity")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="ticketid", referencedColumnName="crmid", unique=true)
     * })
     * @ORM\Id
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="ticket_no", type="string", length=100, nullable=false)
     *
     */
    private $ticketNo;

    /**
     * @var string
     *
     * @ORM\Column(name="groupname", type="string", length=100, nullable=true)
     */
    private $groupName;

    /**
     * @ORM\ManyToOne(targetEntity="VtigerContactdetails")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="parent_id", referencedColumnName="contactid", unique=true)
     * })
     */
    private $parentId;

    /**
     * @ORM\ManyToOne(targetEntity="VtigerAssets")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="product_id", referencedColumnName="assetsid", unique=true)
     * })
     */
    private $productId;

    /**
     * @var string
     *
     * @ORM\Column(name="priority", type="string", length=100, nullable=true)
     */
    private $priority;

    /**
     * @var string
     *
     * @ORM\Column(name="severity", type="string", length=100, nullable=true)
     */
    private $severity;

    /**
     * @var string
     *
     * @ORM\Column(name="status", type="string", length=100, nullable=true)
     */
    private $status;

    /**
     * @var string
     *
     * @ORM\Column(name="category", type="string", length=100, nullable=true)
     */
    private $category;

    /**
     * @var string
     *
     * @ORM\Column(name="title", type="string", length=255, nullable=true)
     */
    private $title;

    /**
     * @var text
     *
     * @ORM\Column(name="solution", type="text", nullable=true)
     */
    private $solution;

    /**
     * @var text
     *
     * @ORM\Column(name="update_log", type="text", nullable=true)
     */
    private $updateLog;

    /**
     * @var integer
     *
     * @ORM\Column(name="version_id", type="integer", nullable=true)
     */
    private $versionId;

    /**
     * @var string
     *
     * @ORM\Column(name="hours", type="string", length=255, nullable=true)
     */
    private $hours;

    /**
     * @var string
     *
     * @ORM\Column(name="days", type="string", length=255, nullable=true)
     */
    private $days;

    /**
     * @var integer
     *
     * @ORM\Column(name="from_portal", type="integer", nullable=true)
     */
    private $fromPortal;

    /**
     * @ORM\OneToMany(targetEntity="VtigerTicketcomments", mappedBy="ticketid")
     * 
     */
    protected $comments;

    /**
     * @ORM\OneToOne(targetEntity="VtigerTicketcf", mappedBy="id")
     */
    protected $ticketcf;
    /**
     * @ORM\OneToOne(targetEntity="VtigerCrmentity", mappedBy="crmid")
     */
    protected $crmtable;
}

VtigerTicketcf.php

<?php

namespace WbsGo\clientsBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * VtigerTicketcf
 *
 * @ORM\Table(name="vtiger_ticketcf")
 * @ORM\Entity
 */
class VtigerTicketcf
{
    /**
     * @var string
     *
     * @ORM\Column(name="cf_546", type="string", length=255, nullable=true)
     */
    private $cf546;

    /**
     * @var string
     *
     * @ORM\Column(name="cf_556", type="string", length=255, nullable=true)
     */
    private $cf556;

    /**
     * @var string
     *
     * @ORM\Column(name="cf_589", type="string", length=3, nullable=true)
     */
    private $cf589;

    /**
     * @var string
     *
     * @ORM\Column(name="cf_590", type="string", length=3, nullable=true)
     */
    private $cf590;

    /**
     * @var string
     *
     * @ORM\Column(name="cf_592", type="string", length=100, nullable=true)
     */
    private $cf592;

    /**
     * @var string
     *
     * @ORM\Column(name="cf_593", type="string", length=255, nullable=true)
     */
    private $cf593;

    /**
     * @var string
     *
     * @ORM\Column(name="cf_594", type="string", length=255, nullable=true)
     */
    private $cf594;

    /**
     * @var string
     *
     * @ORM\Column(name="cf_675", type="string", length=50, nullable=true)
     */
    private $cf675;

    /**
     * @var float
     *
     * @ORM\Column(name="cf_689", type="decimal", nullable=true)
     */
    private $cf689;

    /**
     * @var float
     *
     * @ORM\Column(name="cf_690", type="decimal", nullable=true)
     */
    private $cf690;

    /**
     * @var float
     *
     * @ORM\Column(name="cf_691", type="decimal", nullable=true)
     */
    private $cf691;

    /**
     * @var float
     *
     * @ORM\Column(name="cf_693", type="decimal", nullable=true)
     */
    private $cf693;

    /**
     * @var string
     *
     * @ORM\Column(name="cf_746", type="string", length=50, nullable=true)
     */
    private $cf746;

    /**
     * @var string
     *
     * @ORM\Column(name="cf_747", type="string", length=50, nullable=true)
     */
    private $cf747;

    /**
     * @var string
     *
     * @ORM\Column(name="cf_748", type="string", length=50, nullable=true)
     */
    private $cf748;

    /**
     * @var string
     *
     * @ORM\Column(name="cf_761", type="string", length=255, nullable=true)
     */
    private $cf761;

    /**
     * @var string
     *
     * @ORM\Column(name="cf_763", type="string", length=255, nullable=true)
     */
    private $cf763;

    /**
     * @var string
     *
     * @ORM\Column(name="cf_764", type="string", length=255, nullable=true)
     */
    private $cf764;

    /**
     * @var string
     *
     * @ORM\Column(name="cf_765", type="string", length=255, nullable=true)
     */
    private $cf765;

    /**
     * @var string
     *
     * @ORM\Column(name="cf_770", type="string", length=50, nullable=true)
     */
    private $cf770;

    /**
     * @var \WbsGo\clientsBundle\Entity\Tickets
     * @ORM\Id
     * @ORM\OneToOne(targetEntity="WbsGo\clientsBundle\Entity\Tickets")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="ticketid", referencedColumnName="ticketid", unique=true)
     * })
     * 
     */
    private $id;
}

VtigerTicketcomments.php

<?php

namespace WbsGo\clientsBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * VtigerTicketcomments
 *
 * @ORM\Table(name="vtiger_ticketcomments")
 * @ORM\Entity
 */
class VtigerTicketcomments
{
    /**
     * @var string
     *
     * @ORM\Column(name="comments", type="text", nullable=true)
     */
    private $comments;

    /**
     * @var integer
     *
     * @ORM\Column(name="ownerid", type="integer", nullable=false)
     */
    private $ownerid;

    /**
     * @var string
     *
     * @ORM\Column(name="ownertype", type="string", length=10, nullable=true)
     */
    private $ownertype;

    /**
     * @var \DateTime
     *
     * @ORM\Column(name="createdtime", type="datetime", nullable=false)
     */
    private $createdtime;

    /**
     * @var integer
     *
     * @ORM\Column(name="commentid", type="integer")
     * @ORM\Id
     */
    private $id;

    /**
     * @var \WbsGo\clientsBundle\Entity\Tickets
     * @ORM\OneToOne(targetEntity="WbsGo\clientsBundle\Entity\Tickets")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="ticketid", referencedColumnName="ticketid", unique=true)
     * })
     * 
     */
    private $ticketid;
}

VtigerCrmentity.php

<?php

namespace WbsGo\clientsBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * VtigerCrmentity
 *
 * @ORM\Table(name="vtiger_crmentity")
 * @ORM\Entity
 */
class VtigerCrmentity
{
    /**
     * @var integer
     *
     * @ORM\Column(name="smcreatorid", type="integer", nullable=false)
     */
    private $smcreatorid;

    /**
     * @var integer
     *
     * @ORM\Column(name="smownerid", type="integer", nullable=false)
     */
    private $smownerid;

    /**
     * @var integer
     *
     * @ORM\Column(name="modifiedby", type="integer", nullable=false)
     */
    private $modifiedby;

    /**
     * @var string
     *
     * @ORM\Column(name="setype", type="string", length=30, nullable=false)
     */
    private $setype;

    /**
     * @var string
     *
     * @ORM\Column(name="description", type="text", nullable=true)
     */
    private $description;

    /**
     * @var \DateTime
     *
     * @ORM\Column(name="createdtime", type="datetime", nullable=false)
     */
    private $createdtime;

    /**
     * @var \DateTime
     *
     * @ORM\Column(name="modifiedtime", type="datetime", nullable=false)
     */
    private $modifiedtime;

    /**
     * @var \DateTime
     *
     * @ORM\Column(name="viewedtime", type="datetime", nullable=true)
     */
    private $viewedtime;

    /**
     * @var string
     *
     * @ORM\Column(name="status", type="string", length=50, nullable=true)
     */
    private $status;

    /**
     * @var integer
     *
     * @ORM\Column(name="version", type="integer", nullable=false)
     */
    private $version;

    /**
     * @var integer
     *
     * @ORM\Column(name="presence", type="integer", nullable=true)
     */
    private $presence;

    /**
     * @var integer
     *
     * @ORM\Column(name="deleted", type="integer", nullable=false)
     */
    private $deleted;

    /**
     * @var integer
     *
     * @ORM\Column(name="crmid", type="integer")
     * @ORM\Id
     */
    private $crmid;

}

这是我的存储库方法...

public function findByIdAndCustomerId($id) {
        $query = $this->getEntityManager()
                ->createQuery(
                        '
                        SELECT 
                        IDENTITY(t.id) AS id,
                        t.ticketNo AS Ticket,
                        t.title AS Asunto,
                        t.status AS Estado,
                        t.updateLog AS LOG,
                        t.hours AS Horas,
                        t.solution AS Solucion,
                        t.priority AS Prioridad,
                        tcf.cf748 AS F_Reso,
                        tcf.cf747 AS F_Resp,
                        tcf.cf746 AS F_Noti,
                        tcf.cf770 AS IDPROD,
                        tcf.cf594 AS Tipo,
                        tcf.cf675 AS Suscripcion,
                        c.comments AS Comments,
                        CONCAT (CONCAT(s.firstname, \' \'), s.lastname) AS Contacto
                        FROM WbsGoclientsBundle:Tickets t
                        JOIN t.parentId s
                        JOIN t.ticketcf tcf
                        JOIN t.comments c
                        WHERE  t.ticketNo = :ticketNo

        ')
        ->setParameter('ticketNo', $id)
        ;

        try {
            //return $query->getSingleResult();
            return $query->getResult();
        }
        catch (\Doctrine\ORM\NoResultException $e)
        {
            return null;
        }
    }

即使我只按一个 ID 搜索,我也可以检索一组 X 票,因为如果 ID1 有 4 条评论,那么我得到 4 张相同的票,每个评论一张……我怎样才能让它只有一张票,comments => array(...)这样我就可以在里面迭代树枝里面的那个comments数组?

而且也VtigerCrmentity.Description不起作用,它返回此错误...

注意:未定义索引:/var/www/wbsgo/dev.wbsgo/vendor/doctrine/orm/lib/Doctrine/ORM/Query/SqlWalker.php 第 826 行中的 crmid

我没有 getter 和 setter,因为我正在重新生成它们,如果注释正常,实体将使用 get/set 正确更新,并且我的表单将能够使用关系提交,对吗?

4

4 回答 4

1

mapped您可以通过将选项设置为 false来嵌入代表基础实体字段的表单,例如:

->add('comments', 'collection', array(
    'type'   => new VtigerTicketcommentsType(),
    'mapped' => false
))

但是,在分配表单数据时要小心,因为$form->submit($data)不会将数据设置到评论对象的底层集合。您需要在控制器内手动处理它们。$form->getExtraData()在将数据提交到表单后,您可以访问已标记为未映射的数据。

如果您希望 Symfony 自动将数据设置为评论,您需要在VtigerTroubleticketsVtigerTicketcomments实体之间构建关系,根据问题标题,您没有并尽量避免这种关系。

编辑:

表单类型绑定到给定的实体类。默认情况下,您添加到表单类型的每个字段都必须在已声明的实体类中具有基础属性(如果属性未定义为 public,则为 getter/setter 对)。OpenTicketType当您从表单类型 ( ) 和数据 ( )构造表单对象时new VtigerTroubletickets()

$form = $this->createForm(new OpenTicketType(), new VtigerTroubletickets());

表单与您刚刚创建的对象中存在的数据绑定。该对象没有 comments 属性,更重要的是,表单本身知道该字段未映射,并且不会尝试从对象中填充它,因此该集合自然呈现为空,因为没有传递有关评论的数据。

为了解决这个问题,您可以传递数据数组而不是新创建的对象(注意:值可能为空,但评论数组的长度必须 > 0 - 评论必须存在,但没有实际数据)。

[
  "title"    => "...",
  "priority" => "...",
  "solution" => "...",
  "comments" => [
    0 => [/* comment 0 data */],
    1 => [/* comment 1 data */],
    .......
  ]
]

这就是表单的创建。当表单是 POST-ed 时,除了构建表单之外还有一个额外的步骤。请求数据必须绑定到表单上,所以你可以这样做$form->submit($request)。现在表单和底层实体对象将填充新数据。

$form->getExtraData()只是一种访问表单保存的数据的方法,并且没有映射到底层对象 - 注释字段是,因为我们将其标记为这样。

或者使用getExtraData- 手动从表单中提取数据 - 您可以使用 getter/settercommentsVtigerTroubletickets实体添加属性,而不是将其标记为 db 列。这样,您可以删除mapped => false表单类型的选项,表单将自动读取/填充评论属性。尽管如此,在持久化时,这些注释不会被考虑存储,因此您必须手动处理它们。同样,从数据库中获取对象时,comments 属性将为空,因此在创建表单之前,您必须向对象添加一些注释,例如:

$tickets = new VtigerTroubletickets();
$tickets->setComments(....);
$form = $this->createForm(new OpenTicketType(), $tickets);
于 2013-08-02T10:54:33.310 回答
1

我认为@usoban 已经带你走了大部分路。将这些视为与答案相反的两条长评论。

似乎您有一个票据实体和一个评论实体,它们之间存在一对多关系,但您不想在它们之间实际建立正式关系,因为“数据库被另一个平台使用”?这到底是什么意思呢。您是否与另一个应用程序共享 php 代码?你在使用教义2吗?使用 Doctrine 2,您可以在不更改实际数据库的情况下建立关系。

您真的应该考虑将 getComments 添加到您的票证实体。这将使您的 S2 生活更加轻松。

于 2013-08-02T15:33:14.457 回答
1

这个答案建立在@usoban 所说的关于使用数组的基础上,但采用的方法略有不同。

// In the controller
$formData = array();
$formData['ticket'] = new Ticket(),
$formData['comments'] = array(new Comment(), new Comment());

$form = $this->createForm(new TicketCommentsType(), $formData);
$form->handleRequest($request);

if ($form->isValid()) 
{ 
    $formData = $form->getData();
    $ticket   = $formData['ticket'];
    $comments = $formData['comments'];

    // Persist ticket

    // Persist comments

TicketCommentsFormType 只是将两个不同的实体合并到一个表单中。

class TicketCommentsFormType

public function buildForm(

    $builder->add('ticket',new OpenTicketType());
    $builder->add('comments','collection',array(
            'type' => new VtigerTicketcommentsType()

使用这种方法,Ticket 和 Comment 之间不需要有任何直接关系。

于 2013-08-02T15:45:45.760 回答
0

我找到了方法和问题。

关系是这样的:

crmentity.id> 主要,此表没有关系

troubleticket.ticketid> 这个有关系crmentity.id

ticketcf.ticketid> 这个有关系troubleticket.ticketid

所以插入时的顺序需要是crmentity-> troubleticket->ticketcf

但是在 Symfony2 中,当你制作表单时,你必须创建最后一个表格元素作为要生成的第一个表单,所以我会发布我的代码以防有人和我有同样的问题。

http://pastebin.com/wLPyXvbj

:)

于 2013-08-08T12:12:29.840 回答