5 * Copyright 1999-2001, VA Linux Systems, Inc.
6 * Copyright 2002-2004, GForge, LLC
7 * Copyright 2009, Roland Mas
8 * Copyright (C) 2011 Alain Peyrat - Alcatel-Lucent
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.
26 require_once $gfcommon.'include/Error.class.php';
27 require_once $gfcommon.'tracker/ArtifactExtraFieldElement.class.php';
28 require_once $gfcommon.'tracker/ArtifactStorage.class.php';
31 * Gets an ArtifactType object from the artifact type id
33 * @param artType_id the ArtifactType id
34 * @param res the DB handle if passed in (optional)
35 * @return the ArtifactType object
37 function &artifactType_get_object($artType_id,$res=false) {
38 global $ARTIFACTTYPE_OBJ;
39 if (!isset($ARTIFACTTYPE_OBJ["_".$artType_id."_"])) {
41 //the db result handle was passed in
43 $res = db_query_params ('SELECT * FROM artifact_group_list_vw WHERE group_artifact_id=$1',
44 array ($artType_id)) ;
46 if (!$res || db_numrows($res) < 1 ){
47 $ARTIFACTTYPE_OBJ["_".$artType_id."_"]=false;
49 $data = db_fetch_array($res);
50 $Group = group_get_object($data["group_id"]);
51 $ARTIFACTTYPE_OBJ["_".$artType_id."_"]= new ArtifactType($Group,$data["group_artifact_id"],$data);
54 return $ARTIFACTTYPE_OBJ["_".$artType_id."_"];
57 function artifacttype_get_groupid ($artifact_type_id) {
58 global $ARTIFACTTYPE_OBJ;
59 if (isset($ARTIFACTTYPE_OBJ["_".$artifact_type_id."_"])) {
60 return $ARTIFACTTYPE_OBJ["_".$artifact_type_id."_"]->Group->getID() ;
63 $res = db_query_params ('SELECT group_id FROM artifact_group_list WHERE group_artifact_id=$1',
64 array ($artifact_type_id)) ;
65 if (!$res || db_numrows($res) < 1) {
68 $arr = db_fetch_array ($res);
69 return $arr['group_id'] ;
72 class ArtifactType extends Error {
79 var $Group; //group object
82 * extra_fields 3d array - the IDs and Names of the extra fields
84 * @var array extra_fields;
86 var $extra_fields = array();
89 * extra_field[extra_field_id] array - the IDs and Names of elements on the extra fields
91 * @var array extra_field
96 * Technicians db resource ID.
98 * @var int $technicians_res.
100 var $technicians_res;
103 * Submitters db resource ID.
105 * @var int $submitters_res.
110 * Status db resource ID.
112 * @var int $status_res.
117 * Canned responses resource ID.
119 * @var int $cannecresponses_res.
121 var $cannedresponses_res;
124 * Array of artifact data.
126 * @var array $data_array.
131 * Array of element names so they only have to be fetched once from db.
133 * @var array $data_array.
138 * Array of element status so they only have to be fetched once from db.
140 * @var array $data_array.
145 * ArtifactType - constructor.
147 * @param object The Group object.
148 * @param int The id # assigned to this artifact type in the db.
149 * @param array The associative array of data.
150 * @return boolean success.
152 function __construct($Group,$artifact_type_id=false, $arr=false) {
154 if (!$Group || !is_object($Group)) {
155 $this->setError('No Valid Group Object');
158 if ($Group->isError()) {
159 $this->setError('ArtifactType: '.$Group->getErrorMessage());
162 $this->Group = $Group;
163 if ($artifact_type_id) {
164 if (!$arr || !is_array($arr)) {
165 if (!$this->fetchData($artifact_type_id)) {
169 $this->data_array =& $arr;
170 if ($this->data_array['group_id'] != $this->Group->getID()) {
171 $this->setError('Group_id in db result does not match Group Object');
172 $this->data_array = null;
177 // Make sure they can even access this object
179 if (!forge_check_perm ('tracker', $this->getID(), 'read')) {
180 $this->setPermissionDeniedError();
181 $this->data_array = null;
188 * create - use this to create a new ArtifactType in the database.
190 * @param string The type name.
191 * @param string The type description.
192 * @param bool (1) true (0) false - whether to email on all updates.
193 * @param string The address to send new entries and updates to.
194 * @param int Days before this item is considered overdue.
195 * @param bool (1) trye (0) false - whether the resolution box should be shown.
196 * @param string Free-form string that project admins can place on the submit page.
197 * @param string Free-form string that project admins can place on the browse page.
198 * @param int (1) bug tracker, (2) Support Tracker, (3) Patch Tracker, (4) features (0) other.
199 * @return id on success, false on failure.
201 function create($name,$description,$email_all,$email_address,
202 $due_period,$use_resolution,$submit_instructions,$browse_instructions,$datatype=0) {
204 if (!forge_check_perm('tracker_admin', $this->Group->getID())) {
205 $this->setPermissionDeniedError();
209 if (!$name || !$description || !$due_period) {
210 $this->setError(_('ArtifactType: Name, Description, Due Period, and Status Timeout are required'));
214 if ($email_address) {
215 $invalid_emails = validate_emails($email_address);
216 if (count($invalid_emails) > 0) {
217 $this->SetError(_('E-mail address(es) appeared invalid').': '.implode(',',$invalid_emails));
222 $use_resolution = ((!$use_resolution) ? 0 : $use_resolution);
223 $email_all = ((!$email_all) ? 0 : $email_all);
227 $res = db_query_params ('INSERT INTO
240 ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10)',
241 array ($this->Group->getID(),
242 htmlspecialchars($name),
243 htmlspecialchars($description),
246 $due_period*(60*60*24),
248 htmlspecialchars($submit_instructions),
249 htmlspecialchars($browse_instructions),
252 $id = db_insertid($res,'artifact_group_list','group_artifact_id');
255 $this->setError('ArtifactType: '.db_error());
259 if (!$this->fetchData($id)) {
263 $this->Group->normalizeAllRoles ();
271 * fetchData - re-fetch the data for this ArtifactType from the database.
273 * @param int The artifact type ID.
274 * @return boolean success.
276 function fetchData($artifact_type_id) {
277 $res = db_query_params ('SELECT * FROM artifact_group_list_vw
278 WHERE group_artifact_id=$1
280 array ($artifact_type_id,
281 $this->Group->getID())) ;
282 if (!$res || db_numrows($res) < 1) {
283 $this->setError('ArtifactType: Invalid ArtifactTypeID');
286 $this->data_array = db_fetch_array($res);
287 db_free_result($res);
292 * getGroup - get the Group object this ArtifactType is associated with.
294 * @return Object The Group object.
296 function &getGroup() {
301 * getID - get this ArtifactTypeID.
303 * @return int The group_artifact_id #.
306 return $this->data_array['group_artifact_id'];
310 * getOpenCount - get the count of open tracker items in this tracker type.
312 * @return int The count.
314 function getOpenCount() {
315 return $this->data_array['open_count'];
319 * getTotalCount - get the total number of tracker items in this tracker type.
321 * @return int The total count.
323 function getTotalCount() {
324 return $this->data_array['count'];
328 * getSubmitInstructions - get the free-form string strings.
330 * @return string instructions.
332 function getSubmitInstructions() {
333 return $this->data_array['submit_instructions'];
337 * getBrowseInstructions - get the free-form string strings.
339 * @return string instructions.
341 function getBrowseInstructions() {
342 return $this->data_array['browse_instructions'];
346 * emailAll - determine if we're supposed to email on every event.
348 * @return boolean email_all.
350 function emailAll() {
351 return $this->data_array['email_all_updates'];
355 * emailAddress - defined email address to send events to.
357 * @return string email.
359 function getEmailAddress() {
360 return $this->data_array['email_address'];
364 * getName - the name of this ArtifactType.
366 * @return string name.
369 return $this->data_array['name'];
373 * getFormattedName - formatted name of this ArtifactType
375 * @return string formatted name
377 function getFormattedName() {
378 $name = preg_replace('/[^[:alnum:]]/','',$this->getName());
379 $name = strtolower($name);
384 * getUnixName - returns the name used by email gateway
386 * @return string unix name
388 function getUnixName() {
389 return strtolower($this->Group->getUnixName()).'-'.$this->getFormattedName();
393 * getReturnEmailAddress() - return the return email address for notification emails
395 * @return string return email address
397 function getReturnEmailAddress() {
400 if(forge_get_config('use_gateways')) {
401 $address .= strtolower($this->getUnixName());
403 $address .= 'noreply';
405 $address .= '@'.forge_get_config('web_host');
410 * getDescription - the description of this ArtifactType.
412 * @return string description.
414 function getDescription() {
415 return $this->data_array['description'];
419 * getDuePeriod - how many seconds until it's considered overdue.
421 * @return int seconds.
423 function getDuePeriod() {
424 return $this->data_array['due_period'];
428 * getStatusTimeout - how many seconds until an item is stale.
430 * @return int seconds.
432 function getStatusTimeout() {
433 return $this->data_array['status_timeout'];
437 * getCustomStatusField - return the extra_field_id of the field containing the custom status.
439 * @return int extra_field_id.
441 function getCustomStatusField() {
442 return $this->data_array['custom_status_field'];
446 * setCustomStatusField - set the extra_field_id of the field containing the custom status.
447 * @param int The extra field id.
448 * @return boolean success.
450 function setCustomStatusField($extra_field_id) {
451 $res = db_query_params ('UPDATE artifact_group_list SET custom_status_field=$1
452 WHERE group_artifact_id=$2',
453 array ($extra_field_id,
459 * usesCustomStatuses - boolean
461 * @return boolean use_custom_statues.
463 function usesCustomStatuses() {
464 return $this->getCustomStatusField();
468 * remap status - pass the extra_fields array and return the status_id, either open/closed
469 * @param int The status_id
470 * @param array Complex array of extra_field_data
471 * @return int status_id.
473 function remapStatus($status_id,$extra_fields) {
474 if ($this->usesCustomStatuses()) {
475 //get the selected element for the extra_field_status element
476 $csfield = $this->getCustomStatusField();
477 if (array_key_exists($csfield, $extra_fields)) {
478 $element_id=$extra_fields[$csfield];
480 //convert that element_id into the status_id
481 $res = db_query_params ('SELECT status_id FROM artifact_extra_field_elements WHERE element_id=$1',
482 array ($element_id)) ;
484 $this->setError('Error Remapping Status: '.db_error());
487 $status_id=db_result($res,0,'status_id');
489 // custom status was not passed... use the first status from the database
490 $res = db_query_params ('SELECT status_id FROM artifact_extra_field_elements WHERE extra_field_id=$1 ORDER BY element_id ASC LIMIT 1 OFFSET 0',
492 if (db_numrows($res) == 0) { // No values available
493 $this->setError('Error Remapping Status');
496 $status_id=db_result($res,0,'status_id');
499 if ($status_id < 1 || $status_id > 4) {
500 echo "INVALID STATUS REMAP: $status_id FROM SELECTED ELEMENT: $element_id";
510 * getDataType - flag that is generally unused but can mark the difference between bugs, patches, etc.
512 * @return int The type (1) bug (2) support (3) patch (4) feature (0) other.
514 function getDataType() {
515 return $this->data_array['datatype'];
519 * setMonitor - user can monitor this artifact.
521 * @return false - always false - always use the getErrorMessage() for feedback
523 function setMonitor ($user_id = -1) {
524 if ($user_id == -1) {
525 if (!session_loggedin()) {
526 $this->setError(_('You can only monitor if you are logged in'));
529 $user_id = user_getid() ;
532 $res = db_query_params ('SELECT * FROM artifact_type_monitor WHERE group_artifact_id=$1 AND user_id=$2',
533 array ($this->getID(),
535 if (!$res || db_numrows($res) < 1) {
537 $res = db_query_params ('INSERT INTO artifact_type_monitor (group_artifact_id,user_id) VALUES ($1,$2)',
538 array ($this->getID(),
541 $this->setError(db_error());
544 $this->setError(_('Now Monitoring Tracker'));
548 //already monitoring - remove their monitor
549 db_query_params ('DELETE FROM artifact_type_monitor
550 WHERE group_artifact_id=$1
552 array ($this->getID(),
554 $this->setError(_('Tracker Monitoring Deactivated'));
559 function isMonitoring() {
560 if (!session_loggedin()) {
563 $result = db_query_params ('SELECT count(*) AS count FROM artifact_type_monitor
564 WHERE user_id=$1 AND group_artifact_id=$2',
567 $row_count = db_fetch_array($result);
568 return $result && $row_count['count'] > 0;
572 * getMonitorIds - array of email addresses monitoring this Artifact.
574 * @return array of email addresses monitoring this Artifact.
576 function &getMonitorIds() {
577 $res = db_query_params ('SELECT user_id FROM artifact_type_monitor WHERE group_artifact_id=$1',
578 array ($this->getID())) ;
579 return util_result_column_to_array($res);
583 * getExtraFields - List of possible user built extra fields
584 * set up for this artifact type.
586 * @return arrays of data;
588 function getExtraFields($types=array()) {
590 $filter = implode(',', $types);
591 $types = explode(',', $filter);
595 if (!isset($this->extra_fields["$filter"])) {
596 $this->extra_fields["$filter"] = array();
598 $res = db_query_params ('SELECT *
599 FROM artifact_extra_field_list
600 WHERE group_artifact_id=$1
601 AND field_type = ANY ($2)
602 ORDER BY field_type ASC',
603 array ($this->getID(),
604 db_int_array_to_any_clause ($types))) ;
606 $res = db_query_params ('SELECT *
607 FROM artifact_extra_field_list
608 WHERE group_artifact_id=$1
609 ORDER BY field_type ASC',
610 array ($this->getID())) ;
612 while($arr = db_fetch_array($res)) {
613 $this->extra_fields["$filter"][$arr['extra_field_id']] = $arr;
617 return $this->extra_fields["$filter"];
621 * cloneFieldsFrom - clone all the fields and elements from another tracker
623 * @return boolean true/false on success
625 function cloneFieldsFrom($clone_tracker_id) {
627 $g =& group_get_object(forge_get_config('template_group'));
628 if (!$g || !is_object($g)) {
629 $this->setError('Could Not Get Template Group');
631 } elseif ($g->isError()) {
632 $this->setError('Template Group Error '.$g->getErrorMessage());
635 $at = new ArtifactType($g,$clone_tracker_id);
636 if (!$at || !is_object($at)) {
637 $this->setError('Could Not Get Tracker To Clone');
639 } elseif ($at->isError()) {
640 $this->setError('Clone Tracker Error '.$at->getErrorMessage());
643 $efs = $at->getExtraFields();
646 // Iterate list of extra fields
649 foreach ($efs as $ef) {
650 //new field in this tracker
651 $nef = new ArtifactExtraField($this);
652 if (!$nef->create( util_unconvert_htmlspecialchars($ef['field_name']), $ef['field_type'], $ef['attribute1'], $ef['attribute2'], $ef['is_required'], $ef['alias'])) {
653 $this->setError('Error Creating New Extra Field: '.$nef->getErrorMessage());
658 // Iterate the elements
660 $resel = db_query_params ('SELECT * FROM artifact_extra_field_elements WHERE extra_field_id=$1',
661 array ($ef['extra_field_id'])) ;
662 while ($el = db_fetch_array($resel)) {
664 $nel = new ArtifactExtraFieldElement($nef);
665 if (!$nel->create( util_unconvert_htmlspecialchars($el['element_name']), $el['status_id'] )) {
667 $this->setError('Error Creating New Extra Field Element: '.$nel->getErrorMessage());
678 * getExtraFieldName - Get a box name using the box ID
680 * @param int id of an extra field.
681 * @return string name of extra field.
683 function getExtraFieldName($extra_field_id) {
684 $arr = $this->getExtraFields();
685 return $arr[$extra_field_id]['field_name'];
689 * getExtraFieldElements - List of possible admin configured
690 * extra field elements. This function is used to
691 * present the boxes and choices on the main Add/Update page.
693 * @param int id of the extra field
694 * @return array of elements for this extra field.
696 function getExtraFieldElements($id) {
701 if (!isset($this->extra_field[$id])) {
702 $this->extra_field[$id] = array();
703 $res = db_query_params ('SELECT element_id,element_name,status_id
704 FROM artifact_extra_field_elements
705 WHERE extra_field_id = $1
706 ORDER BY element_pos ASC, element_id ASC',
709 while($arr = db_fetch_array($res)) {
710 $this->extra_field[$id][$i++] = $arr;
712 // if (count($this->extra_field[$id]) == 0) {
717 return $this->extra_field[$id];
721 * getElementName - get the name of a particular element.
723 * @return string The name.
725 function getElementName($choiceid) {
729 if (is_array($choiceid)) {
730 $choiceid=implode(',', array_map('intval', $choiceid));
732 $choiceid=intval($choiceid);
734 if ($choiceid == 100) {
737 if (!isset($this->element_name["$choiceid"])) {
738 $res = db_query_params ('SELECT element_id,extra_field_id,element_name
739 FROM artifact_extra_field_elements
740 WHERE element_id = ANY ($1)',
741 array (db_int_array_to_any_clause (explode (',', $choiceid)))) ;
742 if (db_numrows($res) > 1) {
743 $arr=util_result_column_to_array($res,2);
744 $this->element_name["$choiceid"]=implode(',',$arr);
746 $this->element_name["$choiceid"]=db_result($res,0,'element_name');
749 return $this->element_name["$choiceid"];
753 * getElementStatusID - get the status of a particular element.
755 * @return int The status
757 function getElementStatusID($choiceid) {
761 if (is_array($choiceid)) {
762 $choiceid=implode(',',$choiceid);
764 if ($choiceid == 100) {
767 if (!$this->element_status["$choiceid"]) {
768 $res = db_query_params ('SELECT element_id,extra_field_id,status_id
769 FROM artifact_extra_field_elements
770 WHERE element_id = ANY ($1)',
771 array (db_int_array_to_any_clause (explode (',', $choiceid)))) ;
772 if (db_numrows($res) > 1) {
773 $arr=util_result_column_to_array($res,2);
774 $this->element_status["$choiceid"]=implode(',',$arr);
776 $this->element_status["$choiceid"]=db_result($res,0,'status_id');
779 return $this->element_status["$choiceid"];
784 * delete - delete this tracker and all its related data.
786 * @param bool I'm Sure.
787 * @param bool I'm REALLY sure.
788 * @return bool true/false;
790 function delete($sure, $really_sure) {
791 if (!$sure || !$really_sure) {
792 $this->setMissingParamsError(_('Please tick all checkboxes.'));
795 if (!forge_check_perm ('tracker_admin', $this->Group->getID())) {
796 $this->setPermissionDeniedError();
800 db_query_params ('DELETE FROM artifact_extra_field_data
801 WHERE EXISTS (SELECT artifact_id FROM artifact
802 WHERE group_artifact_id=$1
803 AND artifact.artifact_id=artifact_extra_field_data.artifact_id)',
804 array ($this->getID())) ;
805 //echo '0.1'.db_error();
806 db_query_params ('DELETE FROM artifact_extra_field_elements
807 WHERE EXISTS (SELECT extra_field_id FROM artifact_extra_field_list
808 WHERE group_artifact_id=$1
809 AND artifact_extra_field_list.extra_field_id = artifact_extra_field_elements.extra_field_id)',
810 array ($this->getID())) ;
811 //echo '0.2'.db_error();
812 db_query_params ('DELETE FROM artifact_extra_field_list
813 WHERE group_artifact_id=$1',
814 array ($this->getID())) ;
815 //echo '0.3'.db_error();
816 db_query_params ('DELETE FROM artifact_canned_responses
817 WHERE group_artifact_id=$1',
818 array ($this->getID())) ;
819 //echo '1'.db_error();
820 db_query_params ('DELETE FROM artifact_counts_agg
821 WHERE group_artifact_id=$1',
822 array ($this->getID())) ;
823 //echo '5'.db_error();
825 ArtifactStorage::instance()->deleteFromQuery('SELECT id FROM artifact_file
826 WHERE EXISTS (SELECT artifact_id FROM artifact
827 WHERE group_artifact_id=$1
828 AND artifact.artifact_id=artifact_file.artifact_id)',
829 array ($this->getID())) ;
831 db_query_params ('DELETE FROM artifact_file
832 WHERE EXISTS (SELECT artifact_id FROM artifact
833 WHERE group_artifact_id=$1
834 AND artifact.artifact_id=artifact_file.artifact_id)',
835 array ($this->getID())) ;
836 //echo '6'.db_error();
837 db_query_params ('DELETE FROM artifact_message
838 WHERE EXISTS (SELECT artifact_id FROM artifact
839 WHERE group_artifact_id=$1
840 AND artifact.artifact_id=artifact_message.artifact_id)',
841 array ($this->getID())) ;
842 //echo '7'.db_error();
843 db_query_params ('DELETE FROM artifact_history
844 WHERE EXISTS (SELECT artifact_id FROM artifact
845 WHERE group_artifact_id=$1
846 AND artifact.artifact_id=artifact_history.artifact_id)',
847 array ($this->getID())) ;
848 //echo '8'.db_error();
849 db_query_params ('DELETE FROM artifact_monitor
850 WHERE EXISTS (SELECT artifact_id FROM artifact
851 WHERE group_artifact_id=$1
852 AND artifact.artifact_id=artifact_monitor.artifact_id)',
853 array ($this->getID())) ;
854 //echo '9'.db_error();
855 db_query_params ('DELETE FROM artifact
856 WHERE group_artifact_id=$1',
857 array ($this->getID())) ;
858 //echo '4'.db_error();
859 db_query_params ('DELETE FROM artifact_group_list
860 WHERE group_artifact_id=$1',
861 array ($this->getID())) ;
862 //echo '11'.db_error();
865 ArtifactStorage::instance()->commit();
867 $this->Group->normalizeAllRoles () ;
873 * getSubmitters - returns a result set of submitters.
875 * @return database result set.
877 function getSubmitters() {
878 if (!isset($this->submitters_res)) {
879 $this->submitters_res = db_query_params ('SELECT DISTINCT submitted_by, submitted_realname
881 WHERE group_artifact_id=$1
882 ORDER BY submitted_realname',
883 array ($this->getID()));
885 return $this->submitters_res;
889 * getCannedResponses - returns a result set of canned responses.
891 * @return database result set.
893 function getCannedResponses() {
894 if (!isset($this->cannedresponses_res)) {
895 $this->cannedresponses_res = db_query_params ('SELECT id,title
896 FROM artifact_canned_responses
897 WHERE group_artifact_id=$1',
898 array ($this->getID()));
900 return $this->cannedresponses_res;
904 * getStatuses - returns a result set of statuses.
906 * These statuses are either the default open/closed or any number of
907 * custom statuses that are stored in the extra fields. On insert/update
908 * to an artifact the status_id is remapped from the extra_field_element_id to
909 * the standard open/closed id.
911 * @param boolean Whether to show the real statuses or not.
912 * @return database result set.
914 function getStatuses() {
915 if (!isset($this->status_res)) {
916 $this->status_res = db_query_params ('SELECT * FROM artifact_status',array());
918 return $this->status_res;
922 * getStatusName - returns the name of this status.
924 * @param int The status ID.
925 * @return string name.
927 function getStatusName($id) {
928 $result = db_query_params ('select status_name from artifact_status WHERE id=$1',
930 if ($result && db_numrows($result) > 0) {
931 return db_result($result,0,'status_name');
933 return 'Error - Not Found';
938 * update - use this to update this ArtifactType in the database.
940 * @param string The item name.
941 * @param string The item description.
942 * @param bool (1) true (0) false - whether to email on all updates.
943 * @param string The address to send new entries and updates to.
944 * @param int Days before this item is considered overdue.
945 * @param int Days before stale items time out.
946 * @param bool (1) true (0) false - whether the resolution box should be shown.
947 * @param string Free-form string that project admins can place on the submit page.
948 * @param string Free-form string that project admins can place on the browse page.
949 * @return true on success, false on failure.
951 function update($name,$description,$email_all,$email_address,
952 $due_period, $status_timeout,$use_resolution,$submit_instructions,$browse_instructions) {
954 if (!forge_check_perm ('tracker_admin', $this->Group->getID())) {
955 $this->setPermissionDeniedError();
959 if ($this->getDataType()) {
960 $name=$this->getName();
961 $description=$this->getDescription();
964 if (!$name || !$description || !$due_period || !$status_timeout) {
965 $this->setError(_('ArtifactType: Name, Description, Due Period, and Status Timeout are required'));
969 $result = db_query_params('SELECT count(*) AS count FROM artifact_group_list WHERE group_id=$1 AND name=$2 AND group_artifact_id!=$3',
970 array ($this->Group->getID(), $name, $this->getID()));
972 $this->setError('ArtifactType::Update(): '.db_error());
975 if (db_result($result, 0, 'count')) {
976 $this->setError(_('Tracker name already used'));
980 if ($email_address) {
981 $invalid_emails = validate_emails($email_address);
982 if (count($invalid_emails) > 0) {
983 $this->SetError(_('E-mail address(es) appeared invalid').': '.implode(',',$invalid_emails));
988 $email_all = ((!$email_all) ? 0 : $email_all);
989 $use_resolution = ((!$use_resolution) ? 0 : $use_resolution);
991 $res = db_query_params ('UPDATE artifact_group_list SET
994 email_all_updates=$3,
998 submit_instructions=$7,
999 browse_instructions=$8
1000 WHERE group_artifact_id=$9 AND group_id=$10',
1002 htmlspecialchars($name),
1003 htmlspecialchars($description),
1006 $due_period * (60*60*24),
1007 $status_timeout * (60*60*24),
1008 htmlspecialchars($submit_instructions),
1009 htmlspecialchars($browse_instructions),
1011 $this->Group->getID())) ;
1013 if (!$res || db_affected_rows($res) < 1) {
1014 $this->setError('ArtifactType::Update(): '.db_error());
1017 $this->fetchData($this->getID());
1023 * getBrowseList - get the free-form string strings.
1025 * @return string instructions.
1027 function getBrowseList() {
1028 $list = $this->data_array['browse_list'];
1030 // remove status_id in the browse list if a custom status exists
1031 if (count($this->getExtraFields(array(ARTIFACT_EXTRAFIELDTYPE_STATUS))) > 0) {
1032 $arr = explode(',', $list);
1033 $idx = array_search('status_id', $arr);
1034 if($idx !== False) {
1035 array_splice($arr, $idx, 1);
1037 return join(',', $arr);
1044 * setCustomStatusField - set the extra_field_id of the field containing the custom status.
1045 * @param int The extra field id.
1046 * @return boolean success.
1048 function setBrowseList($list) {
1049 $res=db_query_params ('UPDATE artifact_group_list
1051 WHERE group_artifact_id=$2',
1054 $this->fetchData($this->getID());
1062 // c-file-style: "bsd"