4 * This script will get mails and store it into forum DB
6 * Copyright 2004 GForge, LLC
8 * @author Tim Perdue tim@gforge.org
11 * This file is part of FusionForge. FusionForge is free software;
12 * you can redistribute it and/or modify it under the terms of the
13 * GNU General Public License as published by the Free Software
14 * Foundation; either version 2 of the Licence, or (at your option)
17 * FusionForge is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License along
23 * with FusionForge; if not, write to the Free Software Foundation, Inc.,
24 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 require dirname(__FILE__).'/../www/env.inc.php';
28 require_once $gfcommon.'include/pre.php';
29 require_once $gfcommon.'include/Group.class.php';
30 require_once $gfcommon.'include/MailParser.class.php';
31 require_once $gfcommon.'forum/Forum.class.php';
32 require_once $gfcommon.'forum/ForumMessage.class.php';
34 class ForumGateway extends Error {
54 function ForumGateway() {
57 /* Copy mail message to tmp file */
58 $tmpfile = $this->copyMailTmp();
59 //DBG("Tmpname: ". $tmpfile);
62 $ret = $this->parseMail($tmpfile);
64 /* Delete temp file */
67 /* Check the return variable from parseMail */
72 /* add the info to forum */
73 $ret = $this->addMessage();
83 * function - Copy mail(from stdin to tmp and return the tmp file
85 * @return tmp file name
87 function copyMailTmp() {
88 // Unfortunatly we need a temp file
89 // mailparse needs to read content several times
90 $tmpfile = tempnam ("/tmp", "forum_gateway.".util_randnum()."-".util_randnum());
91 $in = fopen("php://stdin", "r");
92 $out = fopen($tmpfile, "w");
94 while($buffer = fgets($in, 4096)) {
106 * function - Parse mail and fill all kinds of head and body info
108 * @param string tmp file name
109 * @return boolean true if success
111 function parseMail($input_file) {
113 //DBG("parseMail start");
115 if (!$mp = new MailParser($input_file)) {
116 $this->setError('Error In MailParser');
117 //DBG("parseMail error1: ".$mp->getErrorMessage());
119 } elseif ($mp->isError()) {
120 $this->setError('Error In MailParser '.$mp->getErrorMessage());
121 //DBG("parseMail error2: ".$mp->getErrorMessage());
122 // even if it is an error, try to get the address of the sender so we
123 // can send him back the error
124 $this->FromEmail = $mp->getFromEmail();
128 $this->FromEmail = $mp->getFromEmail();
129 //DBG("email: ".$this->FromEmail);
130 //echo ")()()()()()()".$this->FromEmail."(*(*(*(*(*";
132 //subjects are in this required format: '[group - Forum][123456] My Subject'
133 //where 123456 is the msg_id of the forum message.
134 //we parse that ID to get the forum and thread that this should post to
136 $subj = $mp->getSubject();
138 $this->setError($mp->getErrorMessage());
142 //DBG("mp headers: ".implode("**\n",$mp->headers));
143 //DBG("mp body: ".$mp->body);
144 //DBG("SUBJ: ".$subj);
145 //DBG("BODY: ".$mp->getBody());
147 $parent_start = (strpos($subj,'[',(strpos($subj,'[')+1))+1);
148 $parent_end = (strpos($subj,']',$parent_start)-1);
149 $this->Parent = substr($subj,$parent_start,($parent_end-$parent_start+1));
150 if (!$this->Parent || !is_numeric($this->Parent)) {
151 // $argv[1] - listname
152 // echo "No Parent ".$argv[0]."||".$argv[1];
154 $this->Subject = addslashes($subj);
155 // $this->setError('No Valid Parent ID Found in Subject Line');
158 // echo "Parent: ".$this->Parent."||".$argv[0]."||".$argv[1];
159 $this->Subject = addslashes(substr($subj,$parent_end+3));
162 if (preg_match('/(\[)([0-9]*)(\])/',$subj,$arr)) {
163 $this->Parent=$arr[2];
164 $parent_end=(strpos($subj,'['.$arr[2].']')) + strlen('['.$arr[2].']');
165 $this->Subject = substr($subj,$parent_end);
167 $this->Subject = $subj;
170 $this->Body =& $mp->getBody();
171 //DBG( "body1:". $this->Body);
173 $begin = strpos($this->Body, FORUM_MAIL_MARKER);
174 if ($begin === false) { //do nothing
177 // get the part of the message located after the marker
178 $this->Body = substr($this->Body, $begin+strlen(FORUM_MAIL_MARKER));
179 //DBG( "body2:". $this->Body);
180 // now look for the ending marker
181 $end = strpos($this->Body, FORUM_MAIL_MARKER);
182 if ($end === false) {
185 $message = substr($this->Body, 0, $end);
186 $message = trim($message);
188 // maybe the last line was "> (FORUM_MAIL_MARKER)". In that case, delete the last ">"
189 $message = preg_replace('/>$/', '', $message);
190 $this->Message = $message;
196 * Insert data into the forum db
198 * @return - true or false
200 function addMessage() {
204 $user_id = $this->getUserId();
207 // Set up this user's session before posting
209 session_set_new($user_id);
212 //DBG( "AddMessage 1\n");
213 $Forum =& $this->getForum();
214 if (!$Forum || !is_object($Forum)) {
215 $this->setError("Could Not Get Forum");
217 } elseif ($Forum->isError()) {
218 $this->setError("Forum Error: ".$Forum->getErrorMessage());
221 if (!$user_id && !$Forum->AllowAnonymous()) {
222 $this->setError("Could Not Match Sender Email Address to User and Forum Does Not Allow Anonymous Posts");
226 //DBG( "AddMessage 2\n");
228 // Create a blank forum message
230 $ForumMessage = new ForumMessage($Forum);
231 if (!$ForumMessage || !is_object($Forum)) {
232 $this->setError("Could Not Get Forum Message");
234 } elseif ($ForumMessage->isError()) {
235 $this->setError("ForumMessage Error: ".$ForumMessage->getErrorMessage());
238 //DBG( "AddMessage 3\n");
239 if ($this->Message!=""){
240 if (!$ForumMessage->create($this->Subject,$this->Message,$this->ThreadId,$this->Parent)) {
241 //DBG( "AddMessage 4.".$ForumMessage->getErrorMessage()."\n");
242 $this->setError("ForumMessage Create Error: ".$ForumMessage->getErrorMessage());
245 //DBG( "AddMessage 5.".$ForumMessage->getErrorMessage()."\n");
254 /*------------------------------------------------------------------------
256 *-----------------------------------------------------------------------*/
258 /* Find user_id from email */
259 function getUserId() {
260 // Find User id using email
261 $from = strtolower($this->FromEmail);
262 // If no user id, user id is 0;
263 if (! $from) return 0;
264 $res = db_query_params ('SELECT user_id FROM users
265 WHERE lower(email) = $1 AND status = $2',
266 array (strtolower($from),
268 if (!$res || db_numrows($res) < 1) {
271 $user_id = db_result($res,0,'user_id');
273 db_free_result($res);
278 function &getForum() {
281 if ($this->Forum==-1) {
282 $Group = group_get_object_by_name($argv[1]);
283 if (!$Group || !is_object($Group)) {
284 $this->setError('Could Not Get Group Object');
286 } elseif ($Group->isError()) {
287 $this->setError('Getting Group Object: '.$Group->getErrorMessage());
292 // Find Forum id by parent
294 $res = db_query_params ('SELECT group_forum_id,thread_id
297 array ($this->Parent));
300 // Find forum by arguments passed by aliases file
302 $res = db_query_params ('SELECT group_forum_id, 0 AS thread_id
303 FROM forum_group_list
309 if (!$res || db_numrows($res) < 1) {
310 $this->setError('Getting Forum IDs: '.db_error());
313 $this->ForumId = db_result($res,0,'group_forum_id');
314 $this->ThreadId = db_result($res,0,'thread_id');
315 db_free_result($res);
317 $this->Forum = new Forum($Group,$this->ForumId);
327 * Simple debugging printput
329 * Add this in /etc/syslog.conf and see /var/log/debug file:
331 * *.=debug /var/log/debug
337 file_put_contents('/tmp/forum.log', "forum: ".$str."\n", FILE_APPEND);
340 syslog(LOG_DEBUG, "forum_gateway: ". $str);
341 } else if ($debug==2) {
349 $listforum = new ForumGateway();
350 if ($listforum->isError()) {
351 mail ($listforum->FromEmail,'Forum Post Rejected',$listforum->getErrorMessage());
352 DBG('Final Message: '.$listforum->getErrorMessage());