• 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
mail() is broken inside codeigniter?

#1
[eluser]Dave332[/eluser]
Okay, so I need to use the mail() function to send user emails. I tried using the native mail function, but it didn't work, so I tried the email library. That didn't work, so I started trying to debug the mail function (cause I was pretty sure it should work). I wrote a script to test the mail function on my server, which seems to work.

Here is the script I used to test the mail function, if anyone would like to see it:

Code:
<?php

if(isset($_POST['email']))    {
    if(preg_match("/^([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@([a-z0-9\-]+\.)+[a-z]{2,6}$/ix", $_POST['email']))    {
        $to = $_POST['email'];
        $message = "The email system is properly configured for ".$_SERVER['SERVER_NAME'];
        $from = '[email protected]'.$_SERVER['SERVER_NAME'];
        $success = mail($to,'Test Email',$message,"From: $from");
        if(!$success)
            $error = "Sorry, the mail system seems to be non-functional, or misconfigured.";
        else
            $error = "Your email system appears to be functioning correctly.";
    }
    else
        $error = "Please enter a valid email.";


}


?>
<html>
    <body>
        <center>
            &lt;? if(isset($error)) : ?&gt;
            <p>&lt;?=$error?&gt;</p>
            &lt;? endif; ?&gt;
            &lt;form action="&lt;?=$_SERVER['PHP_SELF']?&gt;" method="post"&gt;
                <table>
                    <tr><td colspan="2">Please enter an email to send a test message</td></tr>
                    <tr><td><label for="email">Email</label></td><td>&lt;input type="text" name="email" /&gt;&lt;/td></tr>
                    <tr><td colspan="2">&lt;input type="submit" name="test" value="Test Email" /&gt;&lt;/td></tr>
                </table>
            &lt;/form&gt;
        </center>
    &lt;/body&gt;
&lt;/html&gt;

This script works just fine on my server, so I'm assuming that php is properly configured. The problem is, when I execute the mail() function inside my model, it doesn't work. My CodeIgniter app is running on the same server, so I'm really confused as to why the native mail function works on place and not another. Here is the function I'm using inside my model:

Code:
function reset_password($username)    {
        $u = $this->get_user_by_username($username);
        $password = "";
        $chars = '[email protected]#$%^&*()_-=+\|][}{`~/?.>,<;:';
        for($i = 0; $i < 15; $i++)    {
            $c = substr($chars,mt_rand(0,strlen($chars)-1),1);
            if(!strstr($password,$c))
                $password .= $c;
        }
        $t = $u['email'];
        $s = "Your New Password";
        $m = "Your password has been reset.  The new password for your account is $password \nThis can be changed by editing your profile.";
        $f = "From: [email protected]".$_SERVER['SERVER_NAME'];
        $success = mail ($t,$s,$m,$f);
        if($success)    {
            $qs = "UPDATE users SET users.password = ".$this->db->escape($password)." WHERE users.id = ".intval($u['id']);
            $query = $this->db->query($qs);
            return 1;
        }
        else
            return 0;
    }

Edit:

I added a function called testemail() to one of my controllers to isolate CodeIgniter from the problem, and it seems to be working quite well.

#2
[eluser]darkhouse[/eluser]
Do you get an error, or you just don't get an email? Does $u['email'] actually contain an email address? If your get_user_by_username() function is returning an object, then you'd need to use $u->email. Other than that, it seems fine I think.

Actually, whoa. I think I see a flaw with how you're storing your passwords. It looks like you've reset someone's password to a 15 character string, but then you're storing the password in plain text. You should be using a hash, and furthermore, you should be using a salted hash.

$hash_password = md5($salt.md5($password.$salt));

Some people use $salt = $username, some people use $salt = substr(md5($password), 8), just as long as you can recreate the salt, you can recreate the hash to match when the user logs in. But it ends up being very difficult to crack.

#3
[eluser]Dave332[/eluser]
Thanks for your quick reply.

get_user_by_username() returns a db->query->row_array() result.

The problem I'm getting is that the mail() function returns false, and the password is never updated. I also do not receive an email.

The password is not actually stored as a string, but is hashed by another function (inside Usermodel::update() ), so I don't have to write hashing into every function that changes the password.

Edit: whoops, you're right, I forgot to hash the input in this function, thanks for catching that. Still doesn't get updated, though :-(

#4
[eluser]darkhouse[/eluser]
About the password hash, thanks for clarifying. I don't think I recommend ever storing a password in plain text in the database, even for a moment, I think you might want to rethink some programming structure. If you're worried about having a few functions running the same code to hash a password, they just create one function that updates a password, and call it instead of running that sql to store the plain text version first. That's just my recommendation.

However, that's off topic, sorry for the tangent. As for the mail returning false, I'm not sure why that is, but maybe try using the email library again, but use an SMTP server instead of the native mail function. After that, I think I'm out of suggestions.

#5
[eluser]Dave332[/eluser]
I was able to get the mail() function to work correctly inside my controller, but not inside my model for some reason. I reworked the mail() test script to sit inside a controller function, and it worked fine. Is there any reason that it would work in a controller but not inside a model?

#6
[eluser]darkhouse[/eluser]
I'm not sure why it wouldn't work in a model, I tend to do that sort of thing in a controller anyways, but if it's a native function, it should be available in all php scripts, regardless of what kind of file it is.

#7
[eluser]xwero[/eluser]
Is the email address the same in the form as in the model?

A solution that seems to be common is to add more headers.

#8
[eluser]Dave332[/eluser]
darkhouse, thanks again for all you help. I found the problem. Apparently, I screwed up get_user_by_username() by testing for a variable that was never passed. I guess that's what I get for using copy/paste to quickly duplicate similar function structures. As a result, I was attempting to access 0['email'] rather than a valid field, hence the failed emails.

#9
[eluser]darkhouse[/eluser]
Glad you sorted it out. One thing I do is echo everything, start with the obvious, and continue down the line until something doesn't echo properly. I asked if $u['email'] actually contained an email, it's one of the first things I would've echoed out. Anyways, glad you got it.


Digg   Delicious   Reddit   Facebook   Twitter   StumbleUpon  


  Theme © 2014 iAndrew  
Powered By MyBB, © 2002-2021 MyBB Group.