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 based on forum_gateway.php
15 * This file is part of FusionForge. FusionForge is free software;
16 * you can redistribute it and/or modify it under the terms of the
17 * GNU General Public License as published by the Free Software
18 * Foundation; either version 2 of the Licence, or (at your option)
21 * FusionForge is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
26 * You should have received a copy of the GNU General Public License along
27 * with FusionForge; if not, write to the Free Software Foundation, Inc.,
28 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
31 require dirname(__FILE__).'/../www/env.inc.php';
32 require_once $gfcommon.'include/pre.php';
33 require_once $gfcommon.'include/Group.class.php';
34 require_once $gfcommon.'include/MailParser.class.php';
35 require_once $gfcommon.'tracker/Artifact.class.php';
36 require_once $gfcommon.'tracker/ArtifactFactory.class.php';
38 class TrackerGateway extends Error {
55 function TrackerGateway() {
58 /* Copy mail message to tmp file */
59 $tmpfile = $this->copyMailTmp();
60 //DBG("Tmpname: ". $tmpfile);
63 $ret = $this->parseMail($tmpfile);
65 /* Delete temp file */
68 /* Check the return variable from parseMail */
73 /* add the info to tracker */
74 $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", "artifact_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) {
114 if (!$mp = new MailParser($input_file)) {
115 $this->setError('Error In MailParser');
117 } elseif ($mp->isError()) {
118 $this->setError('Error In MailParser '.$mp->getErrorMessage());
119 // even if it is an error, try to get the address of the sender so we
120 // can send him back the error
121 $this->FromEmail = $mp->getFromEmail();
125 $this->FromEmail = $mp->getFromEmail();
127 //subjects are in this required format: '[group - tracker_name][123456] My Subject'
128 //where 123456 is the artifact_id of the artifact message.
129 //we parse that ID to get the artifact that this should post to
131 $subj = $mp->getSubject();
132 if (preg_match('/(\[)([0-9]*)(\])/',$subj,$arr)) {
133 $this->ArtifactId=$arr[2];
134 $artifactid_end=(strpos($subj,'['.$arr[2].']')) + strlen('['.$arr[2].']');
135 $this->Subject = substr($subj,$artifactid_end);
137 $this->FromEmail = ''; // Do not reply if no pattern found.
138 $this->Subject = $subj;
139 $this->ArtifactId=0; // Not supported at the moment
140 $this->setError("ArtifactId needed at the moment. Artifact creation not supported");
144 $body = $mp->getBody();
145 // find first occurrence of the marker in the message
146 $begin = strpos($body, ARTIFACT_MAIL_MARKER);
147 if ($begin === false) {
148 $this->setError("Response message wasn't found in your mail. Please verify that ".
149 "you entered your message between the correct text markers.".
150 "\nYour message was:".
151 "\n".$mp->getBody());
154 // get the part of the message located after the marker
155 $body = substr($body, $begin+strlen(ARTIFACT_MAIL_MARKER));
156 // now look for the ending marker
157 $end = strpos($body, ARTIFACT_MAIL_MARKER);
158 if ($end === false) {
159 $this->setError("Response message wasn't found in your mail. Please verify that ".
160 "you entered your message between the correct text markers.".
161 "\nYour message was:".
162 "\n".$mp->getBody());
165 $message = substr($body, 0, $end);
166 $message = trim($message);
168 // maybe the last line was "> (ARTIFACT_MAIL_MARKER)". In that case, delete the last ">"
169 $message = preg_replace('/>$/', '', $message);
170 $this->Message = $message;
176 * Insert data into the tracker db
178 * @return - true or false
180 function addMessage() {
184 $user_id = $this->getUserId();
185 $Artifact =& $this->getArtifact();
186 if (!$Artifact || !is_object($Artifact)) {
187 $this->setError("Could Not Get Artifact");
192 // Set up this user's session before posting
194 session_set_new($user_id);
195 if (!forge_check_perm_for_user ($user_id, 'tracker',$this->ArtifactType->getID(),'submit')) {
196 $this->setError(_('This user is not allowed to submit items to this tracker.'));
199 } elseif (!forge_check_perm ('tracker',$this->ArtifactType->getID(),'submit')) {
200 $this->setError(_('Could not match sender email address to user, and tracker does not allow anonymous posts.'));
205 // Create artifact message
207 if ( !$Artifact->addMessage($this->Message,$this->FromName,true) )
209 $this->setError("ArtifactMessage Error:".$Artifact->getErrorMessage());
216 /*------------------------------------------------------------------------
218 *-----------------------------------------------------------------------*/
220 /* Find user_id from email */
221 function getUserId() {
222 // Find User id using email
223 // If no user id, user id is 0;
224 $res = db_query_params ('SELECT user_id FROM users WHERE lower(email)=$1 AND status=$2',
225 array(strtolower($this->FromEmail),
227 if (!$res || db_numrows($res) < 1) {
230 $user_id = db_result($res,0,'user_id');
232 db_free_result($res);
237 function &getArtifact() {
240 // $Group not needed, but let the code here to support
241 // tracker additions in the Future
242 $Group = group_get_object_by_name($argv[1]);
243 if (!$Group || !is_object($Group)) {
244 $this->setError('Could Not Get Group Object');
246 } elseif ($Group->isError()) {
247 $this->setError('Getting Group Object: '.$Group->getErrorMessage());
250 // DBG("Artifact_get_object(".$this->ArtifactId.");");
251 $this->Artifact =& artifact_get_object($this->ArtifactId);
253 return $this->Artifact;
260 * Simple debugging printput
262 * Add this in /etc/syslog.conf and see /var/log/debug file:
264 * *.=debug /var/log/debug
271 file_put_contents('/tmp/tracker-gateway.log', "artifact: ".$str."\n", FILE_APPEND);
272 syslog(LOG_DEBUG, "artifact_gateway: ". $str);
273 } elseif ($debug==2) {
280 $myTrackerGateway = new TrackerGateway();
281 if ($myTrackerGateway->isError()) {
282 DBG ("From: ". $myTrackerGateway->FromEmail);
283 DBG ("Subject: ". $myTrackerGateway->Subject);
284 if ($myTrackerGateway->FromEmail) {
285 mail ($myTrackerGateway->FromEmail,'Tracker Post Rejected',$myTrackerGateway->getErrorMessage());
287 DBG('Final Message: '.$myTrackerGateway->getErrorMessage());