phpDocumentor pond
[ class tree: pond ] [ index: pond ] [ all elements ]

Source for file getmail.php

Documentation is available at getmail.php

  1. <?php
  2. /**
  3.  * pop3-2-b2 mail to blog
  4.  *
  5.  * modified for b2evolution 2.4.1 by Stephan Knauss. Contact me by PM in {@link http://forums.b2evolution.net/} (user stephankn)
  6.  * or send a mail to stephankn at users.sourceforge.net
  7.  *
  8.  * Uses MIME E-mail message parser classes written by Manuel Lemos: {@link http://www.phpclasses.org/browse/package/3169.html}
  9.  *
  10.  * This script can be called with a parameter "test" to specify what
  11.  * should be done and what level of debug output to generate:
  12.  * <ul>
  13.  * <li>level 0: default. Process everything, no debug output, no html (called by cronjob)</li>
  14.  * <li>level 1: Test only connection to server, do not process messages</li>
  15.  * <li>level 2: additionally process messages, but do not post</li>
  16.  * <li>level 3: do everything with extended verbosity</li>
  17.  * </ul>
  18.  * Only messages for "level 0" should get marked for translation (using T_()).
  19.  *
  20.  * Quam Plures - {@link http://quamplures.net/}
  21.  * Released under GNU GPL License - {@link http://quamplures.net/license.html}
  22.  *
  23.  * @author Stephan Knauss
  24.  * @author tblue246: Tilman Blumenbach
  25.  *
  26.  * @copyright (c) 2009 - 2011 by the Quam Plures developers - {@link http://quamplures.net/}
  27.  * @copyright (c)2003-2009 by Francois PLANQUE - {@link http://fplanque.net/}
  28.  *  This file built upon code from original b2 - http://cafelog.com/
  29.  *
  30.  * @todo check different encodings. only tested with iso-8859-1
  31.  * @todo try more exotic email clients like mobile phones
  32.  * @todo tested and working with thunderbird (text, html, signed), yahoo mail (text, html), outlook webmail, K800i
  33.  * @todo Allow the user to choose whether to upload attachments to the blog media folder or to his user root.
  34.  *
  35.  * @package pond
  36.  */
  37.  
  38. /**
  39.  * load Quam Plures configuration
  40.  */
  41. require_once dirname__FILE__ '/../qp_config/_config.php';
  42. require_once $inc_path '_main.inc.php';
  43.  
  44. load_class('items/model/_itemlist.class.php');
  45. load_funcs('files/model/_file.funcs.php');
  46. load_class'_ext/mime_parser/rfc822_addresses.php' );
  47. load_class'_ext/mime_parser/mime_parser.php' );
  48.  
  49. if!$Settings->get'eblog_enabled' ) )
  50. {
  51.     echo T_'Blog by email feature is not enabled.' );
  52.     debug_info()// output debug info if requested
  53.     exit();
  54. }
  55.  
  56. param'test''integer');
  57.  
  58. /**
  59.  * Subject of the current email message
  60.  *
  61.  * @global string $subject 
  62.  */
  63. $subject '';
  64.  
  65. /**
  66.  * post date of current message
  67.  *
  68.  * @global string $post_date 
  69.  */
  70. $post_date '';
  71.  
  72. /**
  73.  * message content of current email that is going to be posted
  74.  *
  75.  * @global string $content 
  76.  */
  77. $content '';
  78.  
  79. /**#@+
  80.  * define colour constants for messages
  81.  */
  82. define'INFO''black' );
  83. define'SUCCESS''green' );
  84. define'WARNING''orange' );
  85. define'ERROR''red' );
  86. /**#@-*/
  87.  
  88. // if it's not called by a logged in user override test settings
  89. if!isset$current_User || !$current_User->check_perm'options''edit'true ) )
  90. {
  91.     $test 0;
  92. }
  93.  
  94. /**
  95.  * Whether to do real posting.
  96.  *
  97.  * It is set to true if the setting eblog_test_mode is set to false *and*
  98.  * the test parameter is not set to 2.
  99.  */
  100. $do_real_posting (!$Settings->get'eblog_test_mode' && $test != 2);
  101. if$do_real_posting )
  102. {
  103.     echo_messageT_('You configured test mode in the settings or set $test to 2. Nothing will be posted to the database/mediastore nor will your inbox be altered.')WARNING);
  104. }
  105.  
  106. if$test )
  107. {
  108.     //error_reporting (0);
  109.  
  110.     // TODO: I don't find a header to include for this popup window.
  111.     //    There should exist one in QP. So right now no valid HTML
  112.     $page_title T_'Blog by email' );
  113.     echo '<html><head><title>' $page_title '</title></head><body>';
  114. }
  115.  
  116. /**
  117.  * Print out a debugging message with optional HTML color added.
  118.  *
  119.  * This function only outputs any additional HTML (colors, <br />) if
  120.  * $test is greater than 0.
  121.  *
  122.  * @global integer The test level
  123.  * @param  string $strmessage The message to print
  124.  * @param  string $color optional colour so use
  125.  * @param  integer $level optional level to limit output to that level
  126.  */
  127. function echo_message$strmessage $color ''$level )
  128. {
  129.     global $test;
  130.  
  131.     if$level <= $test )
  132.     {
  133.         if$test && $color )
  134.         {
  135.             echo '<font color="'.$color.'">';
  136.         }
  137.  
  138.         echo $strmessage;
  139.  
  140.         if$test && $color )
  141.         {
  142.             echo '</font>';
  143.         }
  144.  
  145.         if$test )
  146.         {
  147.             echo '<br />';
  148.         }
  149.         echo "\n";
  150.     }
  151. }
  152.  
  153.  
  154. /**
  155.  * Provide sys_get_temp_dir for older versions of PHP (< 5.2.1).
  156.  *
  157.  * code posted on php.net by minghong at gmail dot com
  158.  * Based on {@link http://www.phpit.net/article/creating-zip-tar-archives-dynamically-php/2/}
  159.  *
  160.  * @return string path to system temporary directory
  161.  */
  162. if!function_exists'sys_get_temp_dir' ) )
  163. {
  164.     function sys_get_temp_dir()
  165.     {
  166.         // Try to get from environment variable
  167.         if!empty$_ENV['TMP') )
  168.         {
  169.             return realpath$_ENV['TMP');
  170.         }
  171.         else if!empty$_ENV['TMPDIR') )
  172.         {
  173.             return realpath$_ENV['TMPDIR');
  174.         }
  175.         else if!empty$_ENV['TEMP') )
  176.         {
  177.             return realpath$_ENV['TEMP');
  178.         }
  179.  
  180.         // Detect by creating a temporary file
  181.         else
  182.         {
  183.             // Try to use system's temporary directory
  184.             // as random name shouldn't exist
  185.             $temp_file tempnammd5uniqidrand()true ) )'' );
  186.             if$temp_file )
  187.             {
  188.                 $temp_dir realpathdirname$temp_file ) );
  189.                 unlink$temp_file );
  190.                 return $temp_dir;
  191.             }
  192.             else
  193.             {
  194.                 return false;
  195.             }
  196.         }
  197.     }
  198. }
  199.  
  200.  
  201. /**
  202.  * Create a new directory with unique name.
  203.  * This creates a new directory below the given path with the given prefix and a random number.
  204.  *
  205.  * @param  string $dir base path to new directory
  206.  * @param  string $prefix prefix random number with this
  207.  * @param  integer $mode permissions to use
  208.  * @return string path to created directory
  209.  */
  210. function tempdir$dir$prefix 'tmp'$mode 0700 )
  211. {
  212.     ifsubstr$dir-!= '/' $dir .= '/';
  213.  
  214.     do
  215.     {
  216.         $path $dir $prefix mt_rand();
  217.     while!mkdir$path$mode ) );
  218.  
  219.     return $path;
  220. }
  221.  
  222.  
  223.  
  224. /**
  225.  * Process Header information like subject and date of a mail.
  226.  *
  227.  * @global string The subject of the current message (write)
  228.  * @global string The post date of the current message (write)
  229.  * @global object QP settings (read)
  230.  * @global integer The test level (read)
  231.  * @param  array $header header as set by mime_parser_class::Analyze()
  232.  * @return bool true if valid subject prefix is detected
  233.  */
  234. function processHeader&$header )
  235. {
  236.     // write to these globals
  237.     global $subject$post_date;
  238.  
  239.     // read these globals
  240.     global $Settings$test;
  241.  
  242.     $subject $header['Subject'];
  243.     $ddate $header['Date'];
  244.  
  245.     $prefix $Settings->get'eblog_subject_prefix' );
  246.     echo_message'Subject: ' $subjectINFO);
  247.  
  248.     if(substr($subject0strlen($prefix)) !== $prefix)
  249.     {
  250.         echo_message'&#x2718; The subject prefix is not ' '"' $prefix '"'WARNING);
  251.         return false;
  252.     }
  253.  
  254.     // Parse Date.
  255.     // TODO: dh> use strftime (after format validation)? or strptime (PHP>=5.1.0)
  256.     // of the form '20 Mar 2002 20:32:37'
  257.     if(!preg_match('#^(.{3}, )?(\d{2}) (.{3}) (\d{4}) (\d{2}):(\d{2}):(\d{2})#'$ddate$match))
  258.     {
  259.         echo_message(T_('Could not parse date header!')ERROR0);
  260.         return false;
  261.     }
  262.  
  263.     $dmonths array(
  264.         'Jan' => 1,
  265.         'Feb' => 2,
  266.         'Mar' => 3,
  267.         'Apr' => 4,
  268.         'May' => 5,
  269.         'Jun' => 6,
  270.         'Jul' => 7,
  271.         'Aug' => 8,
  272.         'Sep' => 9,
  273.         'Oct' => 10,
  274.         'Nov' => 11,
  275.         'Dec' => 12,
  276.     );
  277.  
  278.     $ddate_H $match[5];
  279.     $ddate_i $match[6];
  280.     $ddate_s $match[7];
  281.  
  282.     ifisset$dmonths[$match[3]] ) )
  283.     {
  284.         echo_messageT_'Invalid month name in message date string.' )ERROR);
  285.         return false;
  286.     }
  287.     $ddate_m $dmonths[$match[3]];
  288.     $ddate_d $match[2];
  289.     $ddate_Y $match[4];
  290.  
  291.     $ddate_U mktime$ddate_H$ddate_i$ddate_s$ddate_m$ddate_d$ddate_Y );
  292.     $post_date date'Y-m-d H:i:s'$ddate_U );
  293.  
  294.     return true;
  295. }
  296.  
  297.  
  298.  
  299. /**
  300.  * process attachments by saving into media directory and optionally creating image tag in post
  301.  *
  302.  * @global string message content that is optionally manipulated by adding image tags
  303.  * @global bool do we really post?
  304.  * @global object global QP settings
  305.  * @param  array $mailAttachments array containing path to attachment files
  306.  * @param  string $mediadir path to media directory of blog as seen by file system
  307.  * @param  string $media_url url to media directory as seen by user
  308.  * @param  bool $add_img_tags should img tags be added (instead of adding a normal link)
  309.  * @return bool true for sucessfull execution
  310.  */
  311. function processAttachments$mailAttachments$mediadir$media_url$add_img_tags true )
  312. {
  313.     global $content;
  314.     global $do_real_posting;
  315.     global $Settings;
  316.  
  317.     $return true;
  318.  
  319.     echo_message'Processing attachments'INFO);
  320.  
  321.     foreach$mailAttachments as $attachment )
  322.     {
  323.         $filename strtolower$attachment['FileName');
  324.         if$filename == '' )
  325.         {
  326.             $filename tempnam$mediadir'upload' '.' $attachment['SubType'];
  327.             echo_message'&#x279C; ' sprintf('Attachment without name. Using "%s".'htmlspecialchars$filename ))WARNING);
  328.         }
  329.         $filename preg_replace'/[^a-z0-9\-_.]/''-'$filename );
  330.  
  331.         // Check valid filename/extension: (includes check for locked filenames)
  332.         if$error_filename validate_filename$filenamefalse ) )
  333.         {
  334.             echo_message'&#x2718; ' 'Invalid filename: '.$error_filenameWARNING);
  335.             $return false// return: at least one error. try with next attachment
  336.             continue;
  337.         }
  338.  
  339.         // if file exists count up a number
  340.         $cnt 0;
  341.         $prename substr$filename0strrpos$filename'.' ) ).'-';
  342.         $sufname strrchr$filename'.' );
  343.         whilefile_exists$mediadir $filename ) )
  344.         {
  345.             $filename $prename.$cnt.$sufname;
  346.             echo_message'&#x2718; file already exists. Changing filename to: ' $filename WARNING);
  347.             ++$cnt;
  348.         }
  349.  
  350.         if$do_real_posting )
  351.         {
  352.             echo_message'&#x279C; Saving file to: ' htmlspecialchars$mediadir $filename  )INFO);
  353.             if!rename$attachment['DataFile']$mediadir $filename ) )
  354.             {
  355.                 echo_message'&#x2718; Problem saving upload to ' htmlspecialchars$mediadir $filename )WARNING);
  356.                 $return false// return: at least one error. try with next attachment
  357.                 continue;
  358.             }
  359.  
  360.             // chmod uploaded file:
  361.             $chmod $Settings->get'fm_default_chmod_file' );
  362.             @chmod$mediadir $filenameoctdec$chmod ) );
  363.         }
  364.  
  365.         $imginfo @getimagesize($mediadir.$filename);
  366.         echo_message('Attachment is an image: '.(is_array($imginfoT_('yes'T_('no'))INFO);
  367.  
  368.         $content .= "\n";
  369.         if(is_array($imginfo&& $add_img_tags)
  370.         {
  371.             $content .= '<img src="'.$media_url.$filename.'" '.$imginfo[3].' />';
  372.         }
  373.         else
  374.         {
  375.             $content .= '<a href="'.$media_url.$filename.'">'.basename($filename).'</a>';
  376.         }
  377.         $content .= "\n";
  378.     }
  379.  
  380.     return $return;
  381. }
  382.  
  383. /**
  384.  * look inside message to get title for posting.
  385.  *
  386.  * The message could contain a xml-tag <code><title>sample title</title></code> to specify a title for the posting.
  387.  * If not tag is found there could be a global $post_default_title containing a global default title.
  388.  * If none of these is found then the specified alternate title line is used.
  389.  *
  390.  * @param string $content message to search for title tag
  391.  * @param string $alternate_title use this string if no title tag is found
  392.  * @return string title of posting
  393.  *
  394.  * @see $post_default_title
  395.  */
  396. function get_post_title$content$alternate_title )
  397. {
  398.     $title xmlrpc_getposttitle$content );
  399.     if$title == '' )
  400.     {
  401.         $title $alternate_title;
  402.     }
  403.  
  404.     return $title;
  405. }
  406.  
  407. ifextension_loaded'imap' ) )
  408. {
  409.     echo_messageT_'The php_imap extension is not available to PHP on this server. Please load it in php.ini or ask your hosting provider to do so.' )ERROR);
  410.     exit;
  411. }
  412. echo_message'Connecting and authenticating to mail server.'INFO);
  413.  
  414. /**
  415.  * Prepare the connection string.
  416.  */
  417. $mailserver '{' $Settings->get'eblog_server_host' ':' $Settings->get'eblog_server_port' );
  418. switch($Settings->get('eblog_encrypt'))
  419. {
  420.     case 'ssl':
  421.         $mailserver .= '/ssl';
  422.         break;
  423.     case 'tls':
  424.         $mailserver .= '/tls';
  425.         break;
  426.     case 'none':
  427.     default:
  428.         $mailserver .= '/notls';
  429.         break;
  430. }
  431. switch($Settings->get('eblog_method'))
  432. {
  433.     case 'pop3':
  434.     case 'pop3a':
  435.         $mailserver .= '/pop3';
  436.         break;
  437.     case 'imap':
  438.     default:
  439.         // imap needs no additional options
  440.         break;
  441. }
  442. if($Settings->get('eblog_novalidatecert'))
  443. {
  444.     $mailserver .= '/novalidate-cert';
  445. }
  446. $mailserver .= '}INBOX';
  447.  
  448. // Connect to mail server
  449. $mbox @imap_open$mailserver$Settings->get'eblog_username' )$Settings->get'eblog_password' ) );
  450. if$mbox )
  451. {
  452.     echo_messagesprintf/* TRANS: %s is the error message */ T_'Connection failed: %s' )imap_last_error())ERROR);
  453.     exit();
  454. }
  455. @imap_errors();
  456.  
  457. echo_message'&#x2714; Success'SUCCESS);
  458. if$test == )
  459. {
  460.     echo_message'All tests completed.'INFO);
  461.     imap_close$mbox );
  462.     exit();
  463. }
  464.  
  465.  
  466. // Read messages from server
  467. echo_message'Reading messages from server.'INFO);
  468. $imap_obj imap_check$mbox );
  469. echo_message' &#x279C; ' $imap_obj->Nmsgs ' ' 'messages'INFO);
  470.  
  471. $delMsgs 0;
  472. for $index 1$index <= $imap_obj->Nmsgs$index++ )
  473. {
  474.     echo_message'<strong>Message #' $index ':</strong>'INFO);
  475.  
  476.     $strbody '';
  477.     $hasAttachment false;
  478.  
  479.     // save mail to disk because with attachments could take up much RAM
  480.     if(!($tmpMIME tempnamsys_get_temp_dir()'b2evoMail' )))
  481.     {
  482.         echo_messageT_('Could not create temporary file.')ERROR);
  483.         continue;
  484.     }
  485.     imap_savebody$mbox$tmpMIME$index );
  486.  
  487.     $tmpDirMIME tempdirsys_get_temp_dir()'b2evo' );
  488.     $mimeParser new mime_parser_class;
  489.     $mimeParser->mbox 0// Set to 0 for parsing a single message file
  490.     $mimeParser->decode_bodies 1;
  491.     $mimeParser->ignore_syntax_errors 1;
  492.     $mimeParser->extract_addresses 0;
  493.     $MIMEparameters array(
  494.         'File' => $tmpMIME,
  495.         'SaveBody' => $tmpDirMIME// Save the message body parts to a directory
  496.         'SkipBody' => 1// Do not retrieve or save message body parts
  497.     );
  498.  
  499.     if!$mimeParser->Decode$MIMEparameters$decodedMIME ) )
  500.     {
  501.         echo_messagesprintf(T_('MIME message decoding error: %s at position %d.')$mimeParser->error$mimeParser->error_position)ERROR);
  502.         rmdir_r$tmpDirMIME );
  503.         unlink$tmpMIME );
  504.         continue;
  505.     }
  506.     else
  507.     {
  508.         echo_message'&#x2714; MIME message decoding successful.'INFO);
  509.         if$mimeParser->Analyze$decodedMIME[0]$parsedMIME ) )
  510.         {
  511.             echo_messagesprintf(T_('MIME message analyse error: %s')$mimeParser->error)ERROR);
  512.             rmdir_r$tmpDirMIME );
  513.             unlink$tmpMIME );
  514.             continue;
  515.         }
  516.  
  517.         if(!processHeader($parsedMIME))
  518.         {
  519.             rmdir_r$tmpDirMIME );
  520.             unlink($tmpMIME);
  521.             continue;
  522.         }
  523.  
  524.         // TODO: handle type == "message" recursively
  525.  
  526.         // mail is html
  527.         if$parsedMIME['Type'== 'html' ){
  528.             foreach $parsedMIME['Alternative'as $alternative ){
  529.                 if$alternative['Type'== 'text' ){
  530.                     echo_message'HTML alternative message part saved as ' $alternative['DataFile']INFO);
  531.                     $strbody imap_qprintfile_get_contents$alternative['DataFile') );
  532.                     break// stop after first alternative
  533.                 }
  534.             }
  535.         }
  536.  
  537.         // mail is plain text
  538.         elseif$parsedMIME['Type'== 'text' )
  539.         {
  540.             echo_message'Plain-text message part saved as ' $parsedMIME['DataFile']INFO);
  541.             $strbody imap_qprintfile_get_contents$parsedMIME['DataFile') );
  542.         }
  543.  
  544.         // Check for attachments
  545.         ifisset$parsedMIME['Attachments'&& count($parsedMIME['Attachments']) )
  546.         {
  547.             $hasAttachment true;
  548.             foreach$parsedMIME['Attachments'as $attachment )
  549.             {
  550.                 echo_message'Attachment: ' $attachment['FileName'' stored as ' $attachment['DataFile']INFO);
  551.             }
  552.         }
  553.  
  554.         $warning_count count$mimeParser->warnings );
  555.         if$warning_count )
  556.         {
  557.             echo_message'&#x2718; ' $warning_count ' warnings during decode: 'WARNING);
  558.             foreach ($mimeParser->warnings as $k => $v)
  559.             {
  560.                 echo_message'&#x2718; ' 'Warning: ' $v ' at position ' $kWARNING);
  561.             }
  562.         }
  563.     }
  564.     unlink$tmpMIME );
  565.  
  566.     // process body. First fix different line-endings (dos, mac, unix), remove double newlines
  567.     $strbody str_replacearray("\r""\n\n")"\n"$strbody );
  568.  
  569.     $a_body explode"\n"$strbody);
  570.  
  571.     // tblue> splitting only into 2 parts allows colons in the user PW
  572.     $a_authentication explode':'$a_body[0]);
  573.     $content trim$a_body[1);
  574.  
  575.     echo_message'Message content:' ' <code>' htmlspecialchars$content '</code>'INFO);
  576.  
  577.     $user_login trim$a_authentication[0);
  578.     // TODO: dh> should the password really get trimmed here?!
  579.     $user_pass = isset($a_authentication[1]trim($a_authentication[1]null;
  580.  
  581.     // authenticate user
  582.     echo_message'Authenticating user: ' $user_loginINFO);
  583.     if!user_pass_ok$user_login$user_pass ) )
  584.     {
  585.         echo_messagesprintf(T_'Authentication failed for user %s.' )htmlspecialchars($user_login))ERROR);
  586.         echo_message'&#x2718; Wrong login or password. First line of text in email must be in the format "username:password".'ERROR);
  587.         rmdir_r$tmpDirMIME );
  588.         continue;
  589.     }
  590.     else
  591.     {
  592.         echo_message'&#x2714; Success.'SUCCESS);
  593.     }
  594.  
  595.     $subject trimsubstr($subjectstrlen($Settings->get'eblog_subject_prefix' ))) );
  596.  
  597.     // remove content after terminator
  598.     $eblog_terminator $Settings->get'eblog_body_terminator' );
  599.     if!empty$eblog_terminator &&
  600.          ($os_terminator strpos$content$eblog_terminator )) !== false)
  601.     {
  602.         $content substr$content0$os_terminator );
  603.     }
  604.  
  605.     // check_html_sanity needs local user set.
  606.     $UserCache get_Cache'UserCache' );
  607.     $current_User $UserCache->get_by_login$user_login );
  608.  
  609.     $post_title get_post_title$content$subject );
  610.  
  611.     if$post_category xmlrpc_getpostcategory$content ) ) )
  612.     {
  613.         $post_category $Settings->get'eblog_default_category' );
  614.     }
  615.     echo_message'Category ID: ' htmlspecialchars$post_category )INFO);
  616.  
  617.     $content xmlrpc_removepostdata$content );
  618.     $blog_ID get_catblog$post_category )// TODO: should not die, if cat does not exist!
  619.     echo_message'Blog ID: ' $blog_IDINFO);
  620.  
  621.     $BlogCache get_Cache'BlogCache' );
  622.     $Blog $BlogCache->get_by_ID$blog_IDfalsefalse );
  623.  
  624.     ifempty$Blog ) )
  625.     {
  626.         echo_messagesprintfT_('Blog #%d not found!')$blog_ID )ERROR);
  627.         rmdir_r$tmpDirMIME );
  628.         continue;
  629.     }
  630.  
  631.  
  632.     // Check permission:
  633.     echo_messagesprintf'Checking permissions for user &laquo;%s&raquo; to post to Blog #%d'$user_login$blog_ID )INFO);
  634.     if!$current_User->check_perm'blog_post!published''edit'false$blog_ID )
  635.     || $hasAttachment && !$current_User->check_perm'files''add'false ) )
  636.     )
  637.     {
  638.         echo_messageT_'Permission denied.' )ERROR);
  639.         rmdir_r$tmpDirMIME );
  640.         continue;
  641.     }
  642.     else
  643.     {
  644.         echo_message'&#x2714; Pass.'SUCCESS);
  645.     }
  646.  
  647.     // handle attachments
  648.     if$hasAttachment )
  649.     {
  650.         $mediadir $Blog->get_media_dir();
  651.         if$mediadir )
  652.         {
  653.             processAttachments$parsedMIME['Attachments']$mediadir$Blog->get_media_url()$Settings->get('eblog_add_imgtag') );
  654.         }
  655.         else
  656.         {
  657.             echo_messageT_'Unable to access media directory. No attachments processed.' )ERROR);
  658.         }
  659.     }
  660.  
  661.     // CHECK and FORMAT content
  662.     $post_title check_html_sanitytrim$post_title )'posting'false );
  663.     $content check_html_sanitytrim$content )'posting'$Settings->get'AutoBR' ) );
  664.  
  665.     if( ( $error $Messages->get_stringT_'Cannot post, please correct these errors:' )'''error' ) ) )
  666.     {
  667.         echo_message$errorERROR);
  668.         $Messages->clear'error' );
  669.         rmdir_r$tmpDirMIME );
  670.         continue;
  671.     }
  672.  
  673.     if$do_real_posting )
  674.     {
  675.         // INSERT NEW POST INTO DB:
  676.         $edited_Item new Item();
  677.  
  678.         $post_ID $edited_Item->insert$current_User->ID$post_title$content$post_date$post_categoryarray()'published'$current_User->locale );
  679.  
  680.         // Execute or schedule notifications & pings:
  681.         $edited_Item->handle_post_processing();
  682.     }
  683.  
  684.     echo_message'&#x2714; Message posting successful.'SUCCESS);
  685.     echo_message'&#x279C; Post title: ' htmlspecialchars$post_title )INFO);
  686.     echo_message'&#x279C; Post content: ' htmlspecialchars$content )INFO);
  687.  
  688.     rmdir_r$tmpDirMIME );
  689.  
  690.     echo_message'Marking message for deletion: '.$indexINFO);
  691.     imap_delete$mbox$index );
  692.     ++$delMsgs;
  693. }
  694.  
  695. if$do_real_posting )
  696. {
  697.     imap_expunge$mbox );
  698.     echo_messagesprintf('Deleted %d processed message(s) from inbox.'$delMsgs)INFO);
  699. }
  700.  
  701. imap_close$mbox );
  702.  
  703. if$test )
  704. {
  705.     // TODO: I don't find a footer to include in this popup. QP should include one...
  706.     echo '</body>';
  707. }
  708.  
  709.  
  710. ?>