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 $category_id = getIntFromRequest('category_id');
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);
74 if (!$ah || !is_object($ah)) {
75 form_release_key(getStringFromRequest('form_key'));
76 exit_error(_('Artifact Could Not Be Created'),'tracker');
77 } elseif (!forge_check_perm ('tracker',$ath->getID(),'submit')) {
78 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".
92 if (!$ah->create($summary,$details,$assigned_to,$priority,$extra_fields)) {
93 form_release_key(getStringFromRequest('form_key'));
94 exit_error($ah->getErrorMessage(),'tracker');
97 // Attach files to this Artifact.
100 for ($i=0; $i<5; $i++) {
101 $f = getUploadedFile("input_file$i");
102 $error = $f['error'];
103 if (isset($error) && $error > 0) {
105 if ($error === 1 || $error === 2) {
106 // UPLOAD_ERR_INI_SIZE or UPLOAD_ERR_FORM_SIZE
107 $ext_feedback .= "<br />ERROR: Skipping attachement $n: file is too large.";
108 } elseif ($error === 3) {
109 // UPLOAD_ERR_PARTIAL
110 $ext_feedback .= "<br />ERROR: Skipping attachement $n: transfert interrupted.";
114 $file_name = $f['name'];
115 $tmp_name = $f['tmp_name'];
118 if (!is_uploaded_file($tmp_name)) {
122 $afh=new ArtifactFileHtml($ah);
123 if (!$afh || !is_object($afh)) {
124 $error_msg .= _('Could Not Create File Object');
125 } elseif ($afh->isError()) {
126 $error_msg .= $afh->getErrorMessage();
128 if (!util_check_fileupload($tmp_name)) {
129 form_release_key(getStringFromRequest('form_key'));
130 //delete the artifact
132 exit_error(_('Invalid filename'),'tracker');
134 if (!$afh->upload($tmp_name,$file_name,$type,' ')) {
135 form_release_key(getStringFromRequest('form_key'));
136 //delete the artifact
138 exit_error(_('Could Not Attach File to Item: '.$afh->getErrorMessage()),'tracker');
142 $feedback .= sprintf(_('Item %s successfully created'),'[#'.$ah->getID().']');
143 $feedback .= $ext_feedback;
144 include $gfcommon.'tracker/actions/browse.php';
149 case 'massupdate' : {
150 if (!form_key_is_valid(getStringFromRequest('form_key'))) {
151 exit_form_double_submit('tracker');
154 $artifact_id_list = getArrayFromRequest('artifact_id_list');
155 $priority = getStringFromRequest('priority');
156 $status_id = getIntFromRequest('status_id');
157 $category_id = getIntFromRequest('category_id');
158 $artifact_group_id = getIntFromRequest('artifact_group_id');
159 $resolution_id = getIntFromRequest('resolution_id');
160 $assigned_to = getStringFromRequest('assigned_to');
161 $canned_response = getIntFromRequest("canned_response");
162 $extra_fields = getArrayFromRequest('extra_fields');
165 $count=count($artifact_id_list);
167 session_require_perm ('tracker', $ath->getID(), 'manager') ;
169 $artifact_type_id=$ath->getID();
171 for ($i=0; $i < $count; $i++) {
172 $ah=new Artifact($ath,$artifact_id_list[$i]);
173 if (!$ah || !is_object($ah)) {
174 $feedback .= ' ID: '.$artifact_id_list[$i].'::Artifact Could Not Be Created';
175 } elseif ($ah->isError()) {
176 $feedback .= ' ID: '.$artifact_id_list[$i].'::'.$ah->getErrorMessage();
179 $_priority=(($priority != 100) ? $priority : $ah->getPriority());
180 $_status_id=(($status_id != 100) ? $status_id : $ah->getStatusID());
181 //yikes, we want the ability to mass-update to "un-assigned", which is the ID=100, which
182 //conflicts with the "no change" ID! Sorry for messy use of 100.1
183 $_assigned_to=(($assigned_to != '100.1') ? $assigned_to : $ah->getAssignedTo());
186 // get existing extra field data
187 // we will then override individual elements if needed
189 $ef = $ah->getExtraFieldData();
190 $keys = array_keys($ef);
191 foreach ($keys as $efid) {
192 if (is_array($ef[$efid])) {
193 $f = $extra_fields[$efid];
194 // in this case, if $extra_fields is not setted, it
195 // means no option was selected, so we have to delete
196 // the original values
197 if (!is_array($f) || count($f) == 0) {
198 $ef[$efid] = array();
199 } elseif (in_array('100', $extra_fields[$efid])) { // "No change" option selected?
202 $ef[$efid] = $f; // replace old values with new values
205 // in some cases (ie: textfields) the value is not passed, but
206 // this doesn't mean we must delete the existing value
207 if (array_key_exists($efid, $extra_fields)) {
208 $f = $extra_fields[$efid];
215 $ef[$efid] = addslashes($ef[$efid]);
220 if (!$ah->update($_priority,$_status_id,$_assigned_to,$_summary,$canned_response,'',$artifact_type_id,$ef)) {
225 $error_msg .= ' ID: '.$artifact_id_list[$i].'::'.$ah->getErrorMessage();
233 $feedback = _('Updated Successfully'); }
235 unset ($extra_fields_choice);
236 include $gfcommon.'tracker/actions/browse.php';
240 $artifact_id = getIntFromRequest('artifact_id');
241 $priority = getIntFromRequest('priority');
242 $status_id = getIntFromRequest('status_id');
243 $category_id = getIntFromRequest('category_id');
244 $artifact_group_id = getIntFromRequest('artifact_group_id');
245 $resolution_id = getIntFromRequest('resolution_id');
246 $assigned_to = getStringFromRequest('assigned_to');
247 $summary = getStringFromRequest('summary');
248 $canned_response = getStringFromRequest('canned_response');
249 $details = getStringFromRequest('details');
250 $description = getStringFromRequest('description');
251 $new_artifact_type_id = getIntFromRequest('new_artifact_type_id');
252 $extra_fields = getStringFromRequest('extra_fields');
253 $user_email = getStringFromRequest('user_email', false);
257 Technicians can modify limited fields - to be certain
258 no one is hacking around, we override any fields they don't have
259 permission to change.
261 if (!form_key_is_valid(getStringFromRequest('form_key'))) {
262 exit_form_double_submit('tracker');
265 $ah=new ArtifactHtml($ath,$artifact_id);
266 if (!$ah || !is_object($ah)) {
267 exit_error(_('Artifact Could Not Be Created'),'tracker');
268 } elseif ($ah->isError()) {
269 exit_error($ah->getErrorMessage(),'tracker');
270 } elseif (!forge_check_perm ('tracker',$ath->getID(),'submit')) {
271 exit_permission_denied('tracker');
274 $remlink = getArrayFromRequest('remlink');
275 if (count($remlink) > 0 && forge_check_perm ('tracker_admin', $ah->ArtifactType->Group->getID())) {
276 require_once $gfcommon.'pm/ProjectTask.class.php';
277 foreach ($remlink as $tid) {
278 $pt = &projecttask_get_object($tid);
279 if (!$pt || $pt->isError())
280 exit_error(_('Error'), sprintf(_('Could not get Project Task for %d'), $tid));
281 if (!$pt->removeRelatedArtifacts(array($artifact_id)))
282 exit_error($tid."->removeRelatedArtifacts(".$artifact_id.")", $pt->getErrorMessage());
286 The following logic causes fields to be overridden
287 in the event that someone tampered with the HTML form
289 if (forge_check_perm ('tracker', $ath->getID(), 'tech')
290 || forge_check_perm ('tracker', $ath->getID(), 'manager')) {
291 //admin and techs can do everything
292 //techs will have certain fields overridden inside the update() function call
293 if (!$ah->update($priority,$status_id,
294 $assigned_to,$summary,$canned_response,$details,$new_artifact_type_id,$extra_fields, $description)) {
295 form_release_key(getStringFromRequest('form_key'));
296 $error_msg .= _('Tracker Item'). ': '.$ah->getErrorMessage();
303 // Everyone else can add comments
305 if ($ah->addMessage($details,$user_email,true)) {
306 $feedback=_('Comment added');
308 if ( (strlen($details)>0) ) { //if there was no message, then it's not an error but addMessage returns false and sets missing params error
309 //some kind of error in creation
310 exit_error($ah->getErrorMessage(),'tracker');
312 // we have to unset the error if the user added a file ( add a file and no comment)
313 if ( (getStringFromRequest('add_file')) ) {
321 //everyone else can only add comments
324 if ($ah->addMessage($details,$user_email,true)) {
325 $feedback=_('Comment added');
327 //some kind of error in creation
328 exit_error($ah->getErrorMessage(),'tracker');
333 // Admin, Techs and Submitter can add files.
334 if (forge_check_perm ('tracker', $ath->getID(), 'tech')
335 || forge_check_perm ('tracker', $ath->getID(), 'manager')
336 || (session_loggedin() && ($ah->getSubmittedBy() == user_getid()))) {
338 // Attach files to this Artifact.
341 for ($i=0; $i<5; $i++) {
342 $f = getUploadedFile("input_file$i");
343 $error = $f['error'];
344 if (isset($error) && $error > 0) {
346 if ($error === 1 || $error === 2) {
347 // UPLOAD_ERR_INI_SIZE or UPLOAD_ERR_FORM_SIZE
348 $ext_feedback .= "<br />" .
349 sprintf(_("ERROR: Skipping attachment %d: file is too large."), $n);
350 } elseif ($error === 3) {
351 // UPLOAD_ERR_PARTIAL
352 $ext_feedback .= "<br />" .
353 sprintf(_("ERROR: Skipping attachment %d: transfer interrupted."), $n);
357 $file_name = $f['name'];
358 $tmp_name = $f['tmp_name'];
362 if (!is_uploaded_file($tmp_name)) {
366 $afh=new ArtifactFileHtml($ah);
367 if (!$afh || !is_object($afh)) {
368 $error_msg .= _('Could Not Create File Object');
369 } elseif ($afh->isError()) {
370 $error_msg .= $afh->getErrorMessage();
372 if (!util_check_fileupload($tmp_name)) {
373 form_release_key(getStringFromRequest('form_key'));
374 exit_error(_('Invalid filename'),'tracker');
376 if (!$afh->upload($tmp_name,$file_name,$type,' ')) {
377 $error_msg .= ' <br />'._('File Upload: Error').':'.$afh->getErrorMessage();
380 $feedback .= ' <br />'._('File Upload: Successful');
385 // Admin and Techs can delete files.
386 if (forge_check_perm ('tracker', $ath->getID(), 'tech')
387 || forge_check_perm ('tracker', $ath->getID(), 'manager')) {
389 // Delete list of files from this artifact
391 $delete_file = getStringFromRequest('delete_file');
393 $count=count($delete_file);
394 for ($i=0; $i<$count; $i++) {
395 $afh=new ArtifactFileHtml($ah,$delete_file[$i]);
396 if (!$afh || !is_object($afh)) {
397 $error_msg .= _('Could Not Create File Object::').$delete_file[$i];
398 } elseif ($afh->isError()) {
399 $error_msg .= $afh->getErrorMessage().'::'.$delete_file[$i];
401 if (!$afh->delete()) {
402 $error_msg .= ' <br />'._('File Delete:').': '.$afh->getErrorMessage();
405 $feedback .= ' <br />'._('File Delete: Successful');
413 // Show just one feedback entry if no errors
416 $feedback = sprintf(_('Item %s successfully updated'),'[#'.$ah->getID().']');
418 $feedback .= $ext_feedback;
419 include $gfcommon.'tracker/actions/browse.php';
425 if (!session_loggedin()) {
426 exit_permission_denied();
428 $start = getIntFromRequest('start');
429 $stop = getIntFromRequest('stop');
430 $artifact_id = getIntFromRequest('artifact_id');
432 // Fix to prevent collision with the start variable used in browse.
436 $ah=new ArtifactHtml($ath,$artifact_id);
437 if (!$ah || !is_object($ah)) {
438 exit_error(_('Artifact Could Not Be Created'),'tracker');
439 } elseif ($ah->isError()) {
440 exit_error($ah->getErrorMessage(),'tracker');
442 if ($start && $ah->isMonitoring())
443 $feedback = _('Monitoring Started');
444 elseif ($stop && !$ah->isMonitoring())
445 $feedback = _('Monitoring Deactivated');
448 $error_msg = $ah->getErrorMessage();
450 include $gfcommon.'tracker/actions/browse.php';
453 $at=new ArtifactType($group,$atid);
454 if (!$at || !is_object($at)) {
455 exit_error(_('Artifact Could Not Be Created'),'tracker');
456 } elseif ($at->isError()) {
457 exit_error($at->getErrorMessage(),'tracker');
459 if ($start && $at->isMonitoring())
460 $feedback = _('Monitoring Started');
461 elseif ($stop && !$at->isMonitoring())
462 $feedback = _('Monitoring Deactivated');
465 $feedback=$at->getErrorMessage();
468 include $gfcommon.'tracker/actions/browse.php';
478 case 'deleteartifact' : {
479 session_require_perm ('tracker', $ath->getID(), 'manager') ;
481 $aid = getIntFromRequest('aid');
482 $ah= new ArtifactHtml($ath,$aid);
483 if (!$ah || !is_object($ah)) {
484 exit_error(_('Artifact Could Not Be Created'),'tracker');
485 } elseif ($ah->isError()) {
486 exit_error($ah->getErrorMessage(),'tracker');
488 include $gfcommon.'tracker/actions/deleteartifact.php';
493 // Handle the actual delete
496 case 'postdeleteartifact' : {
497 if (!form_key_is_valid(getStringFromRequest('form_key'))) {
498 exit_form_double_submit('tracker');
500 session_require_perm ('tracker', $ath->getID(), 'manager') ;
502 $aid = getStringFromRequest('aid');
503 $ah= new ArtifactHtml($ath,$aid);
504 if (!$ah || !is_object($ah)) {
505 exit_error(_('Artifact Could Not Be Created'),'tracker');
506 } elseif ($ah->isError()) {
507 exit_error($ah->getErrorMessage(),'tracker');
509 if (!getStringFromRequest('confirm_delete')) {
510 $warning_msg .= _('Confirmation failed. Artifact not deleted');
513 if (!$ah->delete(true)) {
514 $error_msg .= _('Artifact Delete Failed') . ': '.$ah->getErrorMessage();
516 $feedback .= _('Artifact Deleted Successfully');
519 include $gfcommon.'tracker/actions/browse.php';
525 include $gfcommon.'tracker/actions/taskmgr.php';
529 include $gfcommon.'tracker/actions/browse.php';
533 include $gfcommon.'tracker/actions/query.php';
537 include $gfcommon.'tracker/actions/csv.php';
540 case 'format_csv' : {
541 include $gfcommon.'tracker/actions/format_csv.php';
544 case 'downloadcsv' : {
545 include $gfcommon.'tracker/actions/downloadcsv.php';
549 $aid = getIntFromRequest('aid');
550 session_redirect('/tracker/download.php?group_id='.$group_id.'&atid='.$atid.'&aid='.$aid.'&file_id='.$file_id);
554 $aid = getIntFromRequest('aid');
557 // users can modify their own tickets in a limited way if they submitted them
558 // even if they are not artifact admins
560 $ah=new ArtifactHtml($ath,$aid);
561 if (!$ah || !is_object($ah)) {
562 exit_error(_('Artifact Could Not Be Created'),'tracker');
563 } elseif ($ah->isError()) {
564 exit_error($ah->getErrorMessage(),'tracker');
566 if (forge_check_perm ('tracker', $ath->getID(), 'manager')) {
567 include $gfcommon.'tracker/actions/mod.php';
568 } elseif (forge_check_perm ('tracker', $ath->getID(), 'tech')) {
569 include $gfcommon.'tracker/actions/mod-limited.php';
571 include $gfcommon.'tracker/actions/detail.php';
577 include $gfcommon.'tracker/actions/browse.php';
584 // c-file-style: "bsd"