Проблема с использованием функций PHP imap - PullRequest
0 голосов
/ 28 июля 2010

Я пытаюсь создать парсер сообщений электронной почты для нашего сайта.В конечном итоге я собираюсь перебирать сообщения, которые имеют вложения, и сохранять вложение, если сообщение приходит с определенного адреса электронной почты.

Это только начальный тест, однако у меня возникают проблемысм. комментарии ниже.

  <?php
  echo "Loading..."."<br />\n";
  $mailuser="help@mysite.com";

  echo "User=$mailuser"."<br />\n";;
  $mailpass="mypassword";
  echo "Pass=$mailpass"."<br />\n";
  // had to use this because we have SSL on site and regular port 110 didn't work
  $mailhost="{localhost:995/pop3/ssl/novalidate-cert}";
  echo "Host=$mailhost"."<br />\n";

  $mailbox=imap_open($mailhost,$mailuser,$mailpass) or die("<br />\nFAILLED! ".imap_last_error());
  $check = imap_check($mailbox);
  // last message parsed will be stored in the file msgcounter.dat
  $firstmsg = file_get_contents('msgcounter.dat') + 1;
  $lastmsg  = $firstmsg+$check->Recent; // should be == last msg index + count of latest messages
  echo 'First:'.$firstmsg.' - Last:'.$lastmsg."<br>";
  $result   = imap_fetch_overview($mailbox,"$firstmsg:$lastmsg");
  print_r($result);
  foreach ($result as $overview) {
    echo "#{$overview->msgno} ({$overview->date}) - From: {$overview->from}
    {$overview->subject}\n";
  }
  // the following approach didn't work either, Kept getting warnings about
  // Bad message number 
  //
  // Some messages in the sequence HAVE been deleted.
  /*
  for ($index = $firstmsg-1; $index <= ($lastmsg); $index++ ) {
    if (strlen(trim(imap_fetchheader($mailbox, $index))) > 0) { 
      echo 'in message index loop:'.$index;
    }
  }
  */
  imap_close($mailbox);
echo "completed.". "<br />\n";;
?>

Ответы [ 3 ]

0 голосов
/ 29 июля 2010

Хорошо, сейчас у меня есть большая часть того, что я пытаюсь сделать, работая. Единственная проблема, которую я оставил, - это перемещение сообщения в другую «папку». imap_mail_move не поддерживается в почтовых ящиках POP3, и я должен был придумать другой способ действий.

Последняя проблема, с которой я столкнулся, - это знать, какое сообщение FILE идет с тем сообщением, которое я только что открыл. Я знаю, что могу использовать функцию std rename () для перемещения файла, но я обнаружил, что могу найти msgnum в файле courierimapuiddb, и имя файла будет там.

Вот код, который я сейчас работаю, за исключением перемещения файла:

<?php

