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 trialAntonio Jaramillo
15,604 Pointsredirect() with Slim 3.0
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.
Here is my post() code for this lesson:
<?php
$app->post('/contact', function (Request $request, Response $response, array $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)){
} 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');
}
});
?>
Antonio Jaramillo
15,604 PointsNo problem. It was a struggle. Take a look at my post in the previous video, as well. I'm a newb, so figuring this stuff out proves that anyone can do it. I can't get my local server to send out an email in the coming lessons. I'm using Apache 2.4 on a Windows 10 laptop. Also, using Slim 3.0 and PHP 7. I keep getting a Slim Error, with no specifics other than 500. I've set my php.ini sendmail_from value, etc., etc. I just don't know enough to troubleshoot this.
Antonio Jaramillo
15,604 PointsThis is a link to my comment in the previous lesson: https://teamtreehouse.com/community/slim-30-code-for-this-lesson
Tim Knight
28,888 PointsI'm still pretty new with PHP myself... normally focus on Rails and I can't say I'd be much help on Windows setup as a Mac user. What you've done definitely helps many of us though. Mail has always been weird for me with PHP. Are you using SwiftMailer?
Antonio Jaramillo
15,604 PointsI am. It must be something to do with my php.ini or Apache settings. I get a "Slim Error" but I don't think the error has to do with my code, as it's SwiftMailer code that we're using rather than Slim 3.0 to set up our mail. Not sure what the problem is.
I've debugged up to the $result = $mailer->send($message); It's definitely that line that triggers the error. My form input values are all properly assigned to their appropriate variables as verified by 'var_dumping' each of them.
Tim Knight
28,888 PointsI'll try to get something setup using Slim 3.0 and see what kind of errors I come across.
Antonio Jaramillo
15,604 PointsI came across this awesome/useful Swiftmailer Logger plugin at http://swiftmailer.org/docs/plugins.html The logger gave me this when I sent a mail: ++Starting Swift_SmtpTransport
I assume that this is in fact not an error at all. It's working, but my localhost configs must not be set correctly. Here is how to make use of this plugin:
<?php
// Tells us how to send the email
// I'm using a local Apache 2.4 server run with PHP 7. I'm also using Slim 3.0.
// I'm using a free mailing service called Mailgun because Apache apparently
// can't send mail on its own. The code, excluding the logger setup, is recommended
// by Mailgun, and is found in their blog.
// Notice that you can chain, just like in jQuery.
$transport = Swift_SmtpTransport::newInstance('smtp.mailgun.org', 25)
->setUsername('postmaster@my_domain')
->setPassword('my_password')
;
// Create the Mailer using your created Transport
$mailer = Swift_Mailer::newInstance($transport);
$logger = new \Swift_Plugins_Loggers_EchoLogger();
$mailer->registerPlugin(new \Swift_Plugins_LoggerPlugin($logger));
$message = Swift_Message::newInstance()
->setSubject('Email From Our Website')
->setFrom(array(
$cleanEmail => $cleanName
))
->setTo(array('me@me.com'))
->setBody($cleanMsg);
if(!$mailer->send($message, $errors)) {
echo "Error: " . $logger->dump();
} else {
$result = $mailer->send($message);
}
?>
Tim Knight
28,888 PointsI think you're probably right on in terms of it just being a local configuration issue, but this is really helpful.
Antonio Jaramillo
15,604 PointsGot it to work! Mailgun apparently has issues with port 25. Changed it to port 587, as recommended by Mailgun, and I can now successfully send mail from my local server with the code above! Phew. That took 3 days.
Tim Knight
28,888 Points3 days though... not so bad for some new things. Well done!
Mattea Turnbull
4,134 PointsAntonio - I have a related question about redirects from later in the videos when we're trying to redirect after we've set up our mail... can you have a look?
https://teamtreehouse.com/community/redirect-after-email-slim-3
4 Answers
Kristjan Reinsberg
50,960 PointsFULLY WORKING CODE......
if ( !empty($name) && !empty($email) && !empty($msg) ) {
} else {
return $response->withStatus(301)->withHeader('Location', '/composertest/contact');
}
Antonio Jaramillo
15,604 PointsI'm using a local server and had to set up my own mail server. My code wasn't the problem.
Devin Gray
39,261 PointsI did it slightly differently, but I'm glad I figured it out before coming to the forum for help. If you don't like creating a project for every new PHP site you make, like me, it can be a pain to put the whole directory name as the location. So i made the current URI into a variable and pointed the location to that variable. It does the same thing, but it won't break when I migrate the site. But this post even helped me find some errors with my code. I love treehouse!
<?php
$app->post('/contact', function ($request, $response, $args) {
$body = $this->request->getParsedBody();
$name = $body['name'];
$email =$body['email'];
$msg = $body['msg'];
$uri = $request->getUri();
if(!empty($name) && !empty($email) && !empty($msg)) {
} else {
//message the user that there was a problem
return $response->withHeader('Location', $uri);
}
});
Alexander Grishchun
360 PointsHi, guys. I can not understand one thing. If i have 2 different forms on my site. Where in my index.php i need to indicate, from witch form Slim must grub and post data? Maybe it "action" parameter?
Aleksandr Antropov
6,458 PointsCan do like this also
<?php
else {
//message the user that there was a problem
return $res->withRedirect('/contact');
}
Tim Knight
28,888 PointsTim Knight
28,888 PointsThis is great to know Antonio, seriously... thank you so much for sharing this.