<?php
require_once dirname(__FILE__) . '/accesscheck.php';

########################################################################
# Reads mail from a test account that will recieve all sent mail. 
# Use developer_email to send all mail to one account.
# Use test_email settings to pop this box.
# This file shows the links from the first email foun d for a selected user.
# The links can be use to for instance confirm the user in an automated test.
#
# 2007 Bas Ovink - tincan ltd
########################################################################

//CREATE TABLE `dev-phplist`.`phplist_testemail` (
//`id` int( 11 ) NOT NULL AUTO_INCREMENT ,
//`date` datetime default NULL ,
//`header` text,
//`data` blob,
//`status` varchar( 255 ) default NULL ,
//`comment` text,
//PRIMARY KEY ( `id` ) ,
//KEY `dateindex` ( `date` )
//) ENGINE = MYISAM DEFAULT CHARSET = latin1 AUTO_INCREMENT =34;

if (!$GLOBALS["commandline"]) {
  ob_end_flush();
  if (!MANUALLY_PROCESS_testS) {
    print $GLOBALS['I18N']->get("This page can only be called from the commandline");
    return;
  }
} else {
  ob_end_clean();
  print ClineSignature();
  ob_start();
}

function prepareOutput() {
  global $outputdone;
  if (!$outputdone) {
    $outputdone= 1;
    return formStart('name="outputform" class="readtestmailOutput" ') . '<textarea name="output" rows=10 cols=70></textarea></form>';
  }
}

$report= "";
## some general functions
function finish($flag, $message) {
  if ($flag == "error") {
    $subject= $GLOBALS['I18N']->get("test processing error");
  }
  elseif ($flag == "info") {
    $subject= $GLOBALS['I18N']->get("test Processing info");
  }
  if (!TEST && $message)
    sendReport($subject, $message);

  # try..catch
  global $link;
  imap_close($link);
}

function ProcessError($message) {
  output("$message");
  finish('error', $message);
  exit;
}

function processTestEmails_shutdown() {
  global $report, $process_id;
  releaseLock($process_id);
  # $report .= "Connection status:".connection_status();
  finish('info', $report);
  if (!$GLOBALS["commandline"]) {
    include_once dirname(__FILE__) . '/footer.inc';
  }
}

function output($message, $reset= 0) {
  $infostring= "[" . date("D j M Y H:i", time()) . "] [" . getenv("REMOTE_HOST") . "] [" . getenv("REMOTE_ADDR") . "]";
  #print "$infostring $message<br/>\n";
  $message= preg_replace("/\n/", '', $message);
  ## contribution from http://forums.phplist.com/viewtopic.php?p=14648
  ## in languages with accented characters replace the HTML back
  //Replace the "&rsquo;" which is not replaced by html_decode
  $message= preg_replace("/&rsquo;/", "'", $message);
  //Decode HTML chars
  #$message = html_entity_decode($message,ENT_QUOTES,$_SESSION['adminlanguage']['charset']);
  $message= html_entity_decode($message, ENT_QUOTES, 'UTF-8');
  if ($GLOBALS["commandline"]) {
    ob_end_clean();
    print strip_tags($message) . "\n";
    ob_start();
  } else {
    if ($reset)
      print '<script language="Javascript" type="text/javascript">
                                                                  //        if (document.forms[0].name == "outputform") {
                                                                            document.outputform.output.value = "";
                                                                            document.outputform.output.value += "\n";
                                                                  //        }
                                                                        </script>' . "\n";

    print '<script language="Javascript" type="text/javascript">
                                            //      if (document.forms[0].name == "outputform") {
                                                    document.outputform.output.value += "' . $message . '";
                                                    document.outputform.output.value += "\n";
                                            //      } else
                                            //        document.writeln("' . $message . '");
                                                </script>' . "\n";
  }

  flush();
}

