4 * This script will get mails and store it into artifact DB
6 * Copyright 2004 GForge, LLC
7 * Copyright 2009, Roland Mas
9 * @author Tim Perdue tim@gforge.org
11 * @author Francisco Gimeno <kikov@kikov.org>
13 * This file is part of GForge.
15 * GForge is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
20 * GForge is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public License
26 * along with GForge; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 * This file is based on forum_gateway.php
32 require dirname(__FILE__).'/../www/env.inc.php';
33 require_once $gfcommon.'include/pre.php';
34 require_once $gfcommon.'include/Group.class.php';
35 require_once $gfcommon.'include/MailParser.class.php';
36 require_once $gfcommon.'tracker/Artifact.class.php';
37 require_once $gfcommon.'tracker/ArtifactFactory.class.php';
39 class TrackerGateway extends Error {
56 function TrackerGateway() {
59 /* Copy mail message to tmp file */
60 $tmpfile = $this->copyMailTmp();
61 //DBG("Tmpname: ". $tmpfile);
64 $ret = $this->parseMail($tmpfile);
66 /* Delete temp file */
69 /* Check the return variable from parseMail */
74 /* add the info to tracker */
75 $ret = $this->addMessage();
84 * function - Copy mail(from stdin to tmp and return the tmp file
86 * @return tmp file name
88 function copyMailTmp() {
89 // Unfortunatly we need a temp file
90 // mailparse needs to read content several times
91 $tmpfile = tempnam ("/tmp", "artifact_gateway.".rand()."-".rand());
92 $in = fopen("php://stdin", "r");
93 $out = fopen($tmpfile, "w");
95 while($buffer = fgets($in, 4096)) {
107 * function - Parse mail and fill all kinds of head and body info
109 * @param string tmp file name
110 * @return boolean true if success
112 function parseMail($input_file) {
115 if (!$mp = new MailParser($input_file)) {
116 $this->setError('Error In MailParser');
118 } elseif ($mp->isError()) {
119 $this->setError('Error In MailParser '.$mp->getErrorMessage());
120 // even if it is an error, try to get the address of the sender so we
121 // can send him back the error
122 $this->FromEmail = $mp->getFromEmail();
126 $this->FromEmail = $mp->getFromEmail();
128 //subjects are in this required format: '[group - tracker_name][123456] My Subject'
129 //where 123456 is the artifact_id of the artifact message.
130 //we parse that ID to get the artifact that this should post to
132 $subj = $mp->getSubject();
133 if (preg_match('/(\[)([0-9]*)(\])/',$subj,$arr)) {
134 $this->ArtifactId=$arr[2];
135 $artifactid_end=(strpos($subj,'['.$arr[2].']')) + strlen('['.$arr[2].']');
136 $this->Subject = addslashes(substr($subj,$artifactid_end));
138 $this->FromEmail = ''; // Do not reply if no pattern found.
139 $this->Subject = addslashes($subj);
140 $this->ArtifactId=0; // Not supported at the moment
141 $this->setError("ArtifactId needed at the moment. Artifact creation not supported");
145 $body = $mp->getBody();
146 // find first occurrence of the marker in the message
147 $begin = strpos($body, ARTIFACT_MAIL_MARKER);
148 if ($begin === false) {
149 $this->setError("Response message wasn't found in your mail. Please verify that ".
150 "you entered your message between the correct text markers.".
151 "\nYour message was:".
152 "\n".$mp->getBody());
155 // get the part of the message located after the marker
156 $body = substr($body, $begin+strlen(ARTIFACT_MAIL_MARKER));
157 // now look for the ending marker
158 $end = strpos($body, ARTIFACT_MAIL_MARKER);
159 if ($end === false) {
160 $this->setError("Response message wasn't found in your mail. Please verify that ".
161 "you entered your message between the correct text markers.".
162 "\nYour message was:".
163 "\n".$mp->getBody());
166 $message = substr($body, 0, $end);
167 $message = trim($message);
169 // maybe the last line was "> (ARTIFACT_MAIL_MARKER)". In that case, delete the last ">"
170 $message = preg_replace('/>$/', '', $message);
171 $this->Message = $message;
177 * Insert data into the tracker db
179 * @return - true or false
181 function addMessage() {
185 $user_id = $this->getUserId();
188 // Set up this user's session before posting
190 session_set_new($user_id);
193 $Artifact =& $this->getArtifact();
194 if (!$Artifact || !is_object($Artifact)) {
195 $this->setError("Could Not Get Artifact");
198 if (!$user_id && !$Artifact->ArtifactType->allowsAnon()) {
199 $this->setError("Could Not Match Sender Email Address to User and Tracker Does Not Allow Anonymous Posts");
204 // Create artifact message
206 if ( !$Artifact->addMessage($this->Message,$this->FromName,true) )
208 $this->setError("ArtifactMessage Error:".$Artifact->getErrorMessage());
215 /*------------------------------------------------------------------------
217 *-----------------------------------------------------------------------*/
219 /* Find user_id from email */
220 function getUserId() {
221 // Find User id using email
222 // If no user id, user id is 0;
223 $res = db_query_params ('SELECT user_id FROM users WHERE lower(email)=$1 AND status=$2',
224 array(strtolower($this->FromEmail),
226 if (!$res || db_numrows($res) < 1) {
229 $user_id = db_result($res,0,'user_id');
231 db_free_result($res);
236 function &getArtifact() {
239 // $Group not needed, but let the code here to support
240 // tracker additions in the Future
241 $Group =& group_get_object_by_name($argv[1]);
242 if (!$Group || !is_object($Group)) {
243 $this->setError('Could Not Get Group Object');
245 } elseif ($Group->isError()) {
246 $this->setError('Getting Group Object: '.$Group->getErrorMessage());
249 // DBG("Artifact_get_object(".$this->ArtifactId.");");
250 $this->Artifact =& artifact_get_object($this->ArtifactId);
252 return $this->Artifact;
259 * Simple debugging printput
261 * Add this in /etc/syslog.conf and see /var/log/debug file:
263 * *.=debug /var/log/debug
270 system("echo \"artifact: ".$str."\n\" >> /tmp/tracker-gateway.log");
271 syslog(LOG_DEBUG, "artifact_gateway: ". $str);
272 } else if ($debug==2) {
279 $myTrackerGateway = new TrackerGateway();
280 if ($myTrackerGateway->isError()) {
281 DBG ("From: ". $myTrackerGateway->FromEmail);
282 DBG ("Subject: ". $myTrackerGateway->Subject);
283 if ($myTrackerGateway->FromEmail) {
284 mail ($myTrackerGateway->FromEmail,'Tracker Post Rejected',$myTrackerGateway->getErrorMessage());
286 DBG('Final Message: '.$myTrackerGateway->getErrorMessage());