send html emails using a view as the content

In my base controller I have this code which checks if there is a view and then displays it. I want to modify this to use for sending an email. I basically want to create views which contain html content for sending the mails. But trying to access it normally as if I were displaying a view doesn't quite work. This is the code for displaying the views on the website.

	public function view($view, $data = []) {
		// check for view file
		if(file_exists('../app/views/' . $view . '.php')) {
			require_once '../app/views/' . $view . '.php';
		} else {
			die('View does not exist');
		}
	}

Open in new window


To display a view, I would just do this in my controller:

$this->view('pages/contact-us');

Open in new window


When I am trying to send email, I want to just send the view into the email body.

$html = $this->view('pages/email');
//other variables go here

$send = new Email();
$send->sendMail($html, $subject, $setFrom, $addReplyTo, $addAddress, $altBody);

Open in new window


Doing this fails. I think I need to just return the view but not sure how to do this.
LVL 1
Black SulfurAsked:
Who is Participating?
 
Steve BinkCommented:
What framework are you using?

Normally, the controller calls a method in the view class which generates that view's HTML.  The usual calling method is nothing more than a macro/wrapper around "load everything, generate the output, and render to response".  I would start by examining the view class to find out exactly what is going on when you require it.

If it turns out that the view file is rendering to output on its own, then you still have a couple options:

1) Edit the view class to support the separate rendering function.  If this is your framework, this would be my recommended path.  If this is a third-party framework, you should think long and hard about doing this.

2) Use PHP's output buffering functions to capture the required file's output.  If you can't/don't want to edit the framework, this is a decent option.
0
 
Black SulfurAuthor Commented:
@Steve, thanks for your comments. I am not using a framework like Laravel etc. so I should be able to do whatever I like, provided I know what to actually do :)

Before you answered, I had progressed slightly. I created a new method in my core controller like this.

public function getView($view, $data = []) {
if(file_exists('../app/views/' . $view . '.php')) {
     return file_get_contents('../app/views/' . $view . '.php');
} else {
    die('View does not exist');
}

Open in new window


And then did this in the controller:

$html = $this->getView('pages/contact-email', $data);

Open in new window


The plain html content is now displaying in the emails which is great but not the php. If I try this in the view:

<?php echo $data['name']; ?>

Open in new window


nothing shows up php wise, just the html and missing gaps where there should be dynamic values.

$data is just the values from the form in an array eg:

$data = [
 
  'name' => $_POST['name']

];

Open in new window

0
 
Steve BinkCommented:
That's because file_get_contents() doesn't actually execute PHP - it just returns the contents of the file as text.  You should still continue to use require/include to make sure the code runs.  Any variables in the calling scope should be available within the file, which means accessing $data directly should work fine.
0
 
Black SulfurAuthor Commented:
I took a look at ob_start() and got it to work by doing this. Is it an acceptable way?


public function getView($view, $data = []) {
	if(file_exists('../app/views/' . $view . '.php')) {
		ob_start();
		require '../app/views/' . $view . '.php';
		return ob_get_clean();

	} else {

		die('View does not exist');
	}
}

Open in new window


I would have preferred to do what you said here but couldn't figure out how.

Edit the view class to support the separate rendering function.  If this is your framework, this would be my recommended path.  If this is a third-party framework, you should think long and hard about doing this.
0
 
Steve BinkCommented:
Based on your usage of require/include to create your view output, I'm guessing you don't have an actual view class.  That would make it much harder to pursue that option.

Your ob_start() example is right on the nose.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.