Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

PHP Building Websites with PHP Contact Form & Sending Email Sending Our Email

Redirect After Email (SLIM 3)

I'm trying to redirect after email in the 'sending our email' video. I'm using SLIM 3 and have been able to make the corrections so far, but editing the redirect lines has not been working. If someone could lead me into the correct path it would be helpful. My code is below, basically I had everything working up to the redirect after post at which point I was getting this error - Notice: Undefined variable: app in /home/treehouse/workspace/index.php on line 70

I've just realized that the link to my workspace is not pointing at the right thing.

<?php
use \Psr\Http\Message\ServerRequestInterface as Request;
use \Psr\Http\Message\ResponseInterface as Response;

require 'vendor/autoload.php';

// Create app
$configuration  = [
    'settings' => [
        'displayErrorDetails' => true,
    ],
];
$c = new \Slim\Container($configuration);
$app = new \Slim\App($c);

// Get container
$container = $app->getContainer();

// Register component on container
$container['view'] = function ($container) {
    $view = new \Slim\Views\Twig('templates');
    $view->addExtension(new \Slim\Views\TwigExtension(
        $container['router'],
        $container['request']->getUri()
    ));

    return $view;
};



// Render Twig template in route
$app->get('/', function ($request, $response) {
    return $this->view->render($response, 'about.twig');
})->setName('home');

// Render Twig template in route
$app->get('/contact', function ($request, $response) {
    return $this->view->render($response, 'contact.twig');
})->setName('contact');

$app->post('/contact',function($request, $response){
  $body = $this->request->getParsedBody();
  $name =$body['name'];
  $email =$body['email'];
  $msg =$body['msg'];

  if(!empty($name) && !empty($email) && !empty($msg)){
    $cleanName=filter_var($name, FILTER_SANITIZE_STRING);
    $cleanEmail=filter_var($email, FILTER_SANITIZE_EMAIL);
    $cleanMsg=filter_var($msg, FILTER_SANITIZE_STRING);
  }
  else{
   //message the user there was a problem 
    return $this->response->withStatus(200)->withHeader('Location', '/contact');
  }

  $transport = Swift_SendmailTransport::newInstance('/usr/sbin/sendmail -bs');
  $mailer = \Swift_Mailer::newInstance($transport);

  $message = \Swift_Message::newInstance();
  $message->setSubject('Email from our website');
  $message->setFrom(array($cleanEmail=>$cleanName));
  $message->setTo(array('treehouse@localhost'));
  $message->setBody($cleanMsg);

  $result = $mailer->send($message);
  if($result >0){
    //send a message that says thank you 
  $app->get('/', function ($req, $res, $args) use ($app) {
  return $res->withStatus(301)->withHeader('Location', '/');
});

  }
  else{
    //send a message to the user that the message failed to send
    // log that there was an error
    $app->get('/', function ($req, $res, $args) use ($app) {
  return $res->withStatus(301)->withHeader('Location', '/contact');
});
  }

});

// Run app
$app->run();

I'm not sure how far you've gotten with this problem, but this might help:

redirect() is no longer a helper function in the upgrade Slim 3.0. We must now make use of PSR-7's withHeader('Location', 'new-uri') method on the request object. Also, you must use this syntax on the request object to gain access to the field values of your form: $this->request->getParsedBody()[$index]

Notice that getParsedBody() returns an array. You can use extract() on this array to create variables named after the keys found within the array, and values are assigned accordingly. PHP docs does not recommend doing this in our case, however, because our values are not secure; they are input by the user. I didn't understand fully why this complicates things, but it's good to know.

<?php

$app->post('/contact', function ($request, $response, $args){
  $body = $this->request->getParsedBody();
// I chose to only call the getParsedBody() once, 
// but you could also go $name = $this->request->getParsedBody()["name"]
  $name = $body["name"];
  $email = $body["email"];
  $msg = $body["msg"];
  if(!empty($name) && !empty($email) && !empty($msg)){
    $cleanName = filter_var($name, FILTER_SANITIZE_STRING);
    $cleanEmail = filter_var($email, FILTER_SANITIZE_EMAIL);
    $cleanMsg = filter_var($msg, FILTER_SANITIZE_STRING);
  } else {
  //  message the user that there was a problem
 //  Note: 'Location' refers to the current URI and 'contact' refers to my contact URL that I set with 
 // ->setName('contact') at the end of my get() method for the Contact page. ->setName() is the new syntax 
 //  for ->name()
    return $this->response->withStatus(200)->withHeader('Location', '/contact');
  }

// Tells us how to send the email
  $transport = Swift_SmtpTransport::newInstance(whatever-mail-service, whatever-port)
    ->setUsername(your-user-name)
    ->setPassword(your-password)
    ;

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

  $message = Swift_Message::newInstance()
    ->setSubject('Email From Our Website')
    ->setFrom(array(
      $cleanEmail => $cleanName
    ))
    ->setTo(array(your-address))
    ->setBody($cleanMsg);
  $result = $mailer->send($message);

//I added an anchor called #contact so that the page automatically returns to the contact section of my personal portfolio site, which has a much larger height property.
  if($result > 0){
    // say thank you
    $this->flash->addMessage('success', 'Your message has been sent. Thank you!');
    return $this->response->withStatus(200)->withHeader('Location', '/#contact');

  } else {
    //send message to user that message failed to send
    //log that there was an error
    $this->flash->addMessage('err', '***I\'m sorry. There was an issue sending your mail. Please try again.***');
    return $this->response->withStatus(301)->withHeader('Location', '/#contact');
  }
});

Thanks Antonio.. if I replace the if($result > 0) code with your versions, it is working.

1 Answer

Awesome. Look into flash messaging. It allows you to update messages on static pages.