//function processTestEmail($link, $mailIndex, $header) {
//  global $tables;
//  $headerinfo= imap_headerinfo($link, $mailIndex);
//  $header= imap_fetchheader($link, $mailIndex);
//
//  $body= imap_body($link, $mailIndex);
//  $msgid= 0;
//  $user= 0;
//  preg_match("/X-MessageId: (.*)/i", $header, $match);
//  if (is_array($match) && isset ($match[1]))
//    $msgid= trim($match[1]);
//  if (!$msgid) {
//    # older versions use X-Message
//    preg_match("/X-Message: (.*)/i", $header, $match);
//    if (is_array($match) && isset ($match[1]))
//      $msgid= trim($match[1]);
//  }
//
//  preg_match("/X-ListMember: (.*)/i", $header, $match);
//  if (is_array($match) && isset ($match[1]))
//    $user= trim($match[1]);
//  if (!$user) {
//    # older version use X-User
//    preg_match("/X-User: (.*)/i", $header, $match);
//    if (is_array($match) && isset ($match[1]))
//      $user= trim($match[1]);
//  }
//  # some versions used the email to identify the users, some the userid and others the uniqid
//  # use backward compatible way to find user
//  if (preg_match("/.*@.*/i", $user, $match)) {
//    $userid_req= Sql_Fetch_Row_Query("select id from {$tables["user"]} where email = \"$user\"");
//    if (VERBOSE)
//      output("UID" .
//      $userid_req[0] . " MSGID" . $msgid);
//    $userid= $userid_req[0];
//  }
//  elseif (preg_match("/^\d$/", $user)) {
//    $userid= $user;
//    if (VERBOSE)
//      output("UID" . $userid . " MSGID" . $msgid);
//  }
//  elseif ($user) {
//    $userid_req= Sql_Fetch_Row_Query("select id from {$tables["user"]} where uniqid = \"$user\"");
//    if (VERBOSE)
//      output("UID" . $userid_req[0] . " MSGID" . $msgid);
//    $userid= $userid_req[0];
//  } else {
//    $userid= '';
//  }
//  //  Sql_Query(sprintf('insert into %s (date,header,data)
//  //      values("%s","%s","%s")', 'phplist_testemail', date("Y-m-d H:i", @ strtotime($headerinfo->date)), addslashes($header), addslashes($body)));
//  //  $testid= Sql_Insert_id();
//  //  if ($userid) {
//  //    Sql_Query(sprintf('update %s
//  //          set status = "test system message",
//  //          comment = "userid %s"
//  //          where id = %d', 'phplist_testemail', $userid, $testid));
//  //  } else {
//  //    Sql_Query(sprintf('update %s
//  //          set status = "unidentified test",
//  //          comment = "not processed"
//  //          where id = %d', 'phplist_testemail', $testid));
//  //    return false;
//  //  }
//  dbg($userid, '$userid');
//  return true;
//}

function openPop($server, $user, $password) {
  $port= $GLOBALS["test_mailbox_port"];
  if (!$port) {
    $port= '110/pop3/notls';
  }
  set_time_limit(6000);

  if (!TEST) {
    $link= imap_open("{" . $server . ":" . $port . "}INBOX", $user, $password, CL_EXPUNGE);
  } else {
    $link= imap_open("{" . $server . ":" . $port . "}INBOX", $user, $password);
  }

  if (!$link) {
    output($GLOBALS['I18N']->get("Cannot create POP3 connection to") . " $server: " . imap_last_error());
    return null;
  }
  return $link;
}

function openMbox($file) {
  set_time_limit(6000);

  if (!TEST) {
    $link= imap_open($file, "", "", CL_EXPUNGE);
  } else {
    $link= imap_open($file, "", "");
  }
  if (!$link) {
    output($GLOBALS['I18N']->get("Cannot open mailbox file") . " " . imap_last_error());
    return null;
  }
  return $link;
}

