3

I have an installation of survey web app LimeSurvey set up for a coworker's project. It works great. I've customized the HTML, CSS (with a separate print stylesheet), and JavaScript to our liking.

I need the user to able to send the contents of a dynamically-generated page of questions (in our case actually "recommendations", but still "questions" to the system) either in the body of an email, or as an attachment. This content contains a number of divs with simple formatted (some bolding) text content. Preferably this email would use the print stylesheet I've defined, but really anything readable would do.

I would use an existing service like EcoSafe, but that service visits the given URL itself and converts it to a PDF. This means they get the front page of the survey rather than the dynamically-generated page content the user sees.

I've searched and found some talk of PHP libraries that can send formatted emails, but I have little-to-no PHP experience. I'm thinking maybe I can use JavaScript or JQuery to grab the contents of the page and then a server-side tool to send that content in an email...but I don't quite know where to start. I have full access to our web server and so can install any libraries or scripts necessary.

Or if there's even a way to do this with mailto: links, that could be sufficient.

Anybody have ideas on how to send the contents of a dynamically-generated page in an email?

Thanks in advance.

LouieGeetoo
  • 868
  • 2
  • 11
  • 26
  • 1
    On the PHP front, using SwiftMailer or PHPMailer both make it easy to send HTML-formatted emails, with attachments. Given that LimeSurvey itself seems to be written in PHP, you should be able to easily intercept its output to grab the HTML and use either SM or PHPM to redirect it outwards as an email. – Marc B Sep 26 '11 at 21:26

2 Answers2

1

You can use included system from LimeSurvey.

  1. Construct some part of your body with Expression Manager: example :"Your answer to {QuestionCode.question} was {QuestionCode.NAOK}" in some equation question type (more easy to use it after)
  2. Use 'Send basic admin notification email to:' par to put the email adress : you can use EM too : for example {if(Q1.NAOK=='Y','yesadress@example.org','adress@example.org')} ...
  3. Use Email template/Basic admin notification to put all your needed content.

Denis

Denis Chenu
  • 846
  • 2
  • 7
  • 22
1

EDIT: As Cheekysoft points out in the comments, this code as written is not secure and would allow a malicious user to send any arbitrary email content through your app.

In other words, do not use the code below as-is.


I ended up using a combination of jQuery and PHP to get the job done.

  1. On my survey page I added a small form to collect the user's email address.
  2. I used jQuery to POST this form and the contents of the page's wrapper tag to a PHP script.
  3. In that PHP script, I used Emogrifier to add in-line tags to the HTML passed in by jQuery using a stylesheet as reference (because most email clients, including Gmail, don't allow using linked styleheets).
  4. Then (still in the PHP script) I sent the actual email using SwiftMailer (thanks for pointing me towards it, Marc B) and a Google Apps account's SMTP functionality.

Works great!

In case it will help anyone in the future, here's the PHP script (sanitized):

<?php

/***** INITIALIZE *****/

/* Import libraries */
require_once 'swiftmailer/swift_required.php';
require_once 'emogrifier/emogrifier.php';

/* Email stylesheet location */
$stylesheet = 'http://example.com/email.css';

/* SMTP Account Info */
$smtpusername = "sender@gmail.com";
$smtppassword = "senderpassword";
$smtpserver = "smtp.gmail.com";
$smtpport = 465;
$smtpsecurity = "ssl";


/***** RETRIEVE THE DATA *****/

/* Retrieve the passed-in variables */
/* HTML for the email body */
$html = $_POST['content'];
/* Recipient mail address */
$address = $_POST['address'];
/* Recipient name */
$name = $_POST['name'];
if ($name==NULL || $name=="") {
    $name = "You";
}

/***** MODIFY THE HTML *****/
// Get stylesheet contents as a string
$css = file_get_contents($stylesheet);

// Convert stylesheet into in-line styles using Emogrifier - http://www.pelagodesign.com/sidecar/emogrifier/
$converter = new Emogrifier($html, $css);
$content = $converter->emogrify();


/***** CREATE THE MESSAGE *****/

/* Create the message */
$message = Swift_Message::newInstance()

  //Give the message a subject
  ->setSubject("Results for $name")

  //Set the From address with an associative array
  ->setFrom(array('sender@gmail.com' => 'Sender Name'))

  //Set the To addresses with an associative array
  ->setTo(array($address => $name))

  //Give it a body
  ->setBody($content, 'text/html')
  ;

/***** SEND THE EMAIL *****/

//Create the Transport
$transport = Swift_SmtpTransport::newInstance($smtpserver, $smtpport, $smtpsecurity)
  ->setUsername($smtpusername)
  ->setPassword($smtppassword)
  ;

//Create the Mailer using your created Transport
$mailer = Swift_Mailer::newInstance($transport);

//Send the message
$result = $mailer->send($message);

if ($result == "1") {
    echo "<span class='sendstatus success'>Email sent successfully. </span>";
} else {
    echo "<span class='sendstatus failure'>An error occurred. Result code: $result </span>";
}

?>

And here's the jQuery form (simplified a bit):

<div id="emailresults">
    <form id="emailRecsForm" action="http://example.com/emailresults/emailrecs.php"> <!-- THIS PAGE WHERE THE PHP ABOVE IS LOCATED -->
        <h3><img src="email-icon.png" /> Email Your Results</h3>
        <label for="name">Name</label><input type="text" id="name" name="name" placeholder="Recipient's name (optional)" />
        <label for="address">Email address</label><input type="text" id="address" name="address" class="required email" placeholder="recipient@address.org" />
        <div id="submitdiv"><input type="submit" class="submit" value="Send Results" /></div>
    </form>
    <!-- the result of the send will be rendered inside this div -->
    <div id="result"></div>
</div>

<script>
/* attach a submit handler to the form */
$("#emailRecsForm").submit(function(event) {
    /* stop form from submitting normally */
    event.preventDefault();

    $( "#submitdiv" ).empty().append('<span class="sendstatus working"><img src="/images/loadwheel.gif" alt="Sending..."></img></span>');

    /* get some values from elements on the page: */
    var $form = $( this ),
        name = $form.find( 'input[name="name"]' ).val(),
        address = $form.find( 'input[name="address"]' ).val(),
        html = $('.container').html(),
        url = "http://example.com/emailrecs.php";

    /* Send the data using post and put the results in a div */
    $.post( url, { name: name, address: address, content: html },
      function( data ) {
          $( "#submitdiv" ).empty().append('<br />').append( data ).append('<input type="submit" class="submit" value="Send Results" />');
          $form.find( 'input[name="name"]' ).val("");
          $form.find( 'input[name="address"]' ).val("");
      }
    );
});
</script>
LouieGeetoo
  • 868
  • 2
  • 11
  • 26
  • 1
    Bear in mind that without the addition of robust authentication or validation, an attacker can abuse this PHP script to send an email with arbitrary HTML content, to any recipient your mail server is able to send to. – Cheekysoft Oct 05 '17 at 11:06
  • You're right. This code is pretty old, from before I really understood anything about web security. I've switched the accepted answer to Denis Chenu's, which looks sensible enough. – LouieGeetoo Oct 05 '17 at 15:08