2010-08-18 9 views
0

J'ai un fichier xml email comme ceci:Modèles d'e-mail stockés en XML. Comment faire pour exécuter php à l'intérieur du xml?

<?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> 

J'ai une classe qui traite le modèle de courrier électronique.

I.e. vous définissez un paramètre comme ceci:

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

Et lorsque vous appelez setContent il fera un str_replace sur le contenu de% name% et tous les autres paramètres. Assez simple. Puis j'ai réalisé, et si j'ai besoin de faire une boucle dans le modèle pour lister tous les contrats etc. Je devrais faire une boucle php dans le fichier xml, mais comment puis-je passer à travers un objet et alors exécutez le contenu comme php et recevez la sortie?

Des idées?

Merci mec!

EDIT: Juste pour être clair sur quelque chose. Je ne souhaite pas construire le code HTML et le passer en paramètre. J'utilise symfony et donc je veux garder html hors du contrôleur.

C'est là où il est appelé:

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("[email protected]"); 
    $message->setFrom(array("[email protected]"=>"Automated Message")); 
    $message->setBody($mail->getHtmlContent(), 'text/html'); 
    $message->addPart($mail->getPlainContent(), 'text/plain'); 

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

Faire quelque chose comme (dans l'action):

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

Et puis en passant à travers comme paramètre:

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

Cette méthode est juste moche.

Répondre

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

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

Remplacez votre boucle avec %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> 
      ]]> 

construire donc une liste de vos titres de contrat et de le remplacer dans le corps du message.

+0

Aha, je savais que je recevrais cette réponse. Le problème est, j'utilise symfony, et je suis en train de traiter ce modèle d'email dans une action.Je ne souhaite donc pas générer de code HTML dans une action, la stocker dans une variable et la passer en paramètre. Je veux garder le html loin du contrôleur. J'aurais dû le mentionner. – Flukey

1

Je suggère de ne pas avoir de logique dans le modèle. Ajoutez un espace réservé %contracts% et apprenez à votre classe de gestion de modèle comment remplacer ceci à partir de PHP, pas le modèle. Vous pouvez écrire une classe d'assistance pour accompagner votre classe Mailer. De cette façon, vous pouvez le garder hors du contrôleur. IMO, le code configurant l'expéditeur ne devrait pas être là non plus, mais dans une classe de service dans le modèle.

Sur une note, cela semble être un bon candidat pour XSLT.

+0

Hmmmm intéressant .... Je vais regarder dans ce domaine. Merci. EDIT: La classe de courrier est juste pour obtenir le modèle d'email et pour régler tous les paramètres. C'est une entité séparée de $ this-> getMailer. :-) – Flukey

+0

@Jamie ouais, mais quand même. Vous pouvez ajouter une classe 'ContractExpiredMailService' qui n'expose que les méthodes nécessaires pour que le mail soit composé et envoyé. Tout ce que votre contrôleur aurait à faire, c'est gérer la demande et déléguer au service et le service s'occuperait du reste. En configurant et en envoyant le courrier dans le contrôleur, vous gérez efficacement la logique métier dans la couche de présentation. – Gordon

+0

Absolument. C'est le plan ... mais pour l'instant je fais juste des tests rapides. Une fois que j'ai une bonne solution en place, je vais tout transférer vers les classes de service pertinentes, etc. Merci. – Flukey

0

peut-être vous pouvez utiliser ob_start pour préparer la sortie avant d'envoyer à l'email

im désolé, je ne le fais pas en mode classe. mais j'espère que cela vous donnera un aperçu.

Code

est quelque chose comme ceci:

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"));