function showProgressMsg($msg)
{
  echo $msg."<br>";
  ob_flush();
 flush();
  usleep(2500);
}
  $mailpass="mymailpass";
  $mailhost="{localhost:995/pop3/ssl/novalidate-cert}";
  $mailuser="help@myserver.com";
  include "libs/database/db_mysql.php";
  $db = new Database;

  $debug=false;
  if($_GET['debug']= 'yes') {
    $debug = true;
    ini_set('output_buffering', 'Off');
    ob_start();
  }

  if($debug) {showProgressMsg('Opening Mailbox');}

  $mailbox=imap_open($mailhost,$mailuser,$mailpass) or die("<br />\nFAILLED! ".imap_last_error());

  // The IMAP.xml file contains the email address and user_id of the users that we accept 
  // their files via email 
  if($debug) {showProgressMsg('Reading IMAP.xml');}
  $xml = simplexml_load_string(file_get_contents('IMAP.xml'));
  $result = $xml->xpath('item');
  while(list( , $node) = each($result)) {
    $email   = $node->LI_email;
    $user_id = $node->LI_user_id;
    $search  = "RECENT FROM \"$email\"";

    if($debug) {showProgressMsg('Searching for '.$email);}
    $result2 = imap_search($mailbox, $search);
    if($result2) {
      $index = $result2[0];
      $structure = imap_fetchstructure($mailbox, $index);

      $attachments = array();
      if(isset($structure->parts) && count($structure->parts)) {
        if($debug) {showProgressMsg('Handling attachments');}
        for($i = 0; $i < count($structure->parts); $i++) {
          $attachments[$i] = array(
            'is_attachment' => false,
            'filename' => '',
            'name' => '',
            'attachment' => '');

          if($structure->parts[$i]->ifdparameters) {
            foreach($structure->parts[$i]->dparameters as $object) {
              if(strtolower($object->attribute) == 'filename') {
                $attachments[$i]['is_attachment'] = true;
                $attachments[$i]['filename'] = $object->value;
              }
            }
          }

          if($structure->parts[$i]->ifparameters) {
            foreach($structure->parts[$i]->parameters as $object) {
              if(strtolower($object->attribute) == 'name') {
                $attachments[$i]['is_attachment'] = true;
                $attachments[$i]['name'] = $object->value;
              }
            }
          }

          if($attachments[$i]['is_attachment']) {
            $attachments[$i]['attachment'] = imap_fetchbody($mailbox, $index, $i+1, FT_PEEK);
            if($structure->parts[$i]->encoding == 3) { // 3 = BASE64
              $attachments[$i]['attachment'] = base64_decode($attachments[$i]['attachment']);
            }
            elseif($structure->parts[$i]->encoding == 4) { // 4 = QUOTED-PRINTABLE
              $attachments[$i]['attachment'] = quoted_printable_decode($attachments[$i]['attachment']);
            }
          }             
        } // for($i = 0; $i < count($structure->parts); $i++)
      } // if(isset($structure->parts) && count($structure->parts))

      // Now add a record into the file_upload table
      for($i = 0; $i < count($attachments); $i++) {
        if (strlen(trim($attachments[$i]['filename'])) > 0) {
          $path_parts = pathinfo($attachments[$i]['filename']);
          if($debug) {showProgressMsg('Processing '.$attachments[$i]['filename']);}
          if(strtolower($path_parts['extension']) == 'zip') {
            // I am going to do something different with ziped files            
            $filename = 'file_uploads/temp/'.$user_id.'_'.$path_parts['filename'].'_'.date('m_d_Y').'.'.$path_parts['extension'];
            $fp = fopen($filename, "w");
            fwrite($fp, $attachments[$i]['attachment']);
            fclose($fp);                       
            $zip = new ZipArchive();
            if ($zip->open($filename) !== TRUE) {
              die ('Could not open archive');
            }
            $zippedfile = $zip->statIndex(0);
            $path_parts = pathinfo($zippedfile['name']);
            $newfilename = 'file_uploads/'.$user_id.'_'.$path_parts['filename'].'_'.date('m_d_Y').'.'.$path_parts['extension'];
            $zip->extractTo('file_uploads/', $zippedfile['name']);
            $zip->close();           
            unlink($filename);
            rename('file_uploads/'.$zippedfile['name'], $newfilename);
            $filestr = preg_replace('`[\r\n]+`',"\n", file_get_contents($newfilename));
            $fp = fopen($newfilename, "w+");
            fwrite($fp, $filestr);
            fclose($fp);                       
            // remove the directory from the filename
            $filename = $user_id.'_'.$path_parts['filename'].'_'.date('m_d_Y').'.'.$path_parts['extension'];
            // Now insert into file_upload table
            $insert_sql = "INSERT INTO `file_upload` VALUES(NULL,$user_id, '$filename', 0, NOW())";
            $db->query($insert_sql) or die("Can't insert record");
          } else {
            $filename = 'file_uploads/'.$user_id.'_'.$path_parts['filename'].'_'.date('m_d_Y').'.'.$path_parts['extension'];
            $fp = fopen($filename, "w");
            $attachments[$i]['attachment'] = preg_replace('`[\r\n]+`',"\n",$attachments[$i]['attachment']);
            fwrite($fp, $attachments[$i]['attachment']);
            fclose($fp);
            // remove the directory from the filename
            $filename = $user_id.'_'.$path_parts['filename'].'_'.date('m_d_Y').'.'.$path_parts['extension'];
            // Now insert into file_upload table
            $insert_sql = "INSERT INTO `file_upload` VALUES(NULL,$user_id, '$filename', 0, NOW())";
            $db->query($insert_sql) or die("Can't insert record:".mysql_error());
          }
        } // if (strlen(trim($attachments['name'])) > 0
      } // for($i = 0; $i < count($attachments); $i++)
      // Now move the message to completed uploads mailbox
      // imap_mail_move copies the message and then sets the deleted flag.
      // Found out that imap_mail_move is unsupported on POP3 accounts
      // imap_mail_move($mailbox, "$index", "INBOX/completed+uploads") or die("can't move: ".imap_last_error()); 

      // This is a stop gap to circumvent the message being processed twice
      // Found out that this also is not supported by POP3 boxes
      if($debug) {showProgressMsg('Setting \Seen flag');}
      imap_setflag_full($mailbox, "$index", "\Seen \Flagged");

      // This clears out the deleted messages
      // imap_expunge($mailbox);

      /*
        So, I'm going to have to open the courierimapuiddb file and locate the msgnum
        then get the filename and use rename() to move the file to the completed uploads 
        directory.
      */
    if($debug) {showProgressMsg(',oving message');}

    } // if($result2)
    // Now, move the message to completed uploads 
  } // while(list( , $node) = each($result))
  if($debug) {
    showProgressMsg('Closing mailbox and cleaning up');
    ob_flush();
    flush();
    ob_end_clean();
    ini_set('output_buffering', 4096);
  }
  imap_close($mailbox);  
?>
0 голосов
/ 12 ноября 2010

Проблема была в том, что я не проверял почтовый ящик imap в этой строке:

$mailhost="{localhost:995/pop3/ssl/novalidate-cert}";

Это правильная строка для использования:

$mailhost="{localhost/imap/ssl/novalidate-cert}";

0 голосов
/ 28 июля 2010

IMAP - это помойка плохих стандартов и худших реализаций.Если вы не возражаете против ненормативной лексики (или, ну, много), есть печально известная IMAP-рассылка от Ruby библиотеки dev с некоторыми интересными идеями.

Возможно, вам следует рассмотреть используя чужой код для грязной работы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...