将CSS包含在symfony中从任务发送的电子邮件中

时间:2010-08-06 12:31:43

标签: php symfony1 symfony-1.4 task

我正在尝试从symfony(1.4.6)任务发送HTML电子邮件,我不想从特定模块/操作发送整个呈现的HTML输出,所以我渲染部分。这一切都很好,问题是部分包含CSS引用。

是否有一种很好的'symfonic'方法可以在symfony任务的HTML电子邮件中包含CSS文件,当我所做的只是渲染特定的部分?或者是在任务中手动构建HTML头/体的唯一解决方案,使用file_get_contents(cssFile)获取CSS文件,然后连接渲染的部分?

任何想法都会受到赞赏。

1 个答案:

答案 0 :(得分:2)

我在项目中遇到了同样的问题。以下是我修复它的方法:

  1. 为了使CSS保持独立,但在发送电子邮件之前将其内联,我们使用Emogrifier。下载源代码并将其放入%sf_lib_dir%/vendor/emogrifier

  2. 创建一个扩展sfMailer的myMailer类。我的下面。有几个单独的函数,但关键函数是composeAndSendPartial,它采用部分名称(作为字符串),插入所有CSS内联,并发送它。我试图删除所有特定于我的项目的代码,但我可能已经留下了一些。如果它不适合您或者您有任何问题,请告诉我。

  3. 在factories.yml中,将mailer:设置为myMailer

  4. <强> myMailer.class.php:

    <?php
    class myMailer extends sfMailer
    {
      /**
       * Creates a new message with 2 bodies:
       * * 1 with $body and MIME type text/html.
       * * 1 with $body and tags stripped with MIME type text/plain. Stipped <br/>, </p>, and </div> tags and replaced with \n
       *
       * @param string|array $from    The from address
       * @param string|array $to      The recipient(s)
       * @param string       $subject The subject
       * @param string       $body    The body
       *
       * @return Swift_Message A Swift_Message instance
       */
      public function composeAndSendHtml($from, $to, $subject, $body)
      {
        return $this->send($this->composeHtml($from, $to, $subject, $body));
      }
    
    
      /**
       * Sends a message using composeHtml.
       *
       * @param string|array $from    The from address
       * @param string|array $to      The recipient(s)
       * @param string       $subject The subject
       * @param string       $body    The body
       *
       * @return int The number of sent emails
       */
      public function composeHtml($from = null, $to = null, $subject = null, $body = null)
      {
        return Swift_Message::newInstance()
          ->setFrom($from)
          ->setTo($to)
          ->setSubject($subject)
          ->addPart($this->createPlainTextBody($body), 'text/plain')
          ->addPart($body, 'text/html');
      }
    
    
      /**
       * Attempts to create a plaintext message with all html tags stripped out and new lines inserted as necessary
       * @param $body
       * @return $body
       */
      public function createPlainTextBody($body)
      {
        $body = preg_replace('/\<br\s*\/?\>/i', "\n", $body); //replace all <br/s> with new lines
        $body = preg_replace('/\<\/p\s*\>/i', "</p>\n\n", $body); //append 2 newlines to the end of each </p>
        $body = preg_replace('/\<\/div\s*\>/i', "</div>\n\n", $body); //append 2 newlines to the end of each </div>
        $body = strip_tags($body); //strip all tags from the body
        return $body;
      }
    
      /**
       * Composes and sends an email with a body from rendering $partial with $parameters
       * @param string $from
       * @param string $to
       * @param string $subject
       * @param string $partial the partial as a string. Feel free to change the default module name below
       * @param array $parameters Parameters for the partial
       * @param array $globalStylesheets The stylesheets that are included globally (usually global.css, maybe others)
       */
      public function composeAndSendPartial($from, $to, $subject, $partial, $parameters = array(), $globalStylesheets = array())
      {
        require_once(sfConfig::get('sf_lib_dir') . '/vendor/emogrifier/emogrifier.php');
    
        $context = sfContext::getInstance();
        $response = $context->getResponse();
        $originalStylesheets = $response->getStylesheets();
    
        if (false !== $sep = strpos($partial, '/'))
        {
          $moduleName   = substr($partial, 0, $sep);
          $templateName = '_' . substr($partial, $sep + 1);
        }
        else
        {
          $moduleName = 'email';
          $templateName = '_' . $partial;
        }
    
        sfConfig::set('sf_is_email', true);
        $view = new sfPHPView($context, $moduleName, $templateName, ''); #not sure what 4th parameter does
        $view->getAttributeHolder()->add($parameters);
        $view->setDecorator(true);
        $view->setDecoratorTemplate('email.php');
        $html = $view->render();
        sfConfig::set('sf_is_email', false);
    
        $emailStylesheets = array_keys(array_diff_key($response->getStylesheets(), $originalStylesheets));
    
        $css = '';
        foreach($globalStylesheets as $globalStylesheet)
        {
          $css .= file_get_contents(sfConfig::get('sf_web_dir') . '/css/' . $globalStylesheet . '.css');
        }
        foreach ($emailStylesheets as $stylesheet)
        {
          $css .= file_get_contents(sfConfig::get('sf_web_dir') . '/css/' . $stylesheet . '.css');
          $response->removeStylesheet($stylesheet);
        }
    
        $emog = new Emogrifier($html, $css);
        $body = $emog->emogrify();
    
        $this->composeAndSendHtml($from, $to, $subject, $body);
      }
    }