2013-08-02 148 views
0

我試圖寫一個表單提交對MySQL數據庫,但我不能得到它的工作,我已經嘗試了很多東西(單獨的窗體,創建一個字段->add('foo', new foo()),並試圖解析普通的SQL與普通的HTML表單是我唯一的解決辦法,這顯然不是最好的Symfony2關係實體+表格

這是我的數據庫結構:!

[在這裏輸入的形象描述] [1]

正如你所看到的,我需要在編寫它的用戶中插入comments textarea到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, 

,當然,對於提交的表單,每個表格需要具有相同的ticketidid,因此我們可以通過一個簡單的查詢來檢索它。

使用普通的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; 
     } 
    } 

我可以檢索ARRA y的X票,即使我只搜索一個ID,因爲如果ID1有4個評論,那麼我得到4張相同的票,每個評論一張...我如何才能讓它只有一張票comments => array(...),所以我可以迭代內comments陣列裏面的樹枝?在 /var/www/wbsgo/dev.wbsgo/vendor/doctrine/orm crmid:

而且還VtigerCrmentity.Description也不管用,它返回這個錯誤...

注意:未定義指數/ lib目錄/教義/ ORM /查詢/ SqlWalker。PHP 線826

我沒有getter和setter重新生成,因爲我再他們,如果註釋都OK,該實體將具有get/set正確地更新和我的形式就可以提交使用關係,對嗎?

回答

0

我發現這樣做的方式,以及存在的問題。

的關係是這樣的:

crmentity.id>主,此表有關係

troubleticket.ticketid>這其中有與crmentity.id

ticketcf.ticketid關係>這其中有troubleticket.ticketid

關係

所以你插入的順序需要是crmentity - >troubleticket - >ticketcf

但在Symfony2中,當您的形式,你必須創建最後一個表元素作爲要生成的第一種形式,所以我會後我的代碼,以防有人有同樣的問題我。

http://pastebin.com/wLPyXvbj

:)

1

您可以嵌入,它通過設置mapped選項設置爲false表示潛在的實體領域的形式,例如:

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

然而,分配形式的數據時一定要小心,因爲$form->submit($data)不會將數據基礎集合的評論對象。您需要在控制器內手動處理它們。將數據提交到表單後,您可以訪問使用$form->getExtraData()標記爲非映射的數據。

如果您希望Symfony自動將數據設置爲註釋,您需要構建一個VtigerTroubleticketsVtigerTicketcomments實體之間的關係,根據問題標題,您不需要並嘗試避免這種關係。

編輯:

甲形式類型被綁定到給定實體類。默認情況下,添加到表單類型的每個字段都必須在聲明的實體類中具有基礎屬性(如果屬性未定義爲public,則爲getter/setter pair)。當您從表單類型(OpenTicketType)和數據(new VtigerTroubletickets())構造一個表單對象:

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

形式獲得與存在於剛剛創建的對象的數據範圍。該對象沒有註釋屬性,甚至更多的是,表單本身知道該字段沒有被映射,並且不會嘗試從對象中填充它,所以自然,集合呈現爲空,因爲沒有關於註釋的數據被傳遞。要注意這一點,您可以傳遞數組而不是新創建的對象(注意:值可能爲空,但註釋數組必須長度> 0 - 註釋必須存在,但不包含實際數據)。

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

這是表單創建。當表單被POST時,除了構建表單之外還有一個額外的步驟。請求數據必須綁定到表單上,因此您需要執行$form->submit($request)。現在,表單和基礎實體對象將被填充新的數據。

$form->getExtraData()只是一種用於訪問表單保留的數據的方法,並未映射到基礎對象 - 哪些註釋字段是,因爲我們標記爲這樣。

替代地使用getExtraData - 提取形式手動數據 - 你可能屬性添加到comments實體VtigerTroubletickets與getter/setter方法,它不標記爲分貝柱。這樣,您可以刪除表單類型中的mapped => false選項,表單將自動讀取/填充註釋屬性。 但是,如果持續存在,這些註釋將不會被考慮用於存儲,因此您必須手動處理它們。同樣,取出由數據庫中的對象時,註釋屬性將是空的,所以之前創建一個表單,你必須補充一些意見的對象,如:

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

沒錯,我沒有它,我會盡量避免,因爲數據庫已被其他平臺,所以我不想改變什麼,以避免衝突。你說的(使用'collection')我看不出有什麼渲染,我真正得到它正在使用'工作的唯一途徑的方式 - >添加(「評論」, \t \t \t \t \t新VtigerTicketcommentsType() \t \t \t)'這種方式一切都很好,但我不知道如何按下submit,你提到了'$ form-> getExtraData()',但是在我的情況下這是如何工作的?另外,感謝您的回覆。 –

+0

編輯了一些額外的信息。 – usoban

+0

謝謝,你能解釋一下你在哪裏說'爲了克服這個問題,你可以傳遞數組而不是新創建的對象嗎?我不明白你對'comments數組必須具有長度> 0的評論 - 儘管沒有實際數據,評論必須存在「。' –

1

我覺得@usoban採取你大部分的方式。把這些看作是兩個長的評論,而不是回答。

看來你有一票的實體,並用1註釋實體之間一對多的關係,但你不希望真正建立,因爲「DB被另一個平臺」他們之間的正式關係?這到底是什麼意思呢。你是否與另一個應用程序共享php代碼?你在使用教義2嗎?通過Doctrine 2,您可以在不更改實際數據庫的情況下建立關係。

你真的應該看看添加一個getComments您的機票實體。它會讓你的S2生活變得更容易。

+0

感謝您的評論,我不想更改數據庫,因爲我使用vTiger CRM,然後使用其他應用程序S2與相同的數據庫(所以沒有PHP是共享的,只有數據庫)其實,正如你可以看到,不僅僅是'評論'表,如果我可以與我發佈的關係圖,我會發布這將是偉大的,但我對如何使所有的工作都有點失落,我以前從未使用過S2,所以我在這裏是一個新手...閱讀大量文檔'n的東西... –

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() 

通過這種方法,不需要在票證和評論之間有任何直接關係。

+0

我假設'controller'部分一旦表單已經提交,而不是創建本身? –

+0

我改變了我的整個代碼,試圖在不更新數據庫的情況下使用關係(所以只用了Doctrine),但我認爲有些問題... –