function findEmailForUser($link, $mailToFind, $max= 3000) {
  global $test_mailbox_purge_unprocessed, $test_mailbox_purge;
  output(sprintf('Looking for emails to %s', $mailToFind));

  $num= imap_num_msg($link);
  output($num . " " . $GLOBALS['I18N']->get("mails in mailbox") . "\n");
  output($GLOBALS['I18N']->get("Please do not interrupt this process") . "\n");
  if ($num > $max) {
    print $GLOBALS['I18N']->get("Processing first") . " $max " . $GLOBALS['I18N']->get("tests") . "<br/>";
    $num= $max;
  }

  $nberror= 0;
  $found= false;
  $mailIndex= 0;
  while (!$found && $mailIndex++ <= $num) { //for ($x= 1; $x <= $num; $x++)
    set_time_limit(60);
    $header= imap_fetchheader($link, $mailIndex);
    preg_match("/X-ListMember: (.*)/i", $header, $match);
    
    if (is_array($match) && isset ($match[1]) ) {
      $match[1] = trim($match[1]);
      $found= $mailToFind == $match[1];
      if (!$found) {
        printf('<a href="?page=readtestmail&amp;email=%s">Get (& delete) %s</a><br />', $match[1], $match[1]);
      }
    }
    
    if ($found) {
      output('Message found');
      if (!TEST && $test_mailbox_purge) {
        output($GLOBALS['I18N']->get("Deleting message") . " $mailIndex");
        imap_delete($link, $mailIndex);
      }
    } else {
      if (!TEST && $test_mailbox_purge_unprocessed) {
        output($GLOBALS['I18N']->get("Deleting message") . " $mailIndex");
        imap_delete($link, $mailIndex);
      }
    }
    flush();
  }
  flush();
  output($GLOBALS['I18N']->get("Closing mailbox, and purging messages"));
  if ($found) {
    return $num;
  } else {
    return null;
  }
}

#############################################
# main
function main() {
};

if (!function_exists('imap_open')) {
  Error($GLOBALS['I18N']->get('IMAP is not included in your PHP installation, cannot continue') .
  '<br/>' . $GLOBALS['I18N']->get('Check out') .
  ' <a href="http://www.php.net/manual/en/ref.imap.php">http://www.php.net/manual/en/ref.imap.php</a>');
  return;
}

//print '<script language="Javascript" src="js/progressbar.js" type="text/javascript"></script>';
flush();
$outputdone= 0;

# lets not do this unless we do some locking first
register_shutdown_function('processTestEmails_shutdown');
$abort= ignore_user_abort(1);
$process_id= getPageLock();

if (!empty ($_REQUEST['email'])) {
  $mailToFind= $_REQUEST['email'];
  print prepareOutput();

  switch ($test_protocol) {
    case "pop" :
      $link= openPop($test_mailbox_host, $test_mailbox_user, $test_mailbox_password);
      break;
    case "mbox" :
      $link= openMbox($test_mailbox);
      break;
    default :
      Error($GLOBALS['I18N']->get("test_protocol not supported"));
      return;
  }

  if (isset ($link)) {
    $mailIndex= findEmailForUser($link, $mailToFind);
    if ( !is_null($mailIndex) ) {
      $body= imap_body($link, $mailIndex);
      $overview= imap_fetch_overview($link, $mailIndex);
      printf('Subject: %s<br />', $overview[0]->subject);
  
      preg_match_all("/<a(.*)href=[\"\'](.*)[\"\']([^>]*)>/Umis", $body, $links);
      foreach ($links[0] as $matchindex => $fullmatch) {
        preg_match('/p=(\w+)/', $fullmatch, $linkPages);
        printf('<a href="%s" id=%s>Link %s: %s</a><br />', $fullmatch, $matchindex++, $matchindex, $linkPages[1]);
      }

      preg_match_all('/http:\/\/\S+/', $body, $links);
      foreach ($links[0] as $matchindex => $fullmatch) {
        preg_match('/p=(\w+)/', $fullmatch, $linkPages);
        printf('<a href="%s" id=%s>Link %s: %s</a><br />', $fullmatch, $matchindex++, $matchindex, $linkPages[1]);
      }

    }
  }
}

{
  print ('<form method="get">');
  print ('  <input name="page" value="readtestmail" type="hidden" />');
  print ('  <input class="submit" type="submit" name="action" value="Get email for user: " />');
  printf('  <input type="text" name="email" value="%s" />', $_REQUEST['email']);
  print ('</form>');
}

if (!$GLOBALS["commandline"]) {
  print '<script language="Javascript" type="text/javascript"> finish(); </script>';
}
?>