2015-09-17 2 views
9

मेरे पास एक निजी संदेश बंडल/इकाई है जो मेरे उपयोगकर्ताओं को उनके बीच संदेश भेजने की अनुमति देती है।प्रत्येक प्राप्त संदेश के लिए एक उत्तर फ़ॉर्म टेक्स्टफील्ड जोड़ें

/** 
* @var integer 
* 
* @ORM\Column(name="id", type="integer") 
* @ORM\Id 
* @ORM\GeneratedValue(strategy="AUTO") 
*/ 
protected $id; 

/** 
* @var string 
* @Assert\NotBlank(message="private_message.title.blank") 
* @ORM\Column(name="title", type="string", length=50) 
*/ 
protected $title; 

/** 
* @Assert\NotBlank(message="private_message.receiver.blank") 
* @AcmeAssert\IsHimself(message="private_message.receiver.himself", groups={"new"}) 
* @ORM\ManyToOne(targetEntity="MedAppBundle\Entity\User") 
* @ORM\JoinColumn(referencedColumnName="id") 
*/ 
protected $receiver; 
/** 
* @ORM\ManyToOne(targetEntity="MedAppBundle\Entity\User") 
* @ORM\JoinColumn(referencedColumnName="id") 
*/ 
protected $sender; 

/** 
* @var string 
* @Assert\NotBlank(message="private_message.content.blank") 
* @ORM\Column(name="content", type="string") 
*/ 
protected $content; 

/** 
* @var \DateTime 
* 
* @ORM\Column(name="sentAt", type="datetime") 
*/ 
protected $sentAt; 


/** 
* @var boolean 
* 
* @ORM\Column(name="isSpam", type="boolean") 
*/ 
protected $isSpam = false; 


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

/** 
* @ORM\ManyToOne(targetEntity="PrivateMessageBundle\Entity\Message",inversedBy="replies") 
* @ORM\JoinColumn(referencedColumnName="id",nullable=true) 
*/ 
protected $replyof; 

/** 
* @ORM\OneToMany(targetEntity="PrivateMessageBundle\Entity\Message", mappedBy="replyof") 
**/ 
private $replies; 

public function __construct() { 
    $this->replies = new ArrayCollection(); 
} 

सूचना replyof क्षेत्र, यह एक message को संदर्भित करता है, और messages की एक सरणी के लिए replies एक संदर्भ:

इसका क्षेत्रों इस प्रकार हैं। यदि replyof शून्य है, तो संदेश किसी संदेश का उत्तर नहीं है।

मेरे पास एक मैक्रो के साथ एक ट्विग टेम्पलेट है जो उपयोगकर्ता के संदेश और उस संदेश के सभी उत्तरों को प्रदर्शित करता है। मैं क्या करना चाहता हूं, इनमें से प्रत्येक के तहत एक उत्तर टेक्स्टफील्ड है, ठीक उसी तरह जीमेल की तरह, जो मुझे प्रत्येक संदेश का जवाब जोड़ने की अनुमति देता है।

लेकिन जब मैं इसे टेम्पलेट में जोड़ता हूं, केवल एक ही प्रदान किया जाता है क्योंकि इसमें एक एकल आईडी है। प्रत्येक उत्तर के बाद मैं एक उत्तर फ़ॉर्म कैसे जोड़ सकता हूं? उनके फॉर्म टाइप किस तरह दिखना चाहिए?

