5 * Copyright 1999-2001 (c) VA Linux Systems
6 * Copyright 2002-2004 (c) GForge Team
7 * Copyright 2012, Franck Villaume - TrivialDev
8 * http://fusionforge.org/
10 * This file is part of FusionForge. FusionForge is free software;
11 * you can redistribute it and/or modify it under the terms of the
12 * GNU General Public License as published by the Free Software
13 * Foundation; either version 2 of the Licence, or (at your option)
16 * FusionForge is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License along
22 * with FusionForge; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
32 // Create the ArtifactType object
34 $ath = new ArtifactTypeHtml($group, $atid);
36 if (!$ath || !is_object($ath)) {
37 exit_error(_('ArtifactType could not be created'),'tracker');
39 if ($ath->isError()) {
40 if($ath->isPermissionDeniedError()) {
41 exit_permission_denied($ath->getErrorMessage(),'tracker');
43 exit_error($ath->getErrorMessage(),'tracker');
46 switch (getStringFromRequest('func')) {
49 if (!forge_check_perm ('tracker',$ath->getID(),'submit')) {
50 exit_permission_denied('tracker');
52 include $gfcommon.'tracker/actions/add.php';
56 if (!form_key_is_valid(getStringFromRequest('form_key'))) {
57 exit_form_double_submit('tracker');
60 $user_email = getStringFromRequest('user_email');
61 $artifact_group_id = getIntFromRequest('artifact_group_id');
62 $summary = getStringFromRequest('summary');
63 $details = getStringFromRequest('details');
64 $assigned_to = getStringFromRequest('assigned_to');
65 $priority = getStringFromRequest('priority');
66 $extra_fields = getStringFromRequest('extra_fields');
71 $ah=new ArtifactHtml($ath);
72 if (!$ah || !is_object($ah)) {
73 form_release_key(getStringFromRequest('form_key'));
74 exit_error(_('Artifact Could Not Be Created'),'tracker');
75 } elseif (!forge_check_perm ('tracker',$ath->getID(),'submit')) {
76 exit_permission_denied('tracker');
78 if (empty($user_email)) {
81 if (!validate_email($user_email)) {
82 form_release_key(getStringFromRequest('form_key'));
83 exit_error(_('Invalid Email Address') . htmlspecialchars($user_email),'tracker');
87 $details = "Anonymous message posted by $user_email\n\n".
90 if (!$ah->create($summary,$details,$assigned_to,$priority,$extra_fields)) {
91 form_release_key(getStringFromRequest('form_key'));
92 exit_error($ah->getErrorMessage(),'tracker');
95 // Attach files to this Artifact.
98 for ($i=0; $i<5; $i++) {
99 $f = getUploadedFile("input_file$i");
100 $error = $f['error'];
101 if (isset($error) && $error > 0) {
103 if ($error === 1 || $error === 2) {
104 // UPLOAD_ERR_INI_SIZE or UPLOAD_ERR_FORM_SIZE
105 $ext_feedback .= "<br />ERROR: Skipping attachement $n: file is too large.";
106 } elseif ($error === 3) {
107 // UPLOAD_ERR_PARTIAL
108 $ext_feedback .= "<br />ERROR: Skipping attachement $n: transfert interrupted.";
112 $file_name = $f['name'];
113 $tmp_name = $f['tmp_name'];
116 if (!is_uploaded_file($tmp_name)) {
120 $afh=new ArtifactFileHtml($ah);
121 if (!$afh || !is_object($afh)) {
122 $error_msg .= _('Could Not Create File Object');
123 } elseif ($afh->isError()) {
124 $error_msg .= $afh->getErrorMessage();
126 if (!util_check_fileupload($tmp_name)) {
127 form_release_key(getStringFromRequest('form_key'));
128 //delete the artifact
130 exit_error(_('Invalid filename'),'tracker');
132 if (!$afh->upload($tmp_name,$file_name,$type,' ')) {
133 form_release_key(getStringFromRequest('form_key'));
134 //delete the artifact
136 exit_error(_('Could Not Attach File to Item: '.$afh->getErrorMessage()),'tracker');
140 $feedback .= sprintf(_('Item %s successfully created'),'[#'.$ah->getID().']');
141 $feedback .= $ext_feedback;
142 include $gfcommon.'tracker/actions/browse.php';
147 case 'massupdate' : {
148 if (!form_key_is_valid(getStringFromRequest('form_key'))) {
149 exit_form_double_submit('tracker');
152 $artifact_id_list = getArrayFromRequest('artifact_id_list');
153 $priority = getStringFromRequest('priority');
154 $status_id = getIntFromRequest('status_id');
155 $artifact_group_id = getIntFromRequest('artifact_group_id');
156 $resolution_id = getIntFromRequest('resolution_id');
157 $assigned_to = getStringFromRequest('assigned_to');
158 $canned_response = getIntFromRequest("canned_response");
159 $extra_fields = getArrayFromRequest('extra_fields');
162 $count=count($artifact_id_list);
164 session_require_perm ('tracker', $ath->getID(), 'manager') ;
166 $artifact_type_id=$ath->getID();
168 for ($i=0; $i < $count; $i++) {
169 $ah=new Artifact($ath,$artifact_id_list[$i]);
170 if (!$ah || !is_object($ah)) {
171 $feedback .= ' ID: '.$artifact_id_list[$i].'::Artifact Could Not Be Created';
172 } elseif ($ah->isError()) {
173 $feedback .= ' ID: '.$artifact_id_list[$i].'::'.$ah->getErrorMessage();
176 $_priority=(($priority != 100) ? $priority : $ah->getPriority());
177 $_status_id=(($status_id != 100) ? $status_id : $ah->getStatusID());
178 //yikes, we want the ability to mass-update to "un-assigned", which is the ID=100, which
179 //conflicts with the "no change" ID! Sorry for messy use of 100.1
180 $_assigned_to=(($assigned_to != '100.1') ? $assigned_to : $ah->getAssignedTo());
183 // get existing extra field data
184 // we will then override individual elements if needed
186 $ef = $ah->getExtraFieldData();
187 $keys = array_keys($ef);
188 foreach ($keys as $efid) {
189 if (is_array($ef[$efid])) {
190 $f = $extra_fields[$efid];
191 // in this case, if $extra_fields is not setted, it
192 // means no option was selected, so we have to delete
193 // the original values
194 if (!is_array($f) || count($f) == 0) {
195 $ef[$efid] = array();
196 } elseif (in_array('100', $extra_fields[$efid])) { // "No change" option selected?
199 $ef[$efid] = $f; // replace old values with new values
202 // in some cases (ie: textfields) the value is not passed, but
203 // this doesn't mean we must delete the existing value
204 if (array_key_exists($efid, $extra_fields)) {
205 $f = $extra_fields[$efid];
212 $ef[$efid] = addslashes($ef[$efid]);
217 if (!$ah->update($_priority,$_status_id,$_assigned_to,$_summary,$canned_response,'',$artifact_type_id,$ef)) {
222 $error_msg .= ' ID: '.$artifact_id_list[$i].'::'.$ah->getErrorMessage();
230 $feedback = _('Updated Successfully'); }
232 unset ($extra_fields_choice);
233 include $gfcommon.'tracker/actions/browse.php';
237 $artifact_id = getIntFromRequest('artifact_id');
238 $priority = getIntFromRequest('priority');
239 $status_id = getIntFromRequest('status_id');
240 $artifact_group_id = getIntFromRequest('artifact_group_id');
241 $resolution_id = getIntFromRequest('resolution_id');
242 $assigned_to = getStringFromRequest('assigned_to');
243 $summary = getStringFromRequest('summary');
244 $canned_response = getStringFromRequest('canned_response');
245 $details = getStringFromRequest('details');
246 $description = getStringFromRequest('description');
247 $new_artifact_type_id = getIntFromRequest('new_artifact_type_id');
248 $extra_fields = getStringFromRequest('extra_fields');
249 $user_email = getStringFromRequest('user_email', false);
253 Technicians can modify limited fields - to be certain
254 no one is hacking around, we override any fields they don't have
255 permission to change.
257 if (!form_key_is_valid(getStringFromRequest('form_key'))) {
258 exit_form_double_submit('tracker');
261 $ah=new ArtifactHtml($ath,$artifact_id);
262 if (!$ah || !is_object($ah)) {
263 exit_error(_('Artifact Could Not Be Created'),'tracker');
264 } elseif ($ah->isError()) {
265 exit_error($ah->getErrorMessage(),'tracker');
266 } elseif (!forge_check_perm ('tracker',$ath->getID(),'submit')) {
267 exit_permission_denied('tracker');
270 $remlink = getArrayFromRequest('remlink');
271 if (count($remlink) > 0 && forge_check_perm ('tracker_admin', $ah->ArtifactType->Group->getID())) {
272 require_once $gfcommon.'pm/ProjectTask.class.php';
273 foreach ($remlink as $tid) {
274 $pt = &projecttask_get_object($tid);
275 if (!$pt || $pt->isError())
276 exit_error(_('Error'), sprintf(_('Could not get Project Task for %d'), $tid));
277 if (!$pt->removeRelatedArtifacts(array($artifact_id)))
278 exit_error($tid."->removeRelatedArtifacts(".$artifact_id.")", $pt->getErrorMessage());
282 The following logic causes fields to be overridden
283 in the event that someone tampered with the HTML form
285 if (forge_check_perm ('tracker', $ath->getID(), 'tech')
286 || forge_check_perm ('tracker', $ath->getID(), 'manager')) {
287 //admin and techs can do everything
288 //techs will have certain fields overridden inside the update() function call
289 if (!$ah->update($priority,$status_id,
290 $assigned_to,$summary,$canned_response,$details,$new_artifact_type_id,$extra_fields, $description)) {
291 form_release_key(getStringFromRequest('form_key'));
292 $error_msg .= _('Tracker Item'). ': '.$ah->getErrorMessage();
299 // Everyone else can add comments
301 if ($ah->addMessage($details,$user_email,true)) {
302 $feedback=_('Comment added');
304 if ( (strlen($details)>0) ) { //if there was no message, then it's not an error but addMessage returns false and sets missing params error
305 //some kind of error in creation
306 exit_error($ah->getErrorMessage(),'tracker');
308 // we have to unset the error if the user added a file ( add a file and no comment)
309 if ( (getStringFromRequest('add_file')) ) {
317 //everyone else can only add comments
320 if ($ah->addMessage($details,$user_email,true)) {
321 $feedback=_('Comment added');
323 //some kind of error in creation
324 exit_error($ah->getErrorMessage(),'tracker');
329 // Admin, Techs and Submitter can add files.
330 if (forge_check_perm ('tracker', $ath->getID(), 'tech')
331 || forge_check_perm ('tracker', $ath->getID(), 'manager')
332 || (session_loggedin() && ($ah->getSubmittedBy() == user_getid()))) {
334 // Attach files to this Artifact.
337 for ($i=0; $i<5; $i++) {
338 $f = getUploadedFile("input_file$i");
339 $error = $f['error'];
340 if (isset($error) && $error > 0) {
342 if ($error === 1 || $error === 2) {
343 // UPLOAD_ERR_INI_SIZE or UPLOAD_ERR_FORM_SIZE
344 $ext_feedback .= "<br />" .
345 sprintf(_("ERROR: Skipping attachment %d: file is too large."), $n);
346 } elseif ($error === 3) {
347 // UPLOAD_ERR_PARTIAL
348 $ext_feedback .= "<br />" .
349 sprintf(_("ERROR: Skipping attachment %d: transfer interrupted."), $n);
353 $file_name = $f['name'];
354 $tmp_name = $f['tmp_name'];
358 if (!is_uploaded_file($tmp_name)) {
362 $afh=new ArtifactFileHtml($ah);
363 if (!$afh || !is_object($afh)) {
364 $error_msg .= _('Could Not Create File Object');
365 } elseif ($afh->isError()) {
366 $error_msg .= $afh->getErrorMessage();
368 if (!util_check_fileupload($tmp_name)) {
369 form_release_key(getStringFromRequest('form_key'));
370 exit_error(_('Invalid filename'),'tracker');
372 if (!$afh->upload($tmp_name,$file_name,$type,' ')) {
373 $error_msg .= ' <br />'._('File Upload: Error').':'.$afh->getErrorMessage();
376 $feedback .= ' <br />'._('File Upload: Successful');
381 // Admin and Techs can delete files.
382 if (forge_check_perm ('tracker', $ath->getID(), 'tech')
383 || forge_check_perm ('tracker', $ath->getID(), 'manager')) {
385 // Delete list of files from this artifact
387 $delete_file = getStringFromRequest('delete_file');
389 $count=count($delete_file);
390 for ($i=0; $i<$count; $i++) {
391 $afh=new ArtifactFileHtml($ah,$delete_file[$i]);
392 if (!$afh || !is_object($afh)) {
393 $error_msg .= _('Could Not Create File Object::').$delete_file[$i];
394 } elseif ($afh->isError()) {
395 $error_msg .= $afh->getErrorMessage().'::'.$delete_file[$i];
397 if (!$afh->delete()) {
398 $error_msg .= ' <br />'._('File Delete:').': '.$afh->getErrorMessage();
401 $feedback .= ' <br />'._('File Delete: Successful');
409 // Show just one feedback entry if no errors
412 $feedback = sprintf(_('Item %s successfully updated'),'[#'.$ah->getID().']');
414 $feedback .= $ext_feedback;
415 include $gfcommon.'tracker/actions/browse.php';
421 if (!session_loggedin()) {
422 exit_permission_denied();
424 $start = getIntFromRequest('start');
425 $stop = getIntFromRequest('stop');
426 $artifact_id = getIntFromRequest('artifact_id');
428 // Fix to prevent collision with the start variable used in browse.
432 $ah=new ArtifactHtml($ath,$artifact_id);
433 if (!$ah || !is_object($ah)) {
434 exit_error(_('Artifact Could Not Be Created'),'tracker');
435 } elseif ($ah->isError()) {
436 exit_error($ah->getErrorMessage(),'tracker');
438 if ($start && $ah->isMonitoring())
439 $feedback = _('Monitoring Started');
440 elseif ($stop && !$ah->isMonitoring())
441 $feedback = _('Monitoring Deactivated');
444 $error_msg = $ah->getErrorMessage();
446 include $gfcommon.'tracker/actions/browse.php';
449 $at=new ArtifactType($group,$atid);
450 if (!$at || !is_object($at)) {
451 exit_error(_('Artifact Could Not Be Created'),'tracker');
452 } elseif ($at->isError()) {
453 exit_error($at->getErrorMessage(),'tracker');
455 if ($start && $at->isMonitoring())
456 $feedback = _('Monitoring Started');
457 elseif ($stop && !$at->isMonitoring())
458 $feedback = _('Monitoring Deactivated');
461 $feedback=$at->getErrorMessage();
464 include $gfcommon.'tracker/actions/browse.php';
474 case 'deleteartifact' : {
475 session_require_perm ('tracker', $ath->getID(), 'manager') ;
477 $aid = getIntFromRequest('aid');
478 $ah= new ArtifactHtml($ath,$aid);
479 if (!$ah || !is_object($ah)) {
480 exit_error(_('Artifact Could Not Be Created'),'tracker');
481 } elseif ($ah->isError()) {
482 exit_error($ah->getErrorMessage(),'tracker');
484 include $gfcommon.'tracker/actions/deleteartifact.php';
489 // Handle the actual delete
492 case 'postdeleteartifact' : {
493 if (!form_key_is_valid(getStringFromRequest('form_key'))) {
494 exit_form_double_submit('tracker');
496 session_require_perm ('tracker', $ath->getID(), 'manager') ;
498 $aid = getStringFromRequest('aid');
499 $ah= new ArtifactHtml($ath,$aid);
500 if (!$ah || !is_object($ah)) {
501 exit_error(_('Artifact Could Not Be Created'),'tracker');
502 } elseif ($ah->isError()) {
503 exit_error($ah->getErrorMessage(),'tracker');
505 if (!getStringFromRequest('confirm_delete')) {
506 $warning_msg .= _('Confirmation failed. Artifact not deleted');
509 if (!$ah->delete(true)) {
510 $error_msg .= _('Artifact Delete Failed') . ': '.$ah->getErrorMessage();
512 $feedback .= _('Artifact Deleted Successfully');
515 include $gfcommon.'tracker/actions/browse.php';
521 include $gfcommon.'tracker/actions/taskmgr.php';
525 include $gfcommon.'tracker/actions/browse.php';
529 include $gfcommon.'tracker/actions/query.php';
533 include $gfcommon.'tracker/actions/csv.php';
536 case 'format_csv' : {
537 include $gfcommon.'tracker/actions/format_csv.php';
540 case 'downloadcsv' : {
541 include $gfcommon.'tracker/actions/downloadcsv.php';
545 $aid = getIntFromRequest('aid');
546 session_redirect('/tracker/download.php?group_id='.$group_id.'&atid='.$atid.'&aid='.$aid.'&file_id='.$file_id);
550 $aid = getIntFromRequest('aid');
553 // users can modify their own tickets in a limited way if they submitted them
554 // even if they are not artifact admins
556 $ah=new ArtifactHtml($ath,$aid);
557 if (!$ah || !is_object($ah)) {
558 exit_error(_('Artifact Could Not Be Created'),'tracker');
559 } elseif ($ah->isError()) {
560 exit_error($ah->getErrorMessage(),'tracker');
562 if (forge_check_perm ('tracker', $ath->getID(), 'manager')) {
563 include $gfcommon.'tracker/actions/mod.php';
564 } elseif (forge_check_perm ('tracker', $ath->getID(), 'tech')) {
565 include $gfcommon.'tracker/actions/mod-limited.php';
567 include $gfcommon.'tracker/actions/detail.php';
573 include $gfcommon.'tracker/actions/browse.php';
580 // c-file-style: "bsd"