Php 为每个收到的邮件添加回复表单文本字段
我有一个私有消息包/实体,允许我的用户在他们之间发送消息 其字段如下:Php 为每个收到的邮件添加回复表单文本字段,php,symfony,twig,symfony-forms,Php,Symfony,Twig,Symfony Forms,我有一个私有消息包/实体,允许我的用户在他们之间发送消息 其字段如下: /** * @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")
/**
* @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
字段,它引用了另一条消息
,而reply
字段引用了一系列消息
。如果replyof
为空,则该消息不是任何消息的回复
我有一个带有宏的小树枝模板,它显示用户的消息和该消息的所有回复。我想做的是在每封邮件下面都有一个回复文本字段,就像Gmail一样,它允许我为每条邮件添加回复
但当我将其添加到模板时,只会呈现一个,因为它只有一个Id。如何在每次回复后添加回复表单?他们的表单类型应该是什么样的
这也是我的小枝模板:
{% 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 %}
至于回复的其他字段,我在控制器中处理它们。不过,我想我应该在收到表单上的消息后再这样做。类似这样,并从formdata获取标题、内容和回复
$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);
编辑
好的,我做了一些有用的东西,通过添加一个隐藏字段和硬编码多个表单,而不是使用表单类型,但我仍然认为这可以用一种更好、更可重用的方式来完成
<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>
标题
内容
有谁有更好的主意吗?我有!我用了这个答案 因为我使用的是foreach循环,它们的性能可能有点低,所以欢迎有更好想法的人。还有悬赏要接受 我正在通过createNamedBuilder为我的每个表单创建一个表单。它们将有不同的名称,因此不同的id和Symfony将呈现它们。然后,我可以在我想要的地方呈现它们,并通过从数据库中获取它们的唯一id很好地处理它们的请求
$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>
{%macro-displayReply(reply,forms)%}
{%import\u self as macros%}
{{{reply.id}
发送人:{reply.sender}
标题:{reply.title}
内容:{reply.content}
日期:{reply.sentAt | date('d-m-Y H:i:s')}
#
{{reply.title}
{{reply.sender}}
在{{reply.sentAt}日期('fd,yh:i:s')}上发送到{(reply.receiver==app.user){me':reply.receiver}}
{# #}
{reply.content | replace({“:”,“:”})| raw}
{{form_start(forms[reply.id])}
{{form_end(forms[reply.id])}
{NU STERGE!}
{#
标题
内容
#}
{NU STERGE!}
{%用于答复中的答复。答复%}
{%if loop.first%}{%endif%}
{{macros.displayReply(reply,forms)}
{%if loop.last%}{%endif%}
{%endfor%}
{%endmacro%}
{%import\u self as macros%}
{#使用宏#}
{{macros.displayReply(消息、表单)}
同样,我仍在寻找更好或更有效的替代方案,因此请发布它们。似乎可以更好地使用Javascript初始化textarea,因此您只需要一个表单。该表单可以将
replyTo
id作为隐藏字段。这样,您只需要一个文本区域,对吗?这将需要更多的JS,因为每次单击回复按钮时,replyTo也必须更改值。它也更容易受到CSRF的影响。我认为我的解决方案虽然复杂,但有点优雅,但你的也相当不错。
{% 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>