{% macro displayReply(reply,replyform) %} 
     {% import _self as macros %} 


     {# <li> id: {{ reply.id }} </li> 
     <li> sent by: {{ reply.sender }} </li> 
     <li> title: {{ reply.title }} </li> 
     <li> content: {{ reply.content }} </li> 
     <li> date: {{ reply.sentAt|date('d-m-Y H:i:s') }} </li> 
     <a href="{{ path('private_message_new',{'msg':reply.id}) }}"> reply </a> 
     <hr> #} 
     <div class="panel panel-default"> 
      <div class="panel-body"> 
       <div class="message-info"> 
        <input type="hidden" name="messageid" id="messageId" value="{{ reply.id }}"> 

        <div class="message-title clearfix"> 
         <h4 class="pull-left">{{ reply.title }}</h4> 
        </div> 
        <hr class="lite-line"> 
        <div class="message-sender clearfix"> 
         <div class="pull-left sender"> 
          {{ reply.sender }} 
         </div> 
         <div class="pull-right"> 
          to <b>{{ (reply.receiver==app.user)?'me':reply.receiver }}</b> on <span 
            class="message-timestamp">{{ reply.sentAt|date('F d, Y H:i:s') }}</span> 
          <a class="btn btn-start-order" role="button" 
           href="{{ path('private_message_new',{'msg':reply.id}) }}">Reply</a> 
         </div> 

        </div> 
        <hr class="lite-line"> 
        <div class="message-box clearfix"> 
         <span>{{ reply.content | replace({"<script>" : "", "</script>" : ""}) | raw }}</span> 
        </div> 

        {{ form_start(replyform) }} 
        <input type="submit"> 
        {{ form_end(replyform) }} 

       </div> 
      </div> 
     </div> 
     {% for reply in reply.replies %} 

      {% if loop.first %}<div>{% endif %} 
      {{ macros.displayReply(reply) }} 
      {% if loop.last %}</div>{% endif %} 

     {% endfor %} 
    {% endmacro %} 

    {% import _self as macros %} 
    {# use the macro #} 

    <div class="message-back"> 
     <a class="btn btn-start-order-dark btn-block" role="button" 
      href="{{ path('private_message',{'page':'inbox'}) }}"> 
      <span class="fa fa-undo"></span> Go back 
     </a> 
    </div> 

    <div class="messages"> 
     <div class="panel panel-default"> 
      <div class="panel-body"> 
       <div class="message-info"> 
        <input type="hidden" name="messageid" id="messageId" value="{{ message.id }}"> 

        <div class="message-title clearfix"> 
         <h4 class="pull-left">{{ message.title }}</h4> 
        </div> 
        <hr class="lite-line"> 
        <div class="message-sender clearfix"> 
         <div class="pull-left sender"> 
          {{ message.sender }} 
         </div> 
         <div class="pull-right"> 
          to <b>{{ (message.receiver==app.user)?'me':message.receiver }}</b> on <span 
            class="message-timestamp">{{ message.sentAt|date('F d, Y H:i:s') }}</span> <a 
            class="btn btn-start-order" role="button" 
            href="{{ path('private_message_new',{'msg':message.id}) }}">Reply</a> 
         </div> 
        </div> 
        <hr class="lite-line"> 
        <div class="message-box clearfix"> 
         <span>{{ message.content | replace({"<script>" : "", "</script>" : ""}) | raw }}</span> 
        </div> 

        {{ form_start(replyform) }} 
        <input type="submit"> 
        {{ form_end(replyform) }} 
       </div> 
      </div> 
     </div> 
    </div> 
    {% for reply in message.replies %} 

     {% if loop.first %}<div class="replies">{% endif %} 
     {{ macros.displayReply(reply ,replyform) }} 
     {% if loop.last %}</div>{% endif %} 
    {% endfor %} 

सूचना है कि मैं पहली बार संदेश प्रदर्शित है, तो यह करने के लिए मैक्रो लागू एक पेड़ के रूप अपने सभी उत्तरों को प्रदर्शित करता है कि:

यहाँ भी मेरी टहनी टेम्पलेट है। यह जवाब के उत्तरों को भी एक पुनरावर्ती तरीके से प्रदर्शित करेगा, पत्ते नोड्स तक सभी तरह से। मैं प्रत्येक के बाद 'उत्तरफॉर्म' जोड़ता हूं, लेकिन मुझे यकीन नहीं है कि फॉर्मटाइप कैसे होना चाहिए।

मेरा उत्तर फॉर्म प्रकार इस तरह है, लेकिन मुझे यकीन है कि यह गलत है।

public function buildForm(FormBuilderInterface $builder, array $options) 
{ 
    $builder 
     ->add('title') 
     ->add('content', 'textarea') 
     ; 

} 

उत्तर के अन्य क्षेत्रों के लिए, मैं उन्हें नियंत्रक में ख्याल रखता हूं। मुझे लगता है कि मुझे फॉर्म से संदेश प्राप्त करने के बाद ऐसा करना चाहिए। ऐसा कुछ, और फॉर्मडाटा से शीर्षक, सामग्री और उत्तर प्राप्त करें।

$messages = $this->getDoctrine()->getRepository('PrivateMessageBundle:Message'); 
    $isforme = $messages->findOneBy(array('receiver' => $this->getUser(), 'id' => $msg)); 
    $message = new Message(); 
    $message->setSender($this->getUser()); 
    $message->setSentAt(new \Datetime('now')); 
    $message->setReplyof($isforme); 
    $message->setReceiver($isforme->getSender()); 
    $form = $this->createForm(new MessageReplyType($em), $message); 

संपादित

ठीक है, तो मैं कुछ है कि, काम करता है एक छिपी हुई फ़ील्ड जोड़ने और बजाय FormTypes का उपयोग कर के कई रूपों में हार्डकोड द्वारा बनाई गई हैं, लेकिन मैं अब भी लगता है कि यह एक बेहतर किया जा सकता है, अधिक पुन: प्रयोज्य तरीका।

    <form name="privatemessagebundle_message" method="post" action="" id="{{ reply.id }}"> 
         <div><label for="privatemessagebundle_message_title" class="required">Title</label><input 
            type="text" id="privatemessagebundle_message_title" 
            name="privatemessagebundle_message[title]" required="required" maxlength="50"></div> 
         <div><label for="privatemessagebundle_message_content" class="required">Content</label><textarea 
            id="privatemessagebundle_message_content" 
            name="privatemessagebundle_message[content]" required="required"></textarea></div> 
         <input type="hidden" id="privatemessagebundle_message_replyof" 
           name="privatemessagebundle_message[replyof]" value="{{ reply.id }}"> 
         <input type="submit"> 
         <input type="hidden" id="privatemessagebundle_message__token" 
           name="privatemessagebundle_message[_token]" 
           value="{{ csrf_token('privatemessagebundle_message') }}"> 
        </form> 

किसी को भी कोई बेहतर विचार मिला है?

+0

ऐसा लगता है कि टेक्स्टरेरा जावास्क्रिप्ट का उपयोग करके प्रारंभ किया जा सकता है, इसलिए आपको केवल एक ही फॉर्म की आवश्यकता है। उस फ़ॉर्म में एक छिपे हुए क्षेत्र के रूप में 'answerTo' आईडी हो सकती है। इस तरह आपको केवल एक टेक्स्टरेरा की आवश्यकता है? – Rvanlaak

+0

उत्तर के रूप में थोड़ी अधिक जेएस की आवश्यकता होगी जब भी आप उत्तर बटन पर क्लिक करते हैं तो मूल्य को बदलना होगा। यह सीएसआरएफ के लिए थोड़ा और भी कमजोर है। मुझे लगता है कि मेरा समाधान, जटिल होने पर, थोड़ा और सुरुचिपूर्ण है, लेकिन आपका भी बहुत अच्छा है। –

उत्तर

6

मैंने यह किया! मैंने इस question से जवाब का उपयोग किया।

चूंकि मैं फ़ोरैच लूप का उपयोग कर रहा हूं और वे प्रदर्शन पर थोड़ा कम हो सकते हैं, बेहतर विचार वाले किसी भी व्यक्ति का स्वागत है। प्राप्त करने के लिए अभी भी बक्षीस है।

मैं createNamedBuilder के माध्यम से अपने प्रत्येक रूप के लिए एक फॉर्म बना रहा हूं। उनके पास अलग-अलग नाम होंगे, इस प्रकार अलग-अलग आईडी और सिम्फनी उन्हें सभी प्रस्तुत करेंगे। फिर, मैं उन्हें प्रस्तुत कर सकता हूं जहां मैं चाहता हूं और डेटाबेस से ली गई अपनी अनूठी आईडी के माध्यम से उनके अनुरोध को ठीक से संभाल सकता हूं।

$genforms = $this->genReplyForms($isforme); // run the function for my message 
      $forms_views = $genforms['views']; // pass to the view 
      $forms= $genforms['forms']; // handle request... 

यह वह कार्य है जो फ़ॉर्म उत्पन्न करता है। यह मेरे संदेश के प्रत्येक उत्तर के लिए उन्हें पुन: उत्पन्न करता है।

public function genReplyForms(Message $message) 
{ 

    $id = $message->getId(); 

    $msgreply[$id] = new Message(); 

    $forms[$id] = $this->container 
     ->get('form.factory') 
     ->createNamedBuilder('form_'.$id, new MessageReplyType(), $msgreply[$id]) 
     ->getForm(); 

    $forms_views[$id] = $forms[$id]->createView(); 


    $result = array(array(), array()); 

    $result['forms'][$id] = $forms[$id]; 
    $result['views'][$id] = $forms_views[$id]; 


    if (sizeof($message->getReplies())) { 

     foreach ($message->getReplies() as $reply) { 

      $child = $this->genReplyForms($reply); 

      $result['forms'] = $result['forms'] + $child['forms']; 
      $result['views'] = $result['views'] + $child['views']; 

     } 

    } 

    return $result; 
} 

MessageReplyType को केवल उपयोगकर्ता इनपुट की आवश्यकता है। बाकी सब कुछ नियंत्रक

 $builder 
     ->add('title') 
     ->add('content', 'textarea') 
    ; 

भी, मेरे सरलीकृत जुड़वां में संभाला जाता है। मैंने मैक्रो कॉल को भी सरल बना दिया है। मैक्रो को बस पास करने के बजाय पहले संदेश के लिए एक अनावश्यक foreach पाश कर रहा था।

{% macro displayReply(reply, forms) %} 
    {% import _self as macros %} 


    {# <li> id: {{ reply.id }} </li> 
    <li> sent by: {{ reply.sender }} </li> 
    <li> title: {{ reply.title }} </li> 
    <li> content: {{ reply.content }} </li> 
    <li> date: {{ reply.sentAt|date('d-m-Y H:i:s') }} </li> 
    <a href="{{ path('private_message_new',{'msg':reply.id}) }}"> reply </a> 
    <hr> #} 
    <div class="panel panel-default"> 
     <div class="panel-body"> 
      <div class="message-info"> 
       <input type="hidden" name="messageid" id="messageId" value="{{ reply.id }}"> 

       <div class="message-title clearfix"> 
        <h4 class="pull-left">{{ reply.title }}</h4> 
       </div> 
       <hr class="lite-line"> 
       <div class="message-sender clearfix"> 
        <div class="pull-left sender"> 
         {{ reply.sender }} 
        </div> 
        <div class="pull-right"> 
         to <b>{{ (reply.receiver==app.user)?'me':reply.receiver }}</b> on <span 
           class="message-timestamp">{{ reply.sentAt|date('F d, Y H:i:s') }}</span> 
         {# <a class="btn btn-start-order" role="button" 
          href="{{ path('private_message_new',{'msg':reply.id}) }}">Reply</a> #} 
        </div> 

       </div> 
       <hr class="lite-line"> 
       <div class="message-box clearfix"> 
        <span>{{ reply.content | replace({"<script>" : "", "</script>" : ""}) | raw }}</span> 
       </div> 


       {{ form_start(forms[reply.id]) }} 
       <input type="submit"> 
       {{ form_end(forms[reply.id]) }} 



       {# NU STERGE! #} 
       {# 
       <form name="privatemessagebundle_message" method="post" action="" id="{{ reply.id }}"> 
        <div><label for="privatemessagebundle_message_title" class="required">Title</label><input 
           type="text" id="privatemessagebundle_message_title" 
           name="privatemessagebundle_message[title]" required="required" maxlength="50"></div> 
        <div><label for="privatemessagebundle_message_content" class="required">Content</label><textarea 
           id="privatemessagebundle_message_content" 
           name="privatemessagebundle_message[content]" required="required"></textarea></div> 
        <input type="hidden" id="privatemessagebundle_message_replyof" 
          name="privatemessagebundle_message[replyof]" value="{{ reply.id }}"> 
        <input type="submit"> 
        <input type="hidden" id="privatemessagebundle_message__token" 
          name="privatemessagebundle_message[_token]" 
          value="{{ csrf_token('privatemessagebundle_message') }}"></form>#} 
       {# NU STERGE! #} 

      </div> 
     </div> 
    </div> 
    {% for reply in reply.replies %} 

     {% if loop.first %}<div>{% endif %} 
     {{ macros.displayReply(reply,forms) }} 
     {% if loop.last %}</div>{% endif %} 

    {% endfor %} 
{% endmacro %} 

{% import _self as macros %} 
{# use the macro #} 

<div class="message-back"> 
    <a class="btn btn-start-order-dark btn-block" role="button" 
     href="{{ path('private_message',{'page':'inbox'}) }}"> 
     <span class="fa fa-undo"></span> Go back 
    </a> 
</div> 

<div class="replies"> 
    {{ macros.displayReply(message, forms) }} 
</div> 

फिर भी, मैं अभी भी बेहतर या अधिक कुशल विकल्पों की तलाश में हूं, इसलिए कृपया उन्हें पोस्ट करें।

संबंधित मुद्दे