我想在发送电子邮件之前运行重复内容检查,在我的symph2应用中使用 swiftmailer 来发送给我错误的日志条目< / strong>即可。
这个功能就在我的错误日志到数据库功能旁边,它也有重复检查,虽然那个更容易,它使用sql。
对于这一个,我想维护最后发送的邮件至少发送的10封电子邮件,这样如果我的错误日志失控,它就不会继续向我发送同样错误的重复电子邮件。
我应该将这个主体收集到一个包含最后10个邮件正文的对象上,并将其附加到swift邮件程序类中吗?还是有一种更简单的方法,比如使用已经嵌入swift邮件程序的东西进行这种发送使用?或者也许是会议..
编辑,我从后端帮助程序类调用swift邮件程序,所以我认为只要它至少半优雅,我就可以做任何事情。
编辑这是调用电子邮件的持久性和触发方法的精炼版本
<?php
class someWierdClass
{
public function addLogAction(Request $request, $persist = TRUE, $addEmail = TRUE)
{
$responseAdd = array();
if ($this->getRequest()->request->all() !== null) {
$data = $this->getRequest()->request->get('data') ? $this->getRequest()->request->get('data') : 'no_data';
$duplicate = $this->getRequest()->request->get('duplicate', null);
}
if ($addEmail) {
$responseAdd[] = 'firedIt';
$this->fireEmailString('You have an error log here. <br>' . $data);
}
if ($persist)
{
$responseAdd[] = 'persistedIt';
$this->persistLog($data, $duplicate);
}
if ($responseAdd)
{
$body = implode(', ', $responseAdd);
return new Response($body);
}
}
}
答案 0 :(得分:1)
在表格中记录电子邮件,并检查每次发送电子邮件时是否重复。
为此,您应该创建一个帮助函数,在电子邮件表中查询与您要发送的正文相匹配的条目。如果查询没有返回任何内容,那么您就知道它不是重复的。然后,您将发送电子邮件并将其记录到数据库中。否则,如果它返回(a)记录,您将发送一个dev ERROR日志条目。
如果您只想检查最近10封电子邮件,可以通过查询$body == $new_body
和$id >= ($total_rows-10)
然后,您可以将其注入容器并使用类似的东西调用它
$this->container->get('helper')->sendEmail($body, $subject, $recipients);
答案 1 :(得分:0)
好的,感谢Dan关于使用数据库进行重复检查的想法。如果您注意到,根据您的建议,我已经在进行重复检查,但这让我想到了。它帮助我连接点。
我所做的是,如果在更新数据库时它的响应是重复的,则返回答案,然后使用该响应作为标志来确定电子邮件是否触发。 (在我的情况下,我进一步检查更新的邮票至少+1小时,而不是最后10封电子邮件内容&#39;想法)
继承代码..享受..
<?php
namespace Acme\AcmeBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller,
Acme\AcmeBundle\Entity\Log,
Symfony\Component\HttpFoundation\JsonResponse,
Symfony\Component\HttpFoundation\Response,
Symfony\Component\Config\Definition\Exception\Exception,
Symfony\Component\HttpFoundation\Request,
Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
class someWierdClass
{
/**
* @var array
*/
protected $senderArray = array('no-reply@yorudomain.com' => 'Your Website Name');
/**
* @param Request $request
* @param bool $persist
* @param bool $addEmail
* @return Response
*/
public function addLogAction(Request $request, $persist = TRUE, $addEmail = TRUE)
{
$responseAdd = array();
if ($this->getRequest()->request->all() !== null) {
$data = $this->getRequest()->request->get('data') ? $this->getRequest()->request->get('data') : 'no_data';
$type = $this->getRequest()->request->get('type') ? $this->getRequest()->request->get('type') : 'no_type';
$duplicate = $this->getRequest()->request->get('duplicate', null);
}
if ($addEmail) {
$responseAdd[] = 'firedIt';
$this->fireEmailString('You have an error log here. <br>' . $data);
}
if ($persist) {
$responseAdd[] = 'persistedIt';
$persistResponse = $this->persistLog( $type = $data, $duplicate);
if ($persistResponse) {
// a dup check is done here and results of this is on the response. (e.g. $content->passesCutoff)
$content = json_decode($persistResponse->getContent());
}
}
if ( $addEmail && ( isset($content->passesCutoff) && $content->passesCutoff ))
{
//fire off an email also, because its kind of hard to look in teh logs all the time, sometimes we just want an email.
$successEmail = $this->fireEmailString($data);
if( ! $successEmail )
{
$responseAdd[] = 'firedIt';
}
}
if ($responseAdd) {
$body = implode(', ', $responseAdd);
return new Response($body);
}
}
/**
* @param $emailStringData
* @param null $emailSubject
* @param null $emailTo
* @return mixed
*/
protected function fireEmailString($emailStringData, $emailSubject = null, $emailTo=null){
$templateName = 'AcmeBundle:Default:fireEmailString.html.twig';
if( ! $emailSubject )
{
$emailSubject = 'An email is being fired to you!' ;
}
if( ! $emailTo )
{
$emailTo = 'youremail@gmail.com';
}
$renderedView = $this->renderView(
$templateName, array(
'body' => $emailStringData,
));
$mailer = $this->get('mailer');
$message = $mailer->createMessage()
->setSubject( $emailSubject)
->setBody($emailStringData, 'text/plain')
->addPart($renderedView, 'text/html')
->setFrom($this->senderArray)
->setSender($this->senderArray)
->setTo($emailTo);
$results = $mailer->send($message);
return $results;
}
/**
* @param $type
* @param $data
* @param $duplicate
* @return JsonResponse
*/
protected function persistLog($type, $data, $duplicate) {
$em = $this->getDoctrine()->getManager();
$count = null;
$passesCutoff = null;
$mysqlNow = new \DateTime(date('Y-m-d G:i:s'));
//only two conditions can satisy here, strings '1' and 'true'.
if($duplicate !== '1' && $duplicate !== 'true' /*&& $duplicate != TRUE*/)
{
//in order to check if its unique we need to get the repo
//returns an object (findByData() would return an array)
$existingLog = $em->getRepository('AcmeBundle:Log')->findOneByData(
array('type' => $type, 'data' => $data)
);
if($existingLog)
{
$timeUpdatedString = strtotime($existingLog->getTimeupdated()->format('Y-m-d H:i:s'));
$cutoffStamp = strtotime('+1 hour', $timeUpdatedString); //advance 1 hour (customize this to the amount of time you want to go by before you consider this a duplicate. i think 1 hour is good)
$passesCutoff = time() >= $cutoffStamp ? TRUE : FALSE; //1 hour later
$count = $existingLog->getUpdatedcount();
$existingLog->setUpdatedcount($count + 1); // '2014-10-11 03:52:20' // date('Y-m-d G:i:s')
$em->persist($existingLog);
}
else
{
//this record isnt found, must be unique
$newLog = new Log(); //load our entity
//set in new values
$newLog->setType($type);
$newLog->setData($data);
$newLog->setUpdatedcount(0);
$newLog->setTimeupdated($mysqlNow);
$em->persist($newLog);
}
}
else
{
//we dont care if unique or not, we just want a new row
$newLog = new Log(); //load our entity
$newLog->setType($type);
$newLog->setData($data);
//time updated has been set to auto update to current timestamp in the schema, test first, then remove this
$newLog->setUpdatedcount(0);
$newLog->setTimeupdated($mysqlNow);
$em->persist($newLog);
}
$em->flush();
$response = new JsonResponse();
$response->setData(
array(
'data' => 'persistedIt',
'existingLog' => $count,
'passesCutoff' => $passesCutoff,
));
return $response;
}
}
事后看来,我刚刚在persist方法的响应中传递了最后一次更新时间戳,然后显然在fire email方法中进行了cutoff计算,但上面的代码确实起到了作用的作用..: - )