Page 2 of 3

Posted: Wed Aug 24, 2005 8:44 am
by AGISB
If you run PHP as cgi or cli its easy to read mail directly from sendmail. Here is a nice tutorial.

http://www.evolt.org/article/Incoming_M ... /18/27914/

Posted: Wed Aug 24, 2005 8:44 am
by Grim...
I'll share - it's not very well commented though.

When you say 'webmail based programs', do you mean will it accept the pictures if sent by (say) yahoo? Yes, it will.

Here's the code:

Code: Select all

<?php

$nouid = 1; //this just allows the common file to run without a user being logged in
include ("inc/common.php");


$mbox = imap_open ("{localhost:110/pop3}INBOX", "username@lonford.com", "password");


$check = imap_check($mbox);

$num = $check->Nmsgs;


if (!$mid)
{
    exit; //no need to do anything if there are no emails
}
for ($mid = 1; $mid <= $num; $mid++) //loop through mails
{

    $struct = imap_fetchstructure($mbox, $mid); //get mail (I got this lot from the php documentation)

    $parts = $struct->parts;
    $i = 0;

    if (!$parts) { /* Simple message, only 1 piece */
     $attachment = array(); /* No attachments */
     $content = imap_body($mbox, $mid);
    } else { /* Complicated message, multiple parts */

     $endwhile = false;

     $stack = array(); /* Stack while parsing message */
     $content = "";    /* Content of message */
     $attachment = array(); /* Attachments */

     while (!$endwhile) {
       if (!$parts[$i]) {
         if (count($stack) > 0) {
           $parts = $stack[count($stack)-1]["p"];
           $i    = $stack[count($stack)-1]["i"] + 1;
           array_pop($stack);
         } else {
           $endwhile = true;
         }
       }

       if (!$endwhile) {
         /* Create message part first (example '1.2.3') */
         $partstring = "";
         foreach ($stack as $s) {
           $partstring .= ($s["i"]+1) . ".";
         }
         $partstring .= ($i+1);

         if (strtoupper($parts[$i]->disposition) == "ATTACHMENT") { /* Attachment */
           $attachment[] = array("filename" => $parts[$i]->parameters[0]->value,
                                 "filedata" => imap_fetchbody($mbox, $mid, $partstring));
         } elseif (strtoupper($parts[$i]->subtype) == "PLAIN") { /* Message */
           $content .= imap_fetchbody($mbox, $mid, $partstring);
         }
       }

       if ($parts[$i]->parts) {
         $stack[] = array("p" => $parts, "i" => $i);
         $parts = $parts[$i]->parts;
         $i = 0;
       } else {
         $i++;
       }
     } /* while */
    } /* complicated message */


    $header = imap_header($mbox, $mid);
    $from = $header->from;
    foreach ($from as $id => $object) {
       $fromname = $object->personal;
       $fromaddress = $object->mailbox . "@" . $object->host;
    }

    if (count($attachment) > 0) //I don't care about the email if it doesn't have an attachment...
    {
        //there is an image attached -- carry on

        $subject = $header->subject; //this will form the title and description for the image, seperated by '---'

        $td = explode ("---", $subject);

        $title = addslashes($td[0]);
        $desc = addslashes($td[1]);

        $tags = maketags (strtolower($content)); //tags are descriptive keywords for the image, and are send with the image in the body of the email

        foreach ($attachment AS $at)
        {
            $filename = $at[filename];
            $filedata = $at[filedata];
        }

        
        //figure the users ID from the email address the mail was recieved from (userid = uid)
        $result=mysql_query("SELECT * FROM ".$tp."user WHERE strEmailFrom = '$fromaddress'");
        $my_select ++;
        while ( $a_row = mysql_fetch_object( $result ) )
        {
            $uid = $a_row->intId;
        }        
        
        if (!$uid)
        {
            $uid = 3; // <-- me
        }

        //save file into a temp directory

        $path = $_SERVER["DOCUMENT_ROOT"]."/lonford/images/";

        $temp_path = $path."temp/";
        $original_path = $path."user/";
        $cutdown_path = $path."user/cutdown/";
        $thumbnail_path = $path."user/tn/";

        //upload file to temp directory
        $filedata = imap_base64($filedata);

        $fp=fopen($temp_path.$uid.$filename,"w+");
        fwrite($fp,$filedata);
        fclose($fp);  
        
        //now do the rest (this is stuff for my site - it takes the original image, sizes it down to 1024x768 (if it has to))...
        $oldfilename = $filename;
        $file_name = $uid."_".$filename;
        $dup = 0;

        while (file_exists($cutdown_path.$file_name)) //check for a duplicate file on the server
        {
            $result=mysql_query("SELECT * FROM ".$tp."photos WHERE strName = '$file_name'");
            $my_select ++;
            while ( $a_row = mysql_fetch_object( $result ) )
            {
                $dup = $a_row->intId;
            }
            $file_name = $uid."_".rand (0, 1000).$file_name; //give this file a new filename
        }

        if (substr($file_name, -3) != "jpg") //only allow .jpg files
        {
            unlink ($temp_path.$uid.$oldfilename);
            continue;
        }
        
        //create a thumbnail
        $src_name = $temp_path.$uid.$oldfilename;
        $dest_name = $thumbnail_path.$file_name;       
        $src = imagecreatefromjpeg($src_name);

        $image_width = imagesx($src);
        $image_height = imagesy($src);        
        $w = 100;
        $h = 76;

        $dest = @imagecreatetruecolor($w,$h);

        imagecopyresized($dest, $src, 0, 0, 0, 0, $w, $h, imagesx($src), imagesy($src));        
        imagejpeg($dest, $dest_name, 60);
        imagedestroy($dest);     

        //resize from uploaded size to 1024x768 (if you need to)
        
        if ($image_width > 1024 OR $image_height > 768)
        {
            //figure new sizes
            if ($image_width > $image_height)
            {
                $calc = $image_width / 1024;
                $w = 1024;
                $h = ceil($image_height / $calc);
            }
            else
            {
                $calc = $image_height / 768;
                $h = 768;
                $w = ceil($image_width / $calc);
                
                $dest = @imagecreatetruecolor($w,$h);
                $dest_name = $original_path.$file_name;

                imagecopyresized($dest, $src, 0, 0, 0, 0, $w, $h, imagesx($src), imagesy($src));        
                imagejpeg($dest, $dest_name, 100);
                imagedestroy($dest);                
            }
        }
        else
        {
            //width and height remain unchanged - we don't upload a large image
        }
        

        
        //resize to 640x480 for note viewing etc. (notes are user-definable areas of the image that have notes on them)
        if ($image_width > 640 OR $image_height > 480)
        {
            //figure new sizes
            if ($image_width > $image_height)
            {
                $calc = $image_width / 640;
                $w = 640;
                $h = ceil($image_height / $calc);
            }
            else
            {
                $calc = $image_height / 480;
                $h = 480;
                $w = ceil($image_width / $calc);
            }
        }
        else
        {
            //width and height remain unchanged
            $w = $image_width;
            $h = $image_height;
        }
        
        $dest = @imagecreatetruecolor($w,$h);
        
        imagecopyresized($dest, $src, 0, 0, 0, 0, $w, $h, imagesx($src), imagesy($src));
        $dest_name = $cutdown_path.$file_name;
        imagejpeg($dest, $dest_name, 75);
        imagedestroy($dest);        
        
        //finish, kill the source images
        imagedestroy($src);
        unlink ($temp_path.$uid.$oldfilename);
        
        //add the shizzle to the database
        if (file_exists("images/user/cutdown/".$file_name))
        {
            if (!$title)
            {
                $title = substr($oldfilename, 0, -4); //use the filename as the title if the sender didn't provide one
            }
            
            $query = "INSERT INTO ".$tp."photos ( strName, strDesc, intDate, strTitle, intOwner) values( '$file_name', '$desc', '$epoch', '$title', '$uid')";
            mysql_query( $query, $link ) or die ( "My SQL Error:<br><i>$query</i><br><b>".mysql_error() );
            $my_insert ++;
            $pid = mysql_insert_id();

            $sid .= "-".$pid;

            for ($i = 0; $i < count($tags); $i++) 
            {
                //make sure the tag isn't already there (possible if they added the same tag twice)
                $result=mysql_query("SELECT * FROM ".$tp."tags WHERE intObjectId = '$pid' AND strObjectType = 'photo' AND strText = '$tags[$i]'");
                $my_select ++;
                if (mysql_num_rows( $result ))
                {
                    continue;
                }        

                $query = "INSERT INTO ".$tp."tags (intObjectId, strObjectType, strText, intAuthor) values('$pid', 'photo',  '$tags[$i]', '$uid')";
                $my_insert ++;
                mysql_query( $query, $link ) or die ( "My SQL Error:<br><i>$query</i><br><b>".mysql_error() );
            }
            //some people like to know when a new photo is added to the site
            $result=mysql_query("SELECT * FROM ".$tp."user WHERE intId != '$uid' AND intEmailPhoto = 1");
            $my_select ++;
            while ( $a_row = mysql_fetch_object( $result ) )
            {
                $message = "
Hi $a_row->strName,

You wanted an email when someone uploaded a new photo onto Lonford.

Well, someone just has. Take a look:
http://www.lonford.co.uk/

Cheers,
Lonford Admin System";

                email ($a_row->strEmail, "[Lonford] New Photo(s) Online!", $message);
            }            

        }        
        

    }
    
    //delete message
    
    imap_delete($mbox, $mid);
}

imap_close($mbox);
       
?>

Posted: Wed Aug 24, 2005 8:49 am
by Grim...
Wardy7 wrote:I could pay you for it if you like?
http://www.amazon.co.uk/exec/obidos/reg ... 11-6505441

;)

Posted: Wed Aug 24, 2005 8:53 am
by Wardy7
Thanks loads matey. I'll take a look through that all now and try get my head round it :D
Can't believe you just knocked all that up, hope you find good use for it too?!

Cheers
Wardy

Posted: Wed Aug 24, 2005 8:56 am
by Grim...
Um... I was more interested in seeing if I could ;)

Posted: Wed Aug 24, 2005 9:09 am
by JayBird
Grim... wrote:Um... I was more interested in seeing if I could ;)
Thought you are supposed o be getting married today?! :lol:

Posted: Wed Aug 24, 2005 9:20 am
by Wardy7
Grim... wrote:Um... I was more interested in seeing if I could ;)
Oh right, thanks :D
Hopefully the postman will drop you a small something in the next few days.:)

Just looking through the code now to see what to make of it all. Not the best of coders so takes me a while to figure it all out, such as what needs changing, where things need putting etc. :oops:

Cheers
Wardy

Posted: Wed Aug 24, 2005 9:29 am
by Grim...
Pimptastic wrote: Thought you are supposed o be getting married today?! :lol:
Not until later :)

Posted: Wed Aug 24, 2005 9:30 am
by Grim...
Wardy7 wrote:Hopefully the postman will drop you a small something in the next few days.:)
Neat!

If you've got any questions, ask them before 17:30 GMT, as I have to go and get wed.

Posted: Wed Aug 24, 2005 9:32 am
by feyd
ahh, the dedication nerds, dorks and geeks have to their click-worlds, even on their wedding day! Impressive, and yet scary and sad all at once. ;) :P

Posted: Wed Aug 24, 2005 9:36 am
by Wardy7
Oh wow, congratulations.:D
Create a new project in the morning and get wed in the evening, imagine if every day was like that :wink:

OK, just some simple question then hopefully if that is OK?!

Code: Select all

include ("inc/common.php");
Does this mean that the page I have this php code on is called common.php?

This page just needs uploading to www folder?

Cheers
Wardy

Posted: Wed Aug 24, 2005 9:39 am
by Grim...
No, that common page just contains things I use on every page - functions, database connections, etc.

The page can be called, and placed, anywhere you like, but you'll need to change the paths (where the images will be stored) and probably lots of other things, too.

Posted: Wed Aug 24, 2005 9:47 am
by Wardy7
Yeh sorry, just realise that about it being a include file after I posted, told you I was slow...:(

Um, what do I need to change on this,

Code: Select all

$mbox = imap_open ("{localhost:110/pop3}INBOX", "username@mydomain.com", "password");
I have changed the email and password that I woudl use to log into the webmail account for my domain, I just dont' know what to change the localhost:110/pop3 thing to to make it work.
Also what would I put if I was trying to log into say a yahoo email?

Cheers
Wardy

Posted: Wed Aug 24, 2005 9:50 am
by Grim...
Hmm...
If the email you wish to read is going to the same server (and works on pop3) as the code is hosted on, that should work fine.

If not, most other eventualities are covered here: http://uk.php.net/imap_open

Posted: Wed Aug 24, 2005 9:51 am
by Grim...
Php Manual wrote:$mbox = imap_open( "{yourmailserver.com/pop3:110/notls}INBOX", "username", "password" );