swiftmail symfony在发送之前重复检查错误日志/电子邮件

时间:2015-04-06 20:48:49

标签: symfony duplicate-removal swiftmailer

我想在发送电子邮件之前运行重复内容检查,在我的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);
        }
    }
}

2 个答案:

答案 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计算,但上面的代码确实起到了作用的作用..: - )