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');
47 switch (getStringFromRequest('func')) {
50 if (!forge_check_perm ('tracker', $ath->getID(), 'submit')) {
51 exit_permission_denied('tracker');
53 include $gfcommon.'tracker/actions/add.php';
57 if (!form_key_is_valid(getStringFromRequest('form_key'))) {
58 exit_form_double_submit('tracker');
61 $user_email = getStringFromRequest('user_email');
62 $artifact_group_id = getIntFromRequest('artifact_group_id');
63 $summary = getStringFromRequest('summary');
64 $details = getStringFromRequest('details');
65 $assigned_to = getStringFromRequest('assigned_to');
66 $priority = getStringFromRequest('priority');
67 $extra_fields = getStringFromRequest('extra_fields');
72 $ah=new ArtifactHtml($ath);
73 if (!$ah || !is_object($ah)) {
74 form_release_key(getStringFromRequest('form_key'));
75 exit_error(_('Artifact Could Not Be Created'),'tracker');
76 } elseif (!forge_check_perm ('tracker',$ath->getID(),'submit')) {
77 exit_permission_denied('tracker');
80 if (empty($user_email)) {
83 if (!validate_email($user_email)) {
84 form_release_key(getStringFromRequest('form_key'));
85 exit_error(_('Invalid Email Address') . htmlspecialchars($user_email),'tracker');
89 $details = "Anonymous message posted by $user_email\n\n".$details;
92 if (!$ah->create($summary,$details,$assigned_to,$priority,$extra_fields)) {
93 $error_msg = $ah->getErrorMessage();
94 form_release_key(getStringFromRequest('form_key'));
95 include $gfcommon.'tracker/actions/add.php';
97 $feedback .= sprintf(_('Item %s successfully created'),'[#'.$ah->getID().']');
100 // Attach files to this Artifact.
102 for ($i=0; $i<5; $i++) {
103 $f = getUploadedFile("input_file$i");
104 $error = $f['error'];
105 if (isset($error) && $error > 0) {
107 if ($error === 1 || $error === 2) {
108 // UPLOAD_ERR_INI_SIZE or UPLOAD_ERR_FORM_SIZE
109 $error_msg = sprintf(_('Error on attached file %1$d, file is too large (maximum: %2$s).'),
110 $n, ini_get('upload_max_filesize'));
111 } elseif ($error === 3) {
112 // UPLOAD_ERR_PARTIAL
113 $error_msg = sprintf(_('Error on attached file %d, transfer interrupted.'), $n);
117 $file_name = $f['name'];
118 $tmp_name = $f['tmp_name'];
121 if (!is_uploaded_file($tmp_name)) {
125 $afh=new ArtifactFileHtml($ah);
126 if (!$afh || !is_object($afh)) {
127 $error_msg .= _('Could Not Create File Object');
128 } elseif ($afh->isError()) {
129 $error_msg .= $afh->getErrorMessage();
131 if (!util_check_fileupload($tmp_name)) {
132 $error_msg = _('Invalid file name.');
134 if (!$afh->upload($tmp_name,$file_name,$type,' ')) {
135 $error_msg = _('Could Not Attach File to Item: '.$afh->getErrorMessage());
139 session_redirect('/tracker/?group_id='.$group_id.'&atid='.$atid.'&aid='.$aid);
143 case 'massupdate' : {
144 if (!form_key_is_valid(getStringFromRequest('form_key'))) {
145 exit_form_double_submit('tracker');
148 $artifact_id_list = getArrayFromRequest('artifact_id_list');
149 $priority = getStringFromRequest('priority');
150 $status_id = getIntFromRequest('status_id');
151 $artifact_group_id = getIntFromRequest('artifact_group_id');
152 $resolution_id = getIntFromRequest('resolution_id');
153 $assigned_to = getStringFromRequest('assigned_to');
154 $canned_response = getIntFromRequest("canned_response");
155 $extra_fields = getArrayFromRequest('extra_fields');
157 $count=count($artifact_id_list);
159 session_require_perm ('tracker', $ath->getID(), 'manager') ;
161 $artifact_type_id=$ath->getID();
163 for ($i=0; $i < $count; $i++) {
164 $ah=new Artifact($ath,$artifact_id_list[$i]);
165 if (!$ah || !is_object($ah)) {
166 $error_msg .= '[#'.$artifact_id_list[$i].']'._(': ')._('Artifact Could Not Be Created').'<br />';
167 } elseif ($ah->isError()) {
168 $error_msg .= '[#'.$artifact_id_list[$i].']'._(': ').$ah->getErrorMessage().'<br />';
171 $_priority=(($priority != 100) ? $priority : $ah->getPriority());
172 $_status_id=(($status_id != 100) ? $status_id : $ah->getStatusID());
173 //yikes, we want the ability to mass-update to "un-assigned", which is the ID=100, which
174 //conflicts with the "no change" ID! Sorry for messy use of 100.1
175 $_assigned_to=(($assigned_to != '100.1') ? $assigned_to : $ah->getAssignedTo());
178 // get existing extra field data
179 // we will then override individual elements if needed
181 $ef = $ah->getExtraFieldData();
182 $keys = array_keys($ef);
183 foreach ($keys as $efid) {
184 if (is_array($ef[$efid])) {
185 $f = $extra_fields[$efid];
186 // in this case, if $extra_fields is not setted, it
187 // means no option was selected, so we have to delete
188 // the original values
189 if (!is_array($f) || count($f) == 0) {
190 $ef[$efid] = array();
191 } elseif (in_array('100', $extra_fields[$efid])) { // "No change" option selected?
194 $ef[$efid] = $f; // replace old values with new values
197 // in some cases (ie: textfields) the value is not passed, but
198 // this doesn't mean we must delete the existing value
199 if (array_key_exists($efid, $extra_fields)) {
200 $f = $extra_fields[$efid];
207 $ef[$efid] = addslashes($ef[$efid]);
212 if (!$ah->update($_priority,$_status_id,$_assigned_to,$_summary,$canned_response,'',$artifact_type_id,$ef)) {
213 $error_msg .= $ah->getStringID()._(': ').$ah->getErrorMessage().'<br />';
219 $feedback = _('Updated Successfully');
222 unset ($extra_fields_choice);
223 include $gfcommon.'tracker/actions/browse.php';
227 $artifact_id = getIntFromRequest('artifact_id');
228 $priority = getIntFromRequest('priority');
229 $status_id = getIntFromRequest('status_id');
230 $artifact_group_id = getIntFromRequest('artifact_group_id');
231 $resolution_id = getIntFromRequest('resolution_id');
232 $assigned_to = getStringFromRequest('assigned_to');
233 $summary = getStringFromRequest('summary');
234 $canned_response = getStringFromRequest('canned_response');
235 $details = getStringFromRequest('details');
236 $description = getStringFromRequest('description');
237 $new_artifact_type_id = getIntFromRequest('new_artifact_type_id');
238 $extra_fields = getStringFromRequest('extra_fields');
239 $user_email = getStringFromRequest('user_email', false);
243 Technicians can modify limited fields - to be certain
244 no one is hacking around, we override any fields they don't have
245 permission to change.
247 if (!form_key_is_valid(getStringFromRequest('form_key'))) {
248 exit_form_double_submit('tracker');
251 $ah=new ArtifactHtml($ath,$artifact_id);
252 if (!$ah || !is_object($ah)) {
253 exit_error(_('Artifact Could Not Be Created'),'tracker');
254 } elseif ($ah->isError()) {
255 exit_error($ah->getErrorMessage(),'tracker');
256 } elseif (!forge_check_perm ('tracker',$ath->getID(),'submit')) {
257 exit_permission_denied('tracker');
260 $remlink = getArrayFromRequest('remlink');
261 if (count($remlink) > 0 && forge_check_perm ('tracker_admin', $ah->ArtifactType->Group->getID())) {
262 require_once $gfcommon.'pm/ProjectTask.class.php';
263 foreach ($remlink as $tid) {
264 $pt = &projecttask_get_object($tid);
265 if (!$pt || $pt->isError())
266 exit_error(_('Error'), sprintf(_('Could not get Project Task for %d'), $tid));
267 if (!$pt->removeRelatedArtifacts(array($artifact_id)))
268 exit_error($tid."->removeRelatedArtifacts(".$artifact_id.")", $pt->getErrorMessage());
272 The following logic causes fields to be overridden
273 in the event that someone tampered with the HTML form
275 if (forge_check_perm ('tracker', $ath->getID(), 'tech')
276 || forge_check_perm ('tracker', $ath->getID(), 'manager')) {
277 //admin and techs can do everything
278 //techs will have certain fields overridden inside the update() function call
279 if (!$ah->update($priority,$status_id,
280 $assigned_to,$summary,$canned_response,$details,$new_artifact_type_id,$extra_fields, $description)) {
281 form_release_key(getStringFromRequest('form_key'));
282 $error_msg .= _('Tracker Item'). ': '.$ah->getErrorMessage();
289 // Everyone else can add comments
291 if ($ah->addMessage($details,$user_email,true)) {
292 $feedback=_('Comment added');
294 if ( (strlen($details)>0) ) { //if there was no message, then it's not an error but addMessage returns false and sets missing params error
295 //some kind of error in creation
296 exit_error($ah->getErrorMessage(),'tracker');
298 // we have to unset the error if the user added a file ( add a file and no comment)
299 if ( (getStringFromRequest('add_file')) ) {
307 //everyone else can only add comments
310 if ($ah->addMessage($details,$user_email,true)) {
311 $feedback=_('Comment added');
313 //some kind of error in creation
314 exit_error($ah->getErrorMessage(),'tracker');
319 // Admin, Techs and Submitter can add files.
320 if (forge_check_perm ('tracker', $ath->getID(), 'tech')
321 || forge_check_perm ('tracker', $ath->getID(), 'manager')
322 || (session_loggedin() && ($ah->getSubmittedBy() == user_getid()))) {
324 // Attach files to this Artifact.
327 for ($i=0; $i<5; $i++) {
328 $f = getUploadedFile("input_file$i");
329 $error = $f['error'];
330 if (isset($error) && $error > 0) {
332 if ($error === 1 || $error === 2) {
333 // UPLOAD_ERR_INI_SIZE or UPLOAD_ERR_FORM_SIZE
334 $ext_feedback .= "<br />" .
335 sprintf(_("Error: Skipping attachment %d: file is too large."), $n);
336 } elseif ($error === 3) {
337 // UPLOAD_ERR_PARTIAL
338 $ext_feedback .= "<br />" .
339 sprintf(_("Error: Skipping attachment %d: transfer interrupted."), $n);
343 $file_name = $f['name'];
344 $tmp_name = $f['tmp_name'];
348 if (!is_uploaded_file($tmp_name)) {
352 $afh=new ArtifactFileHtml($ah);
353 if (!$afh || !is_object($afh)) {
354 $error_msg .= _('Could Not Create File Object');
355 } elseif ($afh->isError()) {
356 $error_msg .= $afh->getErrorMessage();
358 if (!util_check_fileupload($tmp_name)) {
359 form_release_key(getStringFromRequest('form_key'));
360 exit_error(_('Invalid file name.'),'tracker');
362 if (!$afh->upload($tmp_name,$file_name,$type,' ')) {
363 $error_msg .= ' <br />'._('File Upload: Error').':'.$afh->getErrorMessage();
366 $feedback .= ' <br />'._('File Upload: Successful');
371 // Admin and Techs can delete files.
372 if (forge_check_perm ('tracker', $ath->getID(), 'tech')
373 || forge_check_perm ('tracker', $ath->getID(), 'manager')) {
375 // Delete list of files from this artifact
377 $delete_file = getStringFromRequest('delete_file');
379 $count=count($delete_file);
380 for ($i=0; $i<$count; $i++) {
381 $afh=new ArtifactFileHtml($ah,$delete_file[$i]);
382 if (!$afh || !is_object($afh)) {
383 $error_msg .= _('Could Not Create File Object')._(': ').$delete_file[$i];
384 } elseif ($afh->isError()) {
385 $error_msg .= $afh->getErrorMessage().'::'.$delete_file[$i];
387 if (!$afh->delete()) {
388 $error_msg .= ' <br />'._('File Delete')._(': ').$afh->getErrorMessage();
391 $feedback .= ' <br />'._('File Delete: Successful');
399 // Show just one feedback entry if no errors
402 $feedback = sprintf(_('Item %s successfully updated'),'[#'.$ah->getID().']');
404 $feedback .= $ext_feedback;
407 include $gfcommon.'tracker/actions/browse.php';
411 if (!session_loggedin()) {
412 exit_permission_denied();
414 $start = getIntFromRequest('start');
415 $stop = getIntFromRequest('stop');
416 $artifact_id = getIntFromRequest('artifact_id');
418 // Fix to prevent collision with the start variable used in browse.
422 $ah=new ArtifactHtml($ath,$artifact_id);
423 if (!$ah || !is_object($ah)) {
424 exit_error(_('Artifact Could Not Be Created'),'tracker');
425 } elseif ($ah->isError()) {
426 exit_error($ah->getErrorMessage(),'tracker');
428 if ($start && $ah->isMonitoring())
429 $feedback = _('Monitoring Started');
430 elseif ($stop && !$ah->isMonitoring())
431 $feedback = _('Monitoring Stopped');
434 $error_msg = $ah->getErrorMessage();
436 include $gfcommon.'tracker/actions/browse.php';
439 $at=new ArtifactType($group,$atid);
440 if (!$at || !is_object($at)) {
441 exit_error(_('Artifact Could Not Be Created'),'tracker');
442 } elseif ($at->isError()) {
443 exit_error($at->getErrorMessage(),'tracker');
445 if ($start && $at->isMonitoring())
446 $feedback = _('Monitoring Started');
447 elseif ($stop && !$at->isMonitoring())
448 $feedback = _('Monitoring Deactivated');
451 $feedback=$at->getErrorMessage();
454 include $gfcommon.'tracker/actions/browse.php';
464 case 'deleteartifact' : {
465 session_require_perm ('tracker', $ath->getID(), 'manager') ;
467 $aid = getIntFromRequest('aid');
468 $ah= new ArtifactHtml($ath,$aid);
469 if (!$ah || !is_object($ah)) {
470 exit_error(_('Artifact Could Not Be Created'),'tracker');
471 } elseif ($ah->isError()) {
472 exit_error($ah->getErrorMessage(),'tracker');
474 include $gfcommon.'tracker/actions/deleteartifact.php';
479 // Handle the actual delete
482 case 'postdeleteartifact' : {
483 if (!form_key_is_valid(getStringFromRequest('form_key'))) {
484 exit_form_double_submit('tracker');
486 session_require_perm ('tracker', $ath->getID(), 'manager') ;
488 $aid = getStringFromRequest('aid');
489 $ah= new ArtifactHtml($ath,$aid);
490 if (!$ah || !is_object($ah)) {
491 exit_error(_('Artifact Could Not Be Created'),'tracker');
492 } elseif ($ah->isError()) {
493 exit_error($ah->getErrorMessage(),'tracker');
495 if (!getStringFromRequest('confirm_delete')) {
496 $warning_msg .= _('Confirmation failed. Artifact not deleted');
499 if (!$ah->delete(true)) {
500 $error_msg .= _('Delete failed')._(': ').$ah->getErrorMessage();
502 $feedback .= _('Artifact Deleted Successfully');
505 include $gfcommon.'tracker/actions/browse.php';
511 include $gfcommon.'tracker/actions/taskmgr.php';
515 include $gfcommon.'tracker/actions/browse.php';
519 include $gfcommon.'tracker/actions/query.php';
523 include $gfcommon.'tracker/actions/csv.php';
526 case 'format_csv' : {
527 include $gfcommon.'tracker/actions/format_csv.php';
530 case 'downloadcsv' : {
531 include $gfcommon.'tracker/actions/downloadcsv.php';
535 $aid = getIntFromRequest('aid');
536 session_redirect('/tracker/download.php?group_id='.$group_id.'&atid='.$atid.'&aid='.$aid.'&file_id='.$file_id);
540 $aid = getIntFromRequest('aid');
543 // users can modify their own tickets in a limited way if they submitted them
544 // even if they are not artifact admins
546 $ah=new ArtifactHtml($ath,$aid);
547 if (!$ah || !is_object($ah)) {
548 exit_error(_('Artifact Could Not Be Created'),'tracker');
549 } elseif ($ah->isError()) {
550 exit_error($ah->getErrorMessage(),'tracker');
552 if (forge_check_perm ('tracker', $ath->getID(), 'manager')) {
553 include $gfcommon.'tracker/actions/mod.php';
554 } elseif (forge_check_perm ('tracker', $ath->getID(), 'tech')) {
555 include $gfcommon.'tracker/actions/mod-limited.php';
557 include $gfcommon.'tracker/actions/detail.php';
563 include $gfcommon.'tracker/actions/browse.php';
570 // c-file-style: "bsd"