MailboxQueue.class.php (5628B)
1 <?php 2 3 require('./Queue.class.php'); 4 5 class MailboxQueue extends Queue 6 { 7 public $debug = false; 8 public $hostname = 'localhost'; 9 public $username = 'user'; 10 public $password = ''; 11 12 private $text; 13 private $html; 14 15 public function pull() 16 { 17 /* Verbindung zu Server */ 18 $inbox = imap_open($this->hostname,$this->username,$this->password) or die('Cannot connect to IMAP server: ' . imap_last_error()); 19 20 /* grab emails */ 21 $emails = imap_search($inbox,'ALL UNDELETED UNSEEN'); 22 23 if ($emails) 24 { 25 /* put the newest emails on top */ 26 rsort($emails); 27 28 $email_number = $email[0]; 29 30 /* get information specific to this email */ 31 // $overview = imap_fetch_overview($inbox,$email_number,0); 32 $headers = imap_headerinfo($inbox,$email_number); 33 $structure = imap_fetchstructure($inbox,$email_number); 34 // $message = imap_fetchbody($inbox,$email_number); 35 36 // echo "\nOverview:"; 37 // print_r($overview); 38 if ( $this->debug ) { echo '<pre>'; print_r($headers); echo '</pre>'; } 39 40 // Initalize 41 $this->filenames = array(); 42 $this->text = ''; 43 $this->html = ''; 44 $subject = iconv_mime_decode($headers->subject,0,'UTF-8'); 45 46 $s = imap_fetchstructure($inbox,$email_number); 47 48 if (!$s->parts) // simple 49 $this->getpart($inbox,$email_number,$s,0); // pass 0 as part-number 50 else { // multipart: cycle through each part 51 foreach ($s->parts as $partno0=>$p) 52 $this->getpart($inbox,$email_number,$p,$partno0+1); 53 } 54 55 // print_r($message); 56 /* output the email header information */ 57 // $output.= '<div class="toggler '.($overview[0]->seen ? 'read' : 'unread').'">'; 58 // $output.= '<span class="subject">'.$overview[0]->subject.'</span> '; 59 // $output.= '<span class="from">'.$overview[0]->from.'</span>'; 60 // $output.= '<span class="date">on '.$overview[0]->date.'</span>'; 61 // $output.= '</div>'; 62 63 /* output the email body */ 64 // $output.= '<div class="body">'.$message.'</div>'; 65 66 if ( $this->debug ) echo "\n\nBetreff: ".$subject; 67 if ( $this->debug ) echo "\n\nText: "; 68 if ( $this->debug ) print_r($this->text); 69 if ( $this->debug ) echo "\n\nAnlagen: "; 70 if ( $this->debug ) print_r($this->filenames); 71 72 $entrys[] = array( 73 'filenames'=> $this->filenames, 74 'keywords' => array(), 75 'timestamp' => strtotime($headers->date), 76 'subject' => $subject, 77 'text' => $this->text 78 ); 79 80 // Aufräumen: 81 // - Mail als gelesen markieren und in das Archiv verschieben. 82 if ( $this->config['dry'] ) 83 ; 84 else 85 { 86 imap_setflag_full($inbox,$email_number,'\\SEEN',0); 87 88 if (isset($this->config['archive_folder'])) 89 { 90 imap_mail_move($inbox,$email_number,$this->config['archive_folder']) or die("IMAP: Move did not suceed: "+imap_last_error() ); 91 92 imap_expunge($inbox); 93 } 94 } 95 } 96 97 /* close the connection */ 98 imap_close($inbox); 99 100 return $entrys; 101 } 102 103 104 105 private function getpart($mbox,$mid,$p,$partno) 106 { 107 // $partno = '1', '2', '2.1', '2.1.3', etc for multipart, 0 if simple 108 109 // DECODE DATA 110 $data = ($partno) ? 111 imap_fetchbody($mbox,$mid,$partno): // multipart 112 imap_body($mbox,$mid); // simple 113 114 // Any part may be encoded, even plain text messages, so check everything. 115 if ($p->encoding==4) 116 $data = quoted_printable_decode($data); 117 elseif ($p->encoding==3) 118 $data = base64_decode($data); 119 120 // PARAMETERS 121 // get all parameters, like charset, filenames of attachments, etc. 122 $params = array(); 123 if (@$p->parameters) 124 foreach ($p->parameters as $x) 125 $params[strtolower($x->attribute)] = $x->value; 126 if (@$p->dparameters) 127 foreach ($p->dparameters as $x) 128 $params[strtolower($x->attribute)] = $x->value; 129 130 // ATTACHMENT 131 // Any part with a filename is an attachment, 132 // so an attached text file (type 0) is not mistaken as the message. 133 if (@$params['filename'] || @$params['name']) { 134 // filename may be given as 'Filename' or 'Name' or both 135 $filename = ($params['filename'])? $params['filename'] : $params['name']; 136 // filename may be encoded, so see imap_mime_header_decode() 137 $fname = tempnam(null,'blog-file-'); 138 $file = fopen($fname,'w'); 139 fwrite($file,$data); 140 fclose($file); 141 chmod($fname,0644); 142 143 $this->filenames[] = array('filename'=>$fname,'name'=>$filename); 144 } 145 146 // TEXT 147 if ($p->type==0 && $data) { 148 $charset = $params['charset']; // assume all parts are same charset 149 $data = iconv($charset,'UTF-8//TRANSLIT',$data); 150 151 // Messages may be split in different parts because of inline attachments, 152 // so append parts together with blank row. 153 if (strtolower($p->subtype)=='plain') 154 $this->text.= trim($data) ."\n\n"; 155 else 156 $this->html.= $data ."<br><br>"; 157 } 158 159 // EMBEDDED MESSAGE 160 // Many bounce notifications embed the original message as type 2, 161 // but AOL uses type 1 (multipart), which is not handled here. 162 // There are no PHP functions to parse embedded messages, 163 // so this just appends the raw source to the main message. 164 elseif ($p->type==2 && $data) { 165 $this->text.= $data."\n\n"; 166 } 167 168 // SUBPART RECURSION 169 if (@$p->parts) { 170 foreach ($p->parts as $partno0=>$p2) 171 $this->getpart($mbox,$mid,$p2,$partno.'.'.($partno0+1)); // 1.2, 1.2.1, etc. 172 } 173 } 174 175 176 public function push( $entry ) 177 { 178 $headers = ''; 179 $headers .= 'Queue-Time: '.time()."\r\n"; 180 $headers .= 'Queue-User: '.get_current_user()."\r\n"; 181 $headers .= 'From: '.$this->from. "\r\n"; 182 $headers .= 'X-Mailer: MailboxQueue/PHP/' . phpversion(); 183 184 mail($this->receiver, $this->subject, json_encode($entry->value), $headers); 185 } 186 187 } 188 189 190 ?>