2010-08-06 33 views
0

我試圖從symfony(1.4.6)任務發送HTML電子郵件,我不想從特定的模塊/動作發送整個呈現的HTML輸出,所以我正在渲染一個部分。這很好,問題是部分包含CSS引用。在symfony中的任務發送的電子郵件中包含CSS

當我所做的全部工作都是渲染某個特定的部分時,是否有一種很好的'symfonic'方法來將symfony任務中的CSS文件包含在HTML電子郵件中?或者是在任務內部手動構建HTML頭部/正文的唯一解決方案,使用file_get_contents(cssFile)來獲取CSS文件,然後連接渲染的部分?

任何想法,將不勝感激。

+2

有專門關於在電子郵件CSS的一些其他信息你可能想看看:http://www.campaignmonitor.com/css/ – Navarr 2010-08-06 12:34:29

+0

好的,這很有用,謝謝。我想一種解決方案是將所有樣式直接添加到HTML標籤,但我希望避免這樣做......我想包含的CSS並不複雜。 – chattsm 2010-08-06 12:43:32

回答

2

我在我的項目中遇到了同樣的問題。以下是我固定它:

  1. 要保持CSS分開的,但把它內嵌在發送電子郵件之前,我們使用Emogrifier。下載源代碼並將其放入%sf_lib_dir%/vendor/emogrifier

  2. 創建一個擴展sfMailer的myMailer類。礦在下面。有幾個獨立的函數,但關鍵函數是composeAndSendPartial,它取部分名稱(作爲字符串),將所有CSS內聯插入,併發送它。我嘗試刪除特定於我的項目的所有代碼,但我可能已經留下了一些代碼。請告訴我它是否對您無效或者您有任何問題。

  3. 在factories.yml文件,設置mailer:myMailer

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); 
    } 
} 
相關問題