簡體   English   中英

Symfony2關系實體+形式

[英]Symfony2 Relationship entities + forms

我正在嘗試編寫一種針對MySQL DB提交的表單,但我無法使其正常工作,我嘗試了很多事情(單獨的表單,創建->add('foo', new foo())字段,嘗試用普通的HTML格式解析純SQL是我唯一的解決方案,這顯然不是最好的方法。

這是我的數據庫結構:

![在此處輸入圖片描述] [1]

如您所見,我需要在編寫comments的用戶之間將comments文本區域插入到ticketcomments comments

crmentity description字段。

然后在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 ,與上面的表有關系...如果有人可以檢查出來並告訴我是否可以...

ticket.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正確更新,並且我的表單將能夠使用關系提交,對嗎?

您可以通過將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 */],
    .......
  ]
]

這是表單創建。 將表單過帳后,除了構建表單外,還有一個額外的步驟。 請求數據必須綁定到表單上,因此您可以執行$form->submit($request) 現在,表單AND基礎實體對象將填充有新數據。

$form->getExtraData()只是一種訪問表單保存的數據的方法,該數據沒有映射到基礎對象-注釋字段是,因為我們將其標記為此類。

作為使用getExtraData替代方法-手動從表單提取數據,您可以使用getters / setters向VtigerTroubletickets實體添加屬性comments ,而不將其標記為db列。 這樣,您可以在表單類型中刪除mapped => false選項,並且表單將自動讀取/填充注釋屬性。 盡管如此,在保留時,這些注釋將不被考慮存儲,因此您必須手動處理它們。 同樣,從數據庫中獲取對象時,comment屬性將為空,因此在創建表單之前,您必須向對象添加一些注釋,例如:

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

我認為@usoban帶走了您的大部分時間。 可以將它們視為兩條長長的評論,而不是答案。

看來您有一個票證實體和一個注釋實體,它們之間具有一對多的關系,但是您不希望在它們之間建立正式的關系,因為“ DB被另一個平台使用了”? 這到底是什么意思呢。 您是否正在與其他應用程序共享php代碼? 您是否在使用教義2? 使用Doctrine 2,您可以在不更改實際數據庫的情況下建立關系。

您確實應該考慮將getComments添加到票證實體。 這將使您的S2生活更加輕松。

這個答案建立在@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()

使用這種方法,票證和評論之間沒有任何直接關系。

我已經找到了解決方法以及存在的問題。

關系是這樣的:

crmentity.id > Main,該表沒有關系

troubleticket.ticketid >這與crmentity.id

ticketcf.ticketid >這一個有關系troubleticket.ticketid

所以為了當你插入必須crmentity - > troubleticket - > ticketcf

但是在Symfony2中,制作表格時,必須創建最后一個表格元素作為要生成的第一個表格,因此,如果有人遇到與我相同的問題,我將張貼代碼。

http://pastebin.com/wLPyXvbj

:)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM