summaryrefslogtreecommitdiff
path: root/admin
diff options
context:
space:
mode:
authorTekimaki <tekimaki_admin@users.sourceforge.net>2008-11-29 17:46:30 +0000
committerTekimaki <tekimaki_admin@users.sourceforge.net>2008-11-29 17:46:30 +0000
commite762a31ad526551a74b5cc4456a87405e7e61660 (patch)
treeecadcb392155fee1f28cf6941c8b1c2d4c86f00f /admin
parent76403cfbcbafc30837336225310b3e8ebd50b50a (diff)
downloadboards-e762a31ad526551a74b5cc4456a87405e7e61660.tar.gz
boards-e762a31ad526551a74b5cc4456a87405e7e61660.tar.bz2
boards-e762a31ad526551a74b5cc4456a87405e7e61660.zip
Fix race condition in board syncing and a few other issues with moderation.
Diffstat (limited to 'admin')
-rw-r--r--admin/boardsync_cron.php375
-rw-r--r--admin/boardsync_inc.php398
2 files changed, 401 insertions, 372 deletions
diff --git a/admin/boardsync_cron.php b/admin/boardsync_cron.php
index 4c43cc1..f2eef74 100644
--- a/admin/boardsync_cron.php
+++ b/admin/boardsync_cron.php
@@ -1,380 +1,11 @@
<?php
-global $gShellScript, $gArgs;
+global $gShellScript, $gArgs, $gBitUser;
chdir( dirname( __FILE__ ) );
$gShellScript = TRUE;
//$gDebug = TRUE;
require_once( '../../bit_setup_inc.php' );
-$gBitUser->setPermission('p_users_bypass_captcha', TRUE);
+require_once( BOARDS_PKG_PATH.'admin/boardsync_inc.php');
-print '<pre>\n';
-
-$connectionString = '{'.$gBitSystem->getConfig('boards_sync_mail_server','imap').':'.$gBitSystem->getConfig('boards_sync_mail_port','993').'/'.$gBitSystem->getConfig('boards_sync_mail_protocol','imap').'/ssl/novalidate-cert}';
-
-// Can we open the mailbox?
-if( $mbox = imap_open( $connectionString, $gBitSystem->getConfig( 'boards_sync_user' ), $gBitSystem->getConfig( 'boards_sync_password' ) ) ) {
-
- $MC = imap_check($mbox);
-
- // Fetch an overview for all messages in INBOX of mailbox has messages
- if( $MC->Nmsgs ) {
- print($MC->Nmsgs);
- $result = imap_fetch_overview($mbox,"1:{$MC->Nmsgs}",0);
- if( $messageNumbers = imap_sort( $mbox, SORTDATE, 0 ) ) {
- foreach( $messageNumbers as $msgNum ) {
- print "Processing: ".$msgNum."\r\n";
- $deleteMsg = FALSE;
- $header = imap_headerinfo( $mbox, $msgNum );
-
- // Is this a moderation message?
- if( preg_match('/.*? post from .*? requires approval/', $header->subject) ) {
- print "Moderation Request.\r\n";
- // Fetch the original message
- $body = imap_fetchbody( $mbox, $msgNum, 2);
- $rawHeaders = board_sync_raw_headers($body);
- $replyBody = imap_fetchbody( $mbox, $msgNum, 3);
- $replyHeaders = board_sync_raw_headers($replyBody);
- $approveSubj = board_sync_get_header('Subject', $replyHeaders);
- $confirmCode = substr($approveSubj, strlen('confirm '));
- $deleteMsg = board_sync_process_message($mbox, $msgNum, $rawHeaders, imap_fetchstructure( $mbox, $msgNum, 2), $confirmCode);
- // Is this a reminder message that we just skip?
- } elseif( preg_match('/[0-9]+ .*? moderator request.* waiting/', $header->subject) ) {
- print "Deleting reminder.\r\n";
- $deleteMsg = TRUE;
- } else {
- $deleteMsg = board_sync_process_message( $mbox, $msgNum, imap_fetchheader( $mbox, $msgNum ), imap_fetchstructure( $mbox, $msgNum ) );
- // vd($deleteMsg);
- }
-
- if( $deleteMsg && empty( $gDebug ) && empty( $gArgs['test'] ) ) {
- // vd("DELETE!");
- imap_delete( $mbox, $msgNum );
- }
- }
- }
- }
-
- imap_expunge( $mbox );
- imap_close( $mbox );
-
-} else {
- bit_log_error( __FILE__." failed imap_open $connectionString ".imap_last_error() );
-}
-
-print '</pre>';
-
-function board_parse_msg_parts( &$pPartHash, $pMbox, $pMsgId, $pMsgPart, $pPartNum ) {
-
- //fetch part
- $part=imap_fetchbody( $pMbox, $pMsgId, $pPartNum);
- switch( $pMsgPart->encoding ) {
- case '3': // BASE64
- $part = base64_decode($part);
- break;
- case '4': // QUOTED-PRINTABLE
- $part = quoted_printable_decode($part);
- break;
- //0 7BIT
- //1 8BIT
- //2 BINARY
- //4 QUOTED-PRINTABLE
- //5 OTHER
- }
- switch( $pMsgPart->type ) {
- case '0':
- $pPartHash[$pPartNum][strtolower($pMsgPart->subtype)] = $part;
- break;
- default:
- // type is not text
- if( !preg_match( '/signature/i', $pMsgPart->subtype ) ) {
- //get filename of attachment if present
- $filename='';
- foreach( array( 'dparameters', 'parameters' ) as $prm ) {
- if( empty( $filename ) ) {
- // if there are any dparameters present in this part
- if( !empty($pMsgPart->$prm) && count( $pMsgPart->$prm ) > 0 ){
- foreach( $pMsgPart->$prm as $param ) {
- if( strtoupper( $param->attribute ) == 'NAME' || strtoupper( $param->attribute ) == 'FILENAME' ) {
- $filename = $param->value;
- }
- }
- }
- }
- }
- //write to disk and set pPartHash variable
- if( !empty( $filename ) ) {
- //where to write file attachments to
- srand( time() );
- $filestore = TEMP_PKG_PATH.BOARDS_PKG_NAME.'/boardsync/'.rand( 999, 999999999 ).'/'.$filename;
- mkdir_p( dirname( $filestore ) );
- $pPartHash[$pPartNum]['attachment'] = $filestore;
- $fp=fopen( $filestore, "w+" );
- fwrite( $fp, $part );
- fclose( $fp );
- }
- }
- break;
-
- }
-
- //if subparts... recurse into function and parse them too!
- if( !empty( $pMsgPart->parts ) ){
- foreach ($pMsgPart->parts as $pno=>$parr){
- board_parse_msg_parts( $pPartHash, $pMbox, $pMsgId, $parr, ( $pPartNum.'.'.( $pno + 1 ) ) );
- }
- }
-}
-
-function board_sync_get_user( $pFrom ) {
- global $gBitUser;
-
- if( preg_match_all('/[^<\s]+@[^>\s]+/', $pFrom, $matches) ) {
- foreach( $matches[0] as $email ) {
- $ret = $gBitUser->getUserInfo( array( 'email'=>$email ) );
- if( !empty($ret) ) {
- return $ret;
- }
- }
- }
-
- return $gBitUser->getUserInfo( array( 'user_id'=>-1 ) );
-}
-
-function cache_check_content_prefs( $pName, $pValue ) {
- global $gBitDb, $gBitSystem;
-
- $bindVars = array( $pName, $pValue );
-
- return $gBitDb->getOne( "SELECT `content_id` FROM `".BIT_DB_PREFIX."liberty_content_prefs` WHERE `pref_name`=? AND `pref_value`=?", $bindVars );
-}
-
-function board_sync_process_message( $pMbox, $pMsgNum, $pRawHeader, $pMsgStructure, $pModerate = FALSE ) {
- global $gBitSystem, $gBitDb;
-
- $sql = "SELECT `content_id` FROM `".BIT_DB_PREFIX."liberty_comments` WHERE `message_guid`=?";
-
- // Collect a bit of header information
- $message_id = board_sync_get_header('Message-Id', $pRawHeader);
- $subject = board_sync_get_header('Subject', $pRawHeader);
- print("Processing: ".$message_id."\n");
- print(" Subject: ".$subject."\n");
- // Do we already have this message?
- if( $message_id != NULL && !($contentId = $gBitDb->getOne( $sql, array( $message_id ) ) ) ) {
-
- $matches = array();
- $toAddresses = array();
- $allRecipients = '';
- $allRecipients = board_sync_get_header('To', $pRawHeader).','.
- board_sync_get_header('Cc', $pRawHeader);
-
- print "----$allRecipients----\n";
- $allSplit = split( ',', $allRecipients );
- foreach( $allSplit as $s ) {
- $s = trim( $s );
- $matches = array();
- if( strpos( $s, '<' ) !== FALSE ) {
- if( preg_match( "/\s*(.*)\s*<\s*(.*)\s*>/", $s, $matches ) ) {
- $toAddresses[] = array( 'name'=>$matches[1], 'email'=>$matches[2] );
- } elseif( preg_match('/<\s*(.*)\s*>\s*(.*)\s*/', $s, $matches) ) {
- $toAddresses[] = array( 'email'=>$matches[1], 'name'=>$matches[2] );
- }
- } elseif( validate_email_syntax( $s ) ) {
- $toAddresses[] = array( 'email'=>$s );
- }
- }
- print_r($toAddresses);
-
- $date = board_sync_get_header('Date', $pRawHeader);
- $fromaddress = board_sync_get_header('From', $pRawHeader);
- $toaddress = board_sync_get_header('To', $pRawHeader);
- $in_reply_to = board_sync_get_header('In-Reply-To', $pRawHeader);
-
- $personal = board_sync_get_personal($fromaddress);
-
- print( "\n---- ".date( "Y-m-d HH:mm:ss" )." -------------------------\nImporting: ".$message_id."\nDate: ".$date."\nFrom: ".$fromaddress."\nTo: ".$toaddress."\nSubject: ".$subject."\nIn Reply To: ".$in_reply_to."\nName: ".$personal."\n");
-
- foreach( $toAddresses AS $to ) {
- if( $boardContentId = cache_check_content_prefs( 'board_sync_list_address', $to['email'] ) ) {
- print "Found Board Content $boardContentId for $to[email]\n";
- if( !empty( $in_reply_to ) ) {
- if( $parent = $gBitDb->GetRow( "SELECT `content_id`, `root_id` FROM `".BIT_DB_PREFIX."liberty_comments` WHERE `message_guid`=?", array( $in_reply_to ) ) ) {
- $replyId = $parent['content_id'];
- $rootId = $parent['root_id'];
- } else {
- print ( "WARNING: Reply to unfound message: ".$in_reply_to );
- $replyId = $boardContentId;
- $rootId = $boardContentId;
- }
- } elseif( $parent = $gBitDb->GetRow( "SELECT lcom.`content_id`, lcom.`root_id` FROM `".BIT_DB_PREFIX."liberty_comments` lcom INNER JOIN `".BIT_DB_PREFIX."liberty_content` lc ON(lcom.`content_id`=lc.`content_id`) WHERE lc.`title`=?", array( preg_replace( '/re: /i', '', $subject ) ) ) ) {
- $replyId = $parent['content_id'];
- $rootId = $parent['root_id'];
- } else {
- $replyId = $boardContentId;
- $rootId = $boardContentId;
- }
- $userInfo = board_sync_get_user( $fromaddress );
- $storeRow = array();
- $storeRow['created'] = strtotime( $date );
- $storeRow['last_modified'] = $storeRow['created'];
- $storeRow['user_id'] = $userInfo['user_id'];
- $storeRow['modifier_user_id'] = $userInfo['user_id'];
- $storeRow['title'] = $subject;
- $storeRow['message_guid'] = $message_id;
- if( $userInfo['user_id'] == ANONYMOUS_USER_ID && !empty( $personal ) ) {
- $storeRow['anon_name'] = $personal;
- }
- $storeRow['root_id'] = $rootId;
- $storeRow['parent_id'] = $replyId;
-
- $partHash = array();
-
- switch( $pMsgStructure->type ) {
- case '0':
- board_parse_msg_parts( $partHash, $pMbox, $pMsgNum, $pMsgStructure, 1 );
- break;
- case '1':
- if ($pModerate) {
- $prefix = '2.';
- }
- else {
- $prefix = '';
- }
- foreach( $pMsgStructure->parts as $partNum => $part ) {
- board_parse_msg_parts( $partHash, $pMbox, $pMsgNum, $part, $prefix.($partNum+1) );
- }
- break;
- }
- $plainBody = NULL;
- $htmlBody = NULL;
-
- foreach( array_keys( $partHash ) as $i ) {
- if( !empty( $partHash[$i]['plain'] ) ) {
- $plainBody = $partHash[$i]['plain'];
- }
- if( !empty( $partHash[$i]['html'] ) ) {
- $htmlBody = $partHash[$i]['html'];
- }
- if( !empty( $partHash[$i]['attachment'] ) ) {
- $storeRow['_files_override'][] = array(
- 'tmp_name'=> $partHash[$i]['attachment'],
- 'type'=>$gBitSystem->verifyMimeType( $partHash[$i]['attachment'] ),
- 'size'=>filesize( $partHash[$i]['attachment'] ),
- 'name'=>basename( $partHash[$i]['attachment'] ) );
- }
- }
-
- if( !empty( $htmlBody ) ) {
- $storeRow['edit'] = $htmlBody;
- $storeRow['format_guid'] = 'bithtml';
- } elseif( !empty( $plainBody ) ) {
- $storeRow['edit'] = nl2br( $plainBody );
- $storeRow['format_guid'] = 'bithtml';
- }
-
- // Nuke all email addresses from the body.
- if( !empty($storeRow['edit']) ) {
- $storeRow['edit'] = ereg_replace(
- '[-!#$%&\`*+\\./0-9=?A-Z^_`a-z{|}~]+'.'@'.
- '(localhost|[-!$%&\'*+\\/0-9=?A-Z^_`a-z{|}~]+\.'.
- '[-!$%&\'*+\\./0-9=?A-Z^_`a-z{|}~]+)', '', $storeRow['edit'] );
- }
-
- // We trust the user from this source
- // and count on moderation to handle links
- global $gBitUser;
- $gBitUser->setPermission('p_liberty_trusted_editor', true);
-
- $storeComment = new LibertyComment( NULL );
- $gBitDb->StartTrans();
- if( $storeComment->storeComment($storeRow) ) {
- if( !$pModerate && $gBitSystem->isPackageActive('moderation') && $gBitSystem->isPackageActive('modcomments') ) {
- global $gModerationSystem, $gBitUser;
- $moderation = $gModerationSystem->getModeration(NULL, $storeComment->mContentId);
- // Allow to moderate
- $gBitUser->setPermission('p_admin', TRUE);
- $gModerationSystem->setModerationReply($moderation['moderation_id'], MODERATION_APPROVED);
- $gBitUser->setPermission('p_admin', FALSE);
- }
-
- $storeComment->mDb->query( "UPDATE `".BIT_DB_PREFIX."liberty_comments` SET `message_guid`=? WHERE `content_id`=?", array( $storeRow['message_guid'], $storeComment->mContentId ) );
-
- if(!$pModerate && $gBitSystem->isPackageActive('bitboards') && $gBitSystem->isFeatureActive('bitboards_thread_track')) {
- $topicId = substr( $storeComment->mInfo['thread_forward_sequence'], 0, 10 );
- $data = BitBoardTopic::getNotificationData( $topicId );
- foreach ($data['users'] as $login => $user) {
- if( $data['topic']->mInfo['llc_last_modified'] > $user['track_date'] && $data['topic']->mInfo['llc_last_modified']>$user['track_notify_date']) {
- $data['topic']->sendNotification($user);
- }
- }
- }
-
- // Store the confirm code
- if( $pModerate ) {
- $storeComment->storePreference('board_confirm_code', $pModerate);
- }
- $gBitDb->CompleteTrans();
- return TRUE;
- } else {
- if( $storeComment->mErrors['store'] == 'Duplicate comment.' ) {
- return TRUE;
- } else {
- $gBitDb->RollbackTrans();
- // vd( $storeComment->mErrors );
- return FALSE;
- }
- }
- }
- }
- }
- else {
- print "Exists: $contentId\n";
- // If this isn't a moderation message
- if( !$pModerate ) {
- // If the message exists it must have been approved via some
- // moderation mechanism, so make sure it is available
- if( $gBitSystem->isPackageActive('moderation') && $gBitSystem->isPackageActive('modcomments') ) {
- global $gModerationSystem, $gBitUser;
- print( "Setting approved: $contentId" );
-
- $moderation = $gModerationSystem->getModeration(NULL, $contentId);
- // vd($moderation);
-
- if( !empty($moderation) ) {
- $gBitUser->setPermission('p_admin', TRUE);
- $gModerationSystem->setModerationReply($mod['moderation_id'], MODERATION_APPROVED);
- $gBitUser->setPermission('p_admin', FALSE);
- }
- }
- } else {
- print( "WARNING: Message \"".$subject."\" Exists -> ".BIT_ROOT_URI."index.php?content_id=".$contentId."\n" );
- }
- return TRUE;
- }
-}
-
-function board_sync_raw_headers($body) {
- $matches = preg_split('/^\s*$/ms', $body, 2);
- return $matches[0];
-}
-
-function board_sync_get_header($header, $body) {
- $ret = NULL;
- preg_match( '/^'.$header.':\s*(.*?)\s*$/m', $body, $matches);
- if (!empty($matches[1])) {
- $ret = $matches[1];
- }
- return $ret;
-}
-
-function board_sync_get_personal($pEmail) {
- preg_match( '/<.*?@.*?>\s*(.+?)\s*|(.+?)\s*<.*?@.*?>|<\s*(.+?)\s*>\s*.*@.*\s*|.*@.*\s*<\s*(.+?)\s*>/', $pEmail, $matches);
- if( !empty($matches) ) {
- for( $i=1; $i<count($matches); $i++ ) {
- if( !empty($matches[$i]) ) {
- return $matches[$i];
- }
- }
- }
- return NULL;
-} \ No newline at end of file
+board_sync_run(TRUE);
diff --git a/admin/boardsync_inc.php b/admin/boardsync_inc.php
new file mode 100644
index 0000000..31ead0e
--- /dev/null
+++ b/admin/boardsync_inc.php
@@ -0,0 +1,398 @@
+<?php
+
+function board_sync_run($pLog = FALSE) {
+ global $gBitUser, $gBitSystem;
+
+ $gBitUser->setPermissionOverride('p_users_bypass_captcha', TRUE);
+
+ $connectionString = '{'.$gBitSystem->getConfig('boards_sync_mail_server','imap').':'.$gBitSystem->getConfig('boards_sync_mail_port','993').'/'.$gBitSystem->getConfig('boards_sync_mail_protocol','imap').'/ssl/novalidate-cert}';
+
+ // Can we open the mailbox?
+ if( $mbox = imap_open( $connectionString, $gBitSystem->getConfig( 'boards_sync_user' ), $gBitSystem->getConfig( 'boards_sync_password' ) ) ) {
+
+ $MC = imap_check($mbox);
+
+ // Fetch an overview for all messages in INBOX of mailbox has messages
+ if( $MC->Nmsgs ) {
+ // print($MC->Nmsgs);
+ $result = imap_fetch_overview($mbox,"1:{$MC->Nmsgs}",0);
+ if( $messageNumbers = imap_sort( $mbox, SORTDATE, 0 ) ) {
+ foreach( $messageNumbers as $msgNum ) {
+ if ($pLog) print "Processing: ".$msgNum."\r\n";
+ $deleteMsg = FALSE;
+ $header = imap_headerinfo( $mbox, $msgNum );
+
+ // Is this a moderation message?
+ if( preg_match('/.*? post from .*? requires approval/', $header->subject) ) {
+ if ($pLog) print "Moderation Request.\r\n";
+ // Fetch the original message
+ $body = imap_fetchbody( $mbox, $msgNum, 2);
+ $rawHeaders = board_sync_raw_headers($body);
+ $replyBody = imap_fetchbody( $mbox, $msgNum, 3);
+ $replyHeaders = board_sync_raw_headers($replyBody);
+ $approveSubj = board_sync_get_header('Subject', $replyHeaders);
+ $confirmCode = substr($approveSubj, strlen('confirm '));
+ if ($pLog) print "Confirm code: ".$confirmCode."\r\n";
+ $deleteMsg = board_sync_process_message($mbox, $msgNum, $rawHeaders, imap_fetchstructure( $mbox, $msgNum, 2), $confirmCode, $pLog);
+ // Is this a reminder message that we just skip?
+ } elseif( preg_match('/[0-9]+ .*? moderator request.* waiting/', $header->subject) ) {
+ if ($pLog) print "Deleting reminder.\r\n";
+ $deleteMsg = TRUE;
+ } elseif( preg_match('/Welcome to the .* mailing list/', $header->subject) ) {
+ if ($pLog) print "Deleting welcome message.\r\n";
+ $deleteMsg = TRUE;
+ } else {
+ $deleteMsg = board_sync_process_message( $mbox, $msgNum, imap_fetchheader( $mbox, $msgNum ), imap_fetchstructure( $mbox, $msgNum ) , FALSE, $pLog);
+ // vd($deleteMsg);
+ }
+ if( $deleteMsg && empty( $gDebug ) && empty( $gArgs['test'] ) ) {
+ // vd("DELETE!");
+ if ($pLog) print "Deleted msg $msgNum\r\n";
+ imap_delete( $mbox, $msgNum );
+ }
+ }
+ }
+ }
+
+ imap_expunge( $mbox );
+ imap_close( $mbox );
+
+ } else {
+ bit_log_error( __FILE__." failed imap_open $connectionString ".imap_last_error() );
+ }
+
+}
+
+function board_parse_msg_parts( &$pPartHash, $pMbox, $pMsgId, $pMsgPart, $pPartNum ) {
+
+ //fetch part
+ $part=imap_fetchbody( $pMbox, $pMsgId, $pPartNum);
+ switch( $pMsgPart->encoding ) {
+ case '3': // BASE64
+ $part = base64_decode($part);
+ break;
+ case '4': // QUOTED-PRINTABLE
+ $part = quoted_printable_decode($part);
+ break;
+ //0 7BIT
+ //1 8BIT
+ //2 BINARY
+ //4 QUOTED-PRINTABLE
+ //5 OTHER
+ }
+ switch( $pMsgPart->type ) {
+ case '0':
+ $pPartHash[$pPartNum][strtolower($pMsgPart->subtype)] = $part;
+ break;
+ default:
+ // type is not text
+ if( !preg_match( '/signature/i', $pMsgPart->subtype ) ) {
+ //get filename of attachment if present
+ $filename='';
+ foreach( array( 'dparameters', 'parameters' ) as $prm ) {
+ if( empty( $filename ) ) {
+ // if there are any dparameters present in this part
+ if( !empty($pMsgPart->$prm) && count( $pMsgPart->$prm ) > 0 ){
+ foreach( $pMsgPart->$prm as $param ) {
+ if( strtoupper( $param->attribute ) == 'NAME' || strtoupper( $param->attribute ) == 'FILENAME' ) {
+ $filename = $param->value;
+ }
+ }
+ }
+ }
+ }
+ //write to disk and set pPartHash variable
+ if( !empty( $filename ) ) {
+ //where to write file attachments to
+ srand( time() );
+ $filestore = TEMP_PKG_PATH.BOARDS_PKG_NAME.'/boardsync/'.rand( 999, 999999999 ).'/'.$filename;
+ mkdir_p( dirname( $filestore ) );
+ $pPartHash[$pPartNum]['attachment'] = $filestore;
+ $fp=fopen( $filestore, "w+" );
+ fwrite( $fp, $part );
+ fclose( $fp );
+ }
+ }
+ break;
+
+ }
+
+ //if subparts... recurse into function and parse them too!
+ if( !empty( $pMsgPart->parts ) ){
+ foreach ($pMsgPart->parts as $pno=>$parr){
+ board_parse_msg_parts( $pPartHash, $pMbox, $pMsgId, $parr, ( $pPartNum.'.'.( $pno + 1 ) ) );
+ }
+ }
+}
+
+function board_sync_get_user( $pFrom ) {
+ global $gBitUser;
+
+ if( preg_match_all('/[^<\s]+@[^>\s]+/', $pFrom, $matches) ) {
+ foreach( $matches[0] as $email ) {
+ $ret = $gBitUser->getUserInfo( array( 'email'=>$email ) );
+ if( !empty($ret) ) {
+ return $ret;
+ }
+ }
+ }
+
+ return $gBitUser->getUserInfo( array( 'user_id'=>-1 ) );
+}
+
+function cache_check_content_prefs( $pName, $pValue ) {
+ global $gBitDb, $gBitSystem;
+
+ $bindVars = array( $pName, $pValue );
+
+ return $gBitDb->getOne( "SELECT `content_id` FROM `".BIT_DB_PREFIX."liberty_content_prefs` WHERE `pref_name`=? AND `pref_value`=?", $bindVars );
+}
+
+function board_sync_process_message( $pMbox, $pMsgNum, $pRawHeader, $pMsgStructure, $pModerate = FALSE , $pLog) {
+ global $gBitSystem, $gBitDb;
+
+ // Collect a bit of header information
+ $message_id = board_sync_get_header('Message-ID', $pRawHeader);
+ if( empty($message_id) ) {
+ $message_id = board_sync_get_header('Message-Id', $pRawHeader);
+ }
+ $subject = board_sync_get_header('Subject', $pRawHeader);
+ print("Processing: ".$message_id."\n");
+ print(" Subject: ".$subject."\n");
+ // Do we already have this message?
+ $contentId = NULL;
+ if( $message_id != NULL ) {
+ $sql = "SELECT `content_id` FROM `".BIT_DB_PREFIX."liberty_comments` WHERE `message_guid`=?";
+ $contentId = $gBitDb->getOne( $sql, array( $message_id ) );
+ }
+ print "Message Content Id is: " . $contentId . "\r\n";
+ if( empty($contentId) ) {
+
+ $matches = array();
+ $toAddresses = array();
+ $allRecipients = '';
+ $allRecipients = board_sync_get_header('To', $pRawHeader).','.
+ board_sync_get_header('Cc', $pRawHeader);
+
+ // print " ---- $allRecipients ----\n";
+ $allSplit = split( ',', $allRecipients );
+ foreach( $allSplit as $s ) {
+ $s = trim( $s );
+ $matches = array();
+ if( strpos( $s, '<' ) !== FALSE ) {
+ if( preg_match( "/\s*(.*)\s*<\s*(.*)\s*>/", $s, $matches ) ) {
+ $toAddresses[] = array( 'name'=>$matches[1], 'email'=>$matches[2] );
+ } elseif( preg_match('/<\s*(.*)\s*>\s*(.*)\s*/', $s, $matches) ) {
+ $toAddresses[] = array( 'email'=>$matches[1], 'name'=>$matches[2] );
+ }
+ } elseif( validate_email_syntax( $s ) ) {
+ $toAddresses[] = array( 'email'=>$s );
+ }
+ }
+ // print_r($toAddresses);
+
+ $date = board_sync_get_header('Date', $pRawHeader);
+ $fromaddress = board_sync_get_header('From', $pRawHeader);
+ $toaddress = board_sync_get_header('To', $pRawHeader);
+ $in_reply_to = board_sync_get_header('In-Reply-To', $pRawHeader);
+
+ $personal = board_sync_get_personal($fromaddress);
+
+ print( "\n---- ".date( "Y-m-d HH:mm:ss" )." -------------------------\nImporting: ".$message_id."\nDate: ".$date."\nFrom: ".$fromaddress."\nTo: ".$toaddress."\nSubject: ".$subject."\nIn Reply To: ".$in_reply_to."\nName: ".$personal."\n");
+
+ foreach( $toAddresses AS $to ) {
+ if( $boardContentId = cache_check_content_prefs( 'board_sync_list_address', $to['email'] ) ) {
+ print "Found Board Content $boardContentId for $to[email]\n";
+ if( !empty( $in_reply_to ) ) {
+ if( $parent = $gBitDb->GetRow( "SELECT `content_id`, `root_id` FROM `".BIT_DB_PREFIX."liberty_comments` WHERE `message_guid`=?", array( $in_reply_to ) ) ) {
+ $replyId = $parent['content_id'];
+ $rootId = $parent['root_id'];
+ } else {
+ print ( "WARNING: Reply to unfound message: ".$in_reply_to );
+ $replyId = $boardContentId;
+ $rootId = $boardContentId;
+ }
+ } elseif( $parent = $gBitDb->GetRow( "SELECT lcom.`content_id`, lcom.`root_id` FROM `".BIT_DB_PREFIX."liberty_comments` lcom INNER JOIN `".BIT_DB_PREFIX."liberty_content` lc ON(lcom.`content_id`=lc.`content_id`) WHERE lc.`title`=?", array( preg_replace( '/re: /i', '', $subject ) ) ) ) {
+ $replyId = $parent['content_id'];
+ $rootId = $parent['root_id'];
+ } else {
+ $replyId = $boardContentId;
+ $rootId = $boardContentId;
+ }
+ $userInfo = board_sync_get_user( $fromaddress );
+ $storeRow = array();
+ $storeRow['created'] = strtotime( $date );
+ $storeRow['last_modified'] = $storeRow['created'];
+ $storeRow['user_id'] = $userInfo['user_id'];
+ $storeRow['modifier_user_id'] = $userInfo['user_id'];
+ $storeRow['title'] = $subject;
+ $storeRow['message_guid'] = $message_id;
+ if( $userInfo['user_id'] == ANONYMOUS_USER_ID && !empty( $personal ) ) {
+ $storeRow['anon_name'] = $personal;
+ }
+ $storeRow['root_id'] = $rootId;
+ $storeRow['parent_id'] = $replyId;
+
+ $partHash = array();
+
+ switch( $pMsgStructure->type ) {
+ case '0':
+ board_parse_msg_parts( $partHash, $pMbox, $pMsgNum, $pMsgStructure, 1 );
+ break;
+ case '1':
+ if ($pModerate) {
+ $prefix = '2.';
+ }
+ else {
+ $prefix = '';
+ }
+ foreach( $pMsgStructure->parts as $partNum => $part ) {
+ board_parse_msg_parts( $partHash, $pMbox, $pMsgNum, $part, $prefix.($partNum+1) );
+ }
+ break;
+ }
+ $plainBody = NULL;
+ $htmlBody = NULL;
+
+ foreach( array_keys( $partHash ) as $i ) {
+ if( !empty( $partHash[$i]['plain'] ) ) {
+ $plainBody = $partHash[$i]['plain'];
+ }
+ if( !empty( $partHash[$i]['html'] ) ) {
+ $htmlBody = $partHash[$i]['html'];
+ }
+ if( !empty( $partHash[$i]['attachment'] ) ) {
+ $storeRow['_files_override'][] = array(
+ 'tmp_name'=> $partHash[$i]['attachment'],
+ 'type'=>$gBitSystem->verifyMimeType( $partHash[$i]['attachment'] ),
+ 'size'=>filesize( $partHash[$i]['attachment'] ),
+ 'name'=>basename( $partHash[$i]['attachment'] ) );
+ }
+ }
+
+ if( !empty( $htmlBody ) ) {
+ $storeRow['edit'] = $htmlBody;
+ $storeRow['format_guid'] = 'bithtml';
+ } elseif( !empty( $plainBody ) ) {
+ $storeRow['edit'] = nl2br( $plainBody );
+ $storeRow['format_guid'] = 'bithtml';
+ }
+
+ // Nuke all email addresses from the body.
+ if( !empty($storeRow['edit']) ) {
+ $storeRow['edit'] = ereg_replace(
+ '[-!#$%&\`*+\\./0-9=?A-Z^_`a-z{|}~]+'.'@'.
+ '(localhost|[-!$%&\'*+\\/0-9=?A-Z^_`a-z{|}~]+\.'.
+ '[-!$%&\'*+\\./0-9=?A-Z^_`a-z{|}~]+)', '', $storeRow['edit'] );
+ }
+
+ // We trust the user from this source
+ // and count on moderation to handle links
+ global $gBitUser;
+ $gBitUser->setPermissionOverride('p_liberty_trusted_editor', true);
+
+ $storeComment = new LibertyComment( NULL );
+ $gBitDb->StartTrans();
+ if( $storeComment->storeComment($storeRow) ) {
+ if( !$pModerate && $gBitSystem->isPackageActive('moderation') && $gBitSystem->isPackageActive('modcomments') ) {
+ global $gModerationSystem, $gBitUser;
+ $moderation = $gModerationSystem->getModeration(NULL, $storeComment->mContentId);
+ // Allow to moderate
+ $gBitUser->setPermissionOverride('p_admin', TRUE);
+ $gModerationSystem->setModerationReply($moderation['moderation_id'], MODERATION_APPROVED);
+ $gBitUser->setPermissionOverride('p_admin', FALSE);
+ }
+
+ $storeComment->mDb->query( "UPDATE `".BIT_DB_PREFIX."liberty_comments` SET `message_guid`=? WHERE `content_id`=?", array( $storeRow['message_guid'], $storeComment->mContentId ) );
+
+ if(!$pModerate && $gBitSystem->isPackageActive('bitboards') && $gBitSystem->isFeatureActive('bitboards_thread_track')) {
+ $topicId = substr( $storeComment->mInfo['thread_forward_sequence'], 0, 10 );
+ $data = BitBoardTopic::getNotificationData( $topicId );
+ foreach ($data['users'] as $login => $user) {
+ if( $data['topic']->mInfo['llc_last_modified'] > $user['track_date'] && $data['topic']->mInfo['llc_last_modified']>$user['track_notify_date']) {
+ $data['topic']->sendNotification($user);
+ }
+ }
+ }
+
+ // Store the confirm code
+ if( $pModerate ) {
+ $storeComment->storePreference('board_confirm_code', $pModerate);
+ }
+ $gBitDb->CompleteTrans();
+ return TRUE;
+ } else {
+ if( $storeComment->mErrors['store'] == 'Duplicate comment.' ) {
+ return TRUE;
+ } else {
+ $gBitDb->RollbackTrans();
+ // vd( $storeComment->mErrors );
+ return FALSE;
+ }
+ }
+ }
+ }
+ } elseif ( !empty($contentId) ) {
+ print "Exists: $contentId : $message_id : $pModerate\n";
+ // If this isn't a moderation message
+ if( $pModerate === FALSE ) {
+ // If the message exists it must have been approved via some
+ // moderation mechanism, so make sure it is available
+ if( $gBitSystem->isPackageActive('moderation') && $gBitSystem->isPackageActive('modcomments') ) {
+ global $gModerationSystem, $gBitUser;
+ $storeComment = new LibertyComment( NULL, $contentId );
+ $storeComment->loadComment();
+ if ($storeComment->mInfo['content_status_id'] > 0) {
+ if ($pLog) print "Already approved: $contentId\r\n";
+ } else {
+ $moderation = $gModerationSystem->getModeration(NULL, $contentId);
+ // vd($moderation);
+ if( !empty($moderation) ) {
+ $gBitUser->setPermissionOverride('p_admin', TRUE);
+ if ($pLog) print( "Setting approved: $contentId\n" );
+ $gModerationSystem->setModerationReply($moderation['moderation_id'], MODERATION_APPROVED);
+ $gBitUser->setPermissionOverride('p_admin', FALSE);
+ if ($pLog) print "Done";
+ } else {
+ if ($pLog) print "ERROR: Unable to find moderation to approve for: $contentId";
+ }
+ }
+ }
+ } else {
+ // Store the approve code;
+ print "Storing approval code: " . $contentId . ":" . $pModerate . "\r\n";
+ $storeComment = new LibertyComment( NULL, $contentId );
+ $storeComment->storePreference('board_confirm_code', $pModerate);
+ }
+ return TRUE;
+ } else {
+ print( "WARNING: Message \"".$subject."\" couldn't find message id header." );
+ }
+ return FALSE;
+}
+
+function board_sync_raw_headers($body) {
+ $matches = preg_split('/^\s*$/ms', $body, 2);
+ return $matches[0];
+}
+
+function board_sync_get_header($header, $body) {
+ $ret = NULL;
+ preg_match( '/^'.$header.':\s*(.*?)\s*$/m', $body, $matches);
+ if (!empty($matches[1])) {
+ $ret = $matches[1];
+ }
+ return $ret;
+}
+
+function board_sync_get_personal($pEmail) {
+ preg_match( '/<.*?@.*?>\s*(.+?)\s*|(.+?)\s*<.*?@.*?>|<\s*(.+?)\s*>\s*.*@.*\s*|.*@.*\s*<\s*(.+?)\s*>/', $pEmail, $matches);
+ if( !empty($matches) ) {
+ for( $i=1; $i<count($matches); $i++ ) {
+ if( !empty($matches[$i]) ) {
+ return $matches[$i];
+ }
+ }
+ }
+ return NULL;
+} \ No newline at end of file