开发者

Email templates stored in XML. How to execute php inside the xml?

I开发者_StackOverflow have an email xml file like this:

<?xml version='1.0' standalone='yes'?>
<emails>
 <email id="contract-expired">
    <description>We send this email when we want to inform a user that a contract is coming up to it's expiration date</description>
    <subject>Example: Contract Expiration</subject>
    <parameters>
        <param>name</param>
        <param>number_of_contracts</param>
    </parameters>
    <content>
        <html>
            <![CDATA[
            Dear %name%, <br />
            <p>
            <?php
                       foreach($contract as $value):
                         echo $value->getTitle()
                       endforeach;
                    ?>
            You have %number_of_contracts% contracts that are due to expire in under 30 days. Please log in to example.com to review the contracts.
            <br /><br />
            This is an automated email. Please do not reply.
            </p>
            ]]>
        </html>
        <plain>
            Dear %name%, You have %number_of_contracts% contracts that are due to expired in under 30 days. Please log in to example.com to review the contracts. This is an automated email. Please do not reply.
        </plain>
    </content>
 </email>
</emails>

I have a class that processes the email template.

I.e. you set a parameter like so:

$mail->setParameter("name", "Jamie");

And when you call setContent it will do a str_replace on the content for %name% and all other parameters. Simple enough.

And then I realised, what if I need to do a loop in the template to list out all contracts etc. I'd have to do a php loop in the xml file, but how can I pass through an object and then execute the content as php and receive the output?

Any ideas?

Thanks guy!

EDIT: Just to be clear on something. I don't wish to build up the html and then pass it through as a parameter. I'm using symfony and thus I want to keep html out of the controller.

This is where it's being called:

  public function executeContractExpired(sfWebRequest $request)
  {
    $mail = new Mail("contract-expired");
    $mail->setParameter("name", "Joe Bloggs");
    $mail->setParameter("number_of_contracts", 567);
    $mail->setContent();

    $message = $this->getMailer()->compose();
    $message->setSubject($mail->getSubject());
    $message->setTo("example@example.com");
    $message->setFrom(array("jamie@example.com"=>"Automated Message"));
    $message->setBody($mail->getHtmlContent(), 'text/html');
    $message->addPart($mail->getPlainContent(), 'text/plain');

    $this->getMailer()->send($message);
  }

Doing something like (in the action):

$contracts_html = "<ul>";
foreach($contracts as $contract)
{
    $contracts .= "<li>" . $contract->getTitle() . "</li>"
}
$contracts .= "</il>";

And then passing it through as a parameter:

$mail->addParameter("contracts", $contracts_html);

That method is just ugly.


I'd suggest not having logic in the template. Add a placeholder %contracts% and teach your template handling class how to replace this from within PHP, not the template. You could write a helper class to go alongside your Mailer class. This way, you can keep it out of the controller. IMO, the code configuring the Mailer shouldnt be in there either, but in a Service class in the model.

On a sidenote, this seems to be a good candidate for XSLT.


$contractTitles = implode(',', $contract);

$mail->setParameter("contract_titles", $contractTitles);

Replace your for loop with %contract_titles%

            <![CDATA[
            Dear %name%, <br />
            <p>
           %contract_titles%
            You have %number_of_contracts% contracts that are due to expire in under 30 days. Please log in to example.com to review the contracts.
            <br /><br />
            This is an automated email. Please do not reply.
            </p>
            ]]>

So build a list of your contract titles and replace it into the message body.


may be you can use ob_start to prepare the output before it send to email

im sorry i don't do it on class mode. but i hope you this will give you insight.

code is something like this :

function callback($buffer)
{   
    // bundle of string you want to replace
    return str_replace("name", "Mr.John" , $buffer);
}

function getEmail($email_template_path, $contacts){
    ob_start();
    include($email_template_path);
    $email_to_send = ob_get_contents(); 
    ob_end_clean();

    return callback($email_to_send);
}

echo getEmail("/opt/lampp/htdocs/index.html",array("Mr. Smith", "Mrs.Smith"));
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