Main Page | Directories | File List | File Members

data.php

Go to the documentation of this file.
00001 <?php
00002 # This file is part of the Savane project
00003 # <http://gna.org/projects/savane/>
00004 #
00005 # $Id: data.php 5387 2006-02-15 15:21:25Z yeupou $
00006 #
00007 #  Copyright 1999-2000 (c) The SourceForge Crew
00008 #  Copyright 2001-2002 (c) Laurent Julliard, CodeX Team, Xerox
00009 #
00010 #  Copyright 2003-2005 (c) Mathieu Roy <yeupou--gnu.org>
00011 #                          Yves Perrin <yves.perrin--cern.ch>
00012 #
00013 #
00014 # The Savane project is free software; you can redistribute it and/or
00015 # modify it under the terms of the GNU General Public License
00016 # as published by the Free Software Foundation; either version 2
00017 # of the License, or (at your option) any later version.
00018 #
00019 # The Savane project is distributed in the hope that it will be useful,
00020 # but WITHOUT ANY WARRANTY; without even the implied warranty of
00021 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00022 # GNU General Public License for more details.
00023 #
00024 # You should have received a copy of the GNU General Public License
00025 # along with the Savane project; if not, write to the Free Software
00026 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00027 
00028 
00029 /*
00030 
00031 Simple way of wrapping our SQL so it can be
00032         shared among the XML outputs and the PHP web front-end
00033 
00034         Also abstracts controls to update data
00035 
00036 */
00037 function trackers_data_get_all_fields ($group_id=false,$reload=false)
00038 {
00039 
00040   /*
00041            Get all the possible bug fields for this project both used and unused. If
00042            used then show the project specific information about field usage
00043            otherwise show the default usage parameter
00044            Make sure array element are sorted by ascending place
00045   */
00046 
00047   global $BF_USAGE_BY_ID,$BF_USAGE_BY_NAME, $AT_START;
00048 
00049   # Do nothing if already set and reload not forced
00050   if (isset($BF_USAGE_BY_ID) && !$reload)
00051     {
00052       return;
00053     }
00054 
00055   # Clean up the array
00056   $BF_USAGE_BY_ID=array();
00057   $BF_USAGE_BY_NAME=array();
00058 
00059   # First get the all the defaults.
00060   $sql='SELECT '.ARTIFACT.'_field.bug_field_id, field_name, display_type, '.
00061      'display_size,label, description,scope,required,empty_ok,keep_history,special, custom, '.
00062      'group_id, use_it,show_on_add,show_on_add_members, place, custom_label,'.
00063      'custom_description,custom_display_size,custom_empty_ok,custom_keep_history '.
00064      'FROM '.ARTIFACT.'_field, '.ARTIFACT.'_field_usage '.
00065      'WHERE group_id=100  '.
00066      'AND  '.ARTIFACT.'_field.bug_field_id='.ARTIFACT.'_field_usage.bug_field_id ';
00067 
00068   $res_defaults = db_query($sql);
00069 
00070   # Now put all used fields in a global array for faster access
00071   # Index both by field_name and bug_field_id
00072   while ($field_array = db_fetch_array($res_defaults))
00073     {
00074       $BF_USAGE_BY_ID[$field_array['bug_field_id'] ] = $field_array;
00075       $BF_USAGE_BY_NAME[$field_array['field_name'] ] = $field_array;
00076     }
00077 
00078   # Then select  all project specific entries
00079   $sql='SELECT  '.ARTIFACT.'_field.bug_field_id, field_name, display_type, '.
00080      'display_size,label, description,scope,required,empty_ok,keep_history,special, custom, '.
00081      'group_id, use_it, show_on_add, show_on_add_members, place, custom_label,'.
00082      'custom_description,custom_display_size,custom_empty_ok,custom_keep_history '.
00083      'FROM '.ARTIFACT.'_field,  '.ARTIFACT.'_field_usage '.
00084      'WHERE group_id='.$group_id.
00085      ' AND  '.ARTIFACT.'_field.bug_field_id= '.ARTIFACT.'_field_usage.bug_field_id ';
00086 
00087 
00088   $res_project = db_query($sql);
00089 
00090   # And override entries in the default array
00091   while ($field_array = db_fetch_array($res_project))
00092     {
00093       $BF_USAGE_BY_ID[$field_array['bug_field_id'] ] = $field_array;
00094       $BF_USAGE_BY_NAME[$field_array['field_name'] ] = $field_array;
00095     }
00096 
00097   #Debug code
00098   #print "<br />DBG - At end of bug_get_all_fields: $rows";
00099   #reset($BF_USAGE_BY_NAME);
00100   #while (list($key, $val) = each($BF_USAGE_BY_NAME))
00101   #{
00102   #print "<br />DBG - $key -> use_it: $val[use_it], $val[place]";
00103   #}
00104 
00105   # rewind internal pointer of global arrays
00106   reset($BF_USAGE_BY_ID);
00107   reset($BF_USAGE_BY_NAME);
00108   $AT_START = true;
00109 }
00110 
00111 
00112 function trackers_data_get_item_group($item_id)
00113 {
00114   return  db_result(
00115                     db_query("SELECT group_id FROM ".ARTIFACT." WHERE bug_id='$item_id'"),
00116                     0,
00117                     'group_id');
00118 }
00119 
00120 function &trackers_data_get_notification_settings($group_id, $tracker_name)
00121 {
00122   $result = db_query("SELECT * FROM groups WHERE group_id=$group_id");
00123   if (db_numrows($result) < 1)
00124     {
00125       exit_no_group();
00126     }
00127 
00128   $settings = array();
00129 
00130   $settings['glnotif'] = db_result($result,0,$tracker_name."_glnotif");
00131   $settings['glsendall'] = db_result($result,0,"send_all_".$tracker_name);
00132   $settings['glnewad'] = db_result($result,0,"new_".$tracker_name."_address");
00133   $settings['private_exclude'] = db_result($result,0,$tracker_name."_private_exclude_address");
00134 
00135   $cat_field_name = "category_id";
00136   # Warning: The hardcoded fiels names: bug_fv_id and bug_field_id will need to be changed
00137   #          one day to generic names since they apply to bugs but also to suuports,tasks,
00138   #          and patch related tables. For now these fileds are called bug_xxx whatever
00139   #          the service related tables. Too much work to make all the changes in the code.
00140   $sql="SELECT ".$tracker_name."_field_value.bug_fv_id,".$tracker_name."_field_value.value,".$tracker_name."_field_value.email_ad,".$tracker_name."_field_value.send_all_flag ".
00141     "FROM ".$tracker_name."_field, ".$tracker_name."_field_value ".
00142     "WHERE ".$tracker_name."_field_value.group_id='$group_id' ".
00143     "AND ".$tracker_name."_field.field_name='$cat_field_name' ".
00144     "AND ".$tracker_name."_field_value.bug_field_id=".$tracker_name."_field.bug_field_id ".
00145     "AND ".$tracker_name."_field_value.status!='H'";
00146 
00147   $result=db_query($sql);
00148   $settings['nb_categories']=db_numrows($result);
00149   $settings['category'] = array();
00150   for ($i=0; $i < $settings['nb_categories'] ; $i++) {
00151 
00152     $settings['category'][$i] = array();
00153     $settings['category'][$i]['name'] = db_result($result, $i, 'value');
00154     $settings['category'][$i]['fv_id'] = db_result($result, $i, 'bug_fv_id');
00155     $email = db_result($result, $i, 'email_ad');
00156     if ($email == '100')
00157       { $email = ""; }
00158     $settings['category'][$i]['email'] = $email;
00159     $settings['category'][$i]['send_all_flag'] = db_result($result, $i, 'send_all_flag');
00160   }
00161   return $settings;
00162 }
00163 
00164 function trackers_data_show_notification_settings($group_id, $tracker_name, $show_intro_msg)
00165 {
00166   $grtrsettings = &trackers_data_get_notification_settings($group_id, $tracker_name);
00167 
00168   if (user_ismember($group_id,'A'))
00169     {
00170       if ($grtrsettings['glnotif'] == 0) {
00171         $categoryradio = "CHECKED";
00172         $globalradio = "";
00173         $bothradio = "";
00174       }
00175       if ($grtrsettings['glnotif'] == 1) {
00176         $categoryradio = "";
00177         $globalradio = "CHECKED";
00178         $bothradio = "";
00179       }
00180       if ($grtrsettings['glnotif'] == 2) {
00181         $categoryradio = "";
00182         $globalradio = "";
00183         $bothradio = "CHECKED";
00184       }
00185       if ($grtrsettings['nb_categories'] > 0) {
00186         if ($show_intro_msg != 0) {
00187           print '<p>'.sprintf(_("As a project administrator you must decide if the list of persons to be systematically notified on new %s submissions (and possibly updates) depend on the categories or not and you must provide the corresponding email addresses (comma separated list)."), $tracker_name).'</p>';
00188 
00189         }
00190         print '
00191            <INPUT TYPE="RADIO" NAME="'.$tracker_name.'_notif_scope" VALUE="global" '.$globalradio.' />&nbsp;&nbsp;<span class="preinput">'._("Notify persons in the global list only").'</span><br />
00192           <INPUT TYPE="RADIO" NAME="'.$tracker_name.'_notif_scope" VALUE="category" '.$categoryradio.' />&nbsp;&nbsp;<span class="preinput">'._("Notify persons in the category related list instead of the global list").'</span><br />
00193           <INPUT TYPE="RADIO" NAME="'.$tracker_name.'_notif_scope" VALUE="both" '.$bothradio.' />&nbsp;&nbsp;<span class="preinput">'._("Notify persons in the category related list in addition to the global list").'</span><br />
00194 
00195 
00196           <h4>'._("Category related lists").'</h4>';
00197         print '<INPUT TYPE="HIDDEN" NAME="'.$tracker_name.'_nb_categories" VALUE="'.$grtrsettings['nb_categories'].'" />';
00198 
00199         for ($i=0; $i < $grtrsettings['nb_categories'] ; $i++)
00200           {
00201             print '<INPUT TYPE="HIDDEN" NAME="'.$tracker_name.'_cat_'.$i.'_bug_fv_id" VALUE="'.$grtrsettings['category'][$i]['fv_id'].'" />';
00202             print '<span class="preinput">'.$grtrsettings['category'][$i]['name'].'</span><br />&nbsp;&nbsp;<INPUT TYPE="TEXT" NAME="'.$tracker_name.'_cat_'.$i.'_email" VALUE="'.$grtrsettings['category'][$i]['email'].'" SIZE="50" MAXLENGTH="255" />
00203           &nbsp;&nbsp;<span class="preinput">(
00204           <INPUT TYPE="CHECKBOX" NAME="'.$tracker_name.'_cat_'.$i.'_send_all_flag" VALUE="1" '. (($grtrsettings['category'][$i]['send_all_flag'])?'checked="checked"':'') .' />'._("Send on all updates").')</span><br />
00205 ';
00206           }
00207 
00208         print '<h4>'._("Global list").'</h4>';
00209 
00210       } else {
00211         if ($show_intro_msg != 0) {
00212           print '<p>'.sprintf(_("As a project administrator you must decide if the list of persons to be systematically notified on new %s submissions (and possibly updates) depend on the categories or not and you must provide the corresponding email addresses (comma separated list)."), $tracker_name).'</p>';
00213         }
00214       }
00215       print '<span class="preinput">'._("Global List:").'</span><br />&nbsp;&nbsp;<INPUT TYPE="TEXT" NAME="'.$tracker_name.'_new_item_address" VALUE="'.$grtrsettings['glnewad'].'" SIZE="50" MAXLENGTH="255" />
00216       &nbsp;&nbsp;<span class="preinput">(<INPUT TYPE="CHECKBOX" NAME="'.$tracker_name.'_send_all_changes" VALUE="1" '. (($grtrsettings['glsendall'])?'CHECKED':'') .'>'._("Send on all updates").')</span>';
00217 
00218         print '<h4>'._("Private items exclude list").'</h4>';
00219         if ($show_intro_msg != 0) {
00220           print '<p>'._("Addresses registered in this list will be excluded from default mail notification for private items.").'</p>';
00221         }
00222 
00223         print '<span class="preinput">'._("Exclude List:").'</span><br />&nbsp;&nbsp;<INPUT TYPE="TEXT" NAME="'.$tracker_name.'_private_exclude_address" VALUE="'.$grtrsettings['private_exclude'].'" SIZE="50" MAXLENGTH="255" /><br />';
00224 
00225     }
00226 }
00227 
00228 function trackers_data_post_notification_settings($group_id, $tracker_name)
00229 {
00230 
00231   global $feedback;
00232 
00233   $local_feedback = "";
00234   # build the variable names related to elements always present in the form
00235   # and get their values
00236 
00237   $notif_scope_name = $tracker_name."_notif_scope";
00238   $notif_scope = $GLOBALS[$notif_scope_name];
00239   $new_item_address_name = $tracker_name."_new_item_address";
00240   $new_item_address = $GLOBALS[$new_item_address_name];
00241   $send_all_changes_name = $tracker_name."_send_all_changes";
00242   $send_all_changes = $GLOBALS[$send_all_changes_name];
00243   $nb_categories_name = $tracker_name."_nb_categories";
00244   $nb_categories = $GLOBALS[$nb_categories_name];
00245   $private_exclude_address_name = $tracker_name."_private_exclude_address";
00246   $private_exclude_address = $GLOBALS[$private_exclude_address_name];
00247 
00248   if ($notif_scope != "global") {
00249     if ($notif_scope == "category") {
00250       $notif_value = 0;
00251     }
00252     if ($notif_scope == "both") {
00253       $notif_value = 2;
00254     }
00255   } else {
00256     $notif_value = 1;
00257   }
00258 
00259   # set global notification info for this group
00260   $res_gl=db_query("UPDATE groups SET "
00261         .$tracker_name."_glnotif='$notif_value', "
00262         ."send_all_".$tracker_name."='$send_all_changes', "
00263         ."new_".$tracker_name."_address=".($new_item_address? "'$new_item_address' " : "''").", "
00264         .$private_exclude_address_name.'='.($private_exclude_address? "'$private_exclude_address' " : "''")
00265         . " WHERE group_id=$group_id");
00266   if (!$res_gl)
00267     { $local_feedback .= _("groups table Update failed.").' '.db_error(); }
00268 
00269   $ok = 0;
00270   if ($nb_categories > 0) {
00271     for ($i=0; $i<$nb_categories; $i++) {
00272       $current_fv_name = $tracker_name."_cat_".$i."_bug_fv_id";
00273       $current_fv_id = $GLOBALS[$current_fv_name];
00274       $current_email_name = $tracker_name."_cat_".$i."_email";
00275       $current_email = $GLOBALS[$current_email_name];
00276 #      if ($current_email && !validate_email($current_email))
00277 #        {
00278 #          $local_feedback .= _("[".$tracker_name."]  notification address: ".$current_email." appeared Invalid");
00279 #          $current_email='';
00280 #        }
00281       $current_send_all_name = $tracker_name."_cat_".$i."_send_all_flag";
00282       $current_send_all_flag = $GLOBALS[$current_send_all_name];
00283 
00284       $res_cat=db_query("UPDATE ".$tracker_name."_field_value SET "
00285              ."email_ad='$current_email', "
00286              ."send_all_flag='$current_send_all_flag' "
00287              ." WHERE bug_fv_id=$current_fv_id");
00288       if ($res_cat) {
00289         $ok++;
00290       } else {
00291         $local_feedback .= _($tracker_name."_field_value table Update failed.").' '.db_error();
00292       }
00293     }
00294   }
00295   if (($res_gl) && ($ok == $nb_categories) && ($local_feedback == ""))  {
00296     return 1;
00297   } else {
00298     if ($local_feedback != "") { fb($local_feedback); }
00299     return 0;
00300   }
00301 }
00302 
00303 function trackers_data_get_item_notification_info($item_id, $artifact, $updated)
00304 {
00305   $emailad = "";
00306   $sendemail = 0;
00307   # Get group information bur new entity notification settings
00308   $sql="SELECT groups.$artifact"."_glnotif, groups.send_all_"."$artifact, groups.new_"."$artifact"."_address ".
00309      "FROM "."$artifact, groups ".
00310      "WHERE "."$artifact.bug_id='$item_id' ".
00311      "AND groups.group_id="."$artifact.group_id";
00312   $result=db_query($sql);
00313 
00314   $glnotif = db_result($result,0,$artifact."_glnotif");
00315   $glsendall = db_result($result,0,"send_all_".$artifact);
00316   $glnewad = db_result($result,0,"new_".$artifact."_address");
00317   if ($glnotif != 1) {   # if not 'global only'
00318     $cat_field_name = "category_id";
00319 
00320     $sql="SELECT "."$artifact"."_field_value.email_ad, "."$artifact"."_field_value.send_all_flag ".
00321        "FROM "."$artifact"."_field_value, "."$artifact"."_field, $artifact ".
00322        "WHERE "."$artifact.bug_id='$item_id' ".
00323        "AND "."$artifact"."_field.field_name='$cat_field_name' ".
00324        "AND "."$artifact"."_field_value.bug_field_id="."$artifact"."_field.bug_field_id ".
00325        "AND "."$artifact"."_field_value.group_id="."$artifact.group_id ".
00326        "AND "."$artifact"."_field_value.value_id="."$artifact.category_id";
00327 
00328     $result=db_query($sql);
00329     $rows=db_numrows($result);
00330     if ($rows > 0) {
00331       $sendallflag = db_result($result, 0, 'send_all_flag');
00332       if (($updated == 0) || (($updated == 1) && ($sendallflag == 1))) {
00333         $emailad .= db_result($result, 0, 'email_ad');
00334       }
00335     } else {
00336       # could be that administrator closes category notification and forgot
00337       # to define categories BUT in most cases it means the submitter selected
00338       # the 'NONE' category for this bug
00339       if (($updated == 0) || (($updated == 1) && ($glsendall == 1))) {
00340         $emailad .= $glnewad;
00341       }
00342     }
00343   }
00344   if ($glnotif > 0) {   # if not 'category only'
00345     if (($updated == 0) || (($updated == 1) && ($glsendall == 1))) {
00346       if ($emailad != "") {
00347         $emailad .= ',';
00348       }
00349       $emailad .= $glnewad;
00350     }
00351   }
00352   if (trim($emailad) != "") {
00353     $sendemail = 1;
00354   }
00355   #  print "EMAILAD=$emailad SENDEMAIL=$sendemail";
00356   return array($emailad, $sendemail);
00357 }
00358 
00359 
00360 function cmp_place($ar1, $ar2)
00361 {
00362   if ($ar1['place']< $ar2['place'])
00363     return -1;
00364   else if ($ar1['place']>$ar2['place'])
00365     return 1;
00366   return 0;
00367 }
00368 
00369 function cmp_place_query($ar1, $ar2)
00370 {
00371   if ($ar1['place_query']< $ar2['place_query'])
00372     return -1;
00373   else if ($ar1['place_query']>$ar2['place_query'])
00374     return 1;
00375   return 0;
00376 }
00377 
00378 function cmp_place_result($ar1, $ar2)
00379 {
00380   if ($ar1['place_result']< $ar2['place_result'])
00381     return -1;
00382   else if ($ar1['place_result']>$ar2['place_result'])
00383     return 1;
00384   return 0;
00385 }
00386 
00387 function trackers_data_get_all_report_fields($group_id=false,$report_id=100)
00388 {
00389   global $BF_USAGE_BY_ID,$BF_USAGE_BY_NAME;
00390 
00391   /*
00392            Get all the bug fields involved in the bug report.
00393            WARNING: This function ust only be called after bug_init()
00394   */
00395 
00396   # Build the list of fields involved in this report
00397   $sql = "SELECT * FROM ".ARTIFACT."_report_field WHERE report_id='".safeinput($report_id)."'";
00398   $res = db_query($sql);
00399 
00400   while ($arr = db_fetch_array($res))
00401     {
00402       $field = $arr['field_name'];
00403       $field_id = trackers_data_get_field_id($field);
00404       $BF_USAGE_BY_NAME[$field]['show_on_query'] =
00405          $BF_USAGE_BY_ID[$field_id]['show_on_query'] = $arr['show_on_query'];
00406 
00407       $BF_USAGE_BY_NAME[$field]['show_on_result'] =
00408          $BF_USAGE_BY_ID[$field_id]['show_on_result'] = $arr['show_on_result'];
00409 
00410       $BF_USAGE_BY_NAME[$field]['place_query'] =
00411          $BF_USAGE_BY_ID[$field_id]['place_query'] = $arr['place_query'];
00412 
00413       $BF_USAGE_BY_NAME[$field]['place_result'] =
00414          $BF_USAGE_BY_ID[$field_id]['place_result'] = $arr['place_result'];
00415 
00416       $BF_USAGE_BY_NAME[$field]['col_width'] =
00417          $BF_USAGE_BY_ID[$field_id]['col_width'] = $arr['col_width'];
00418     }
00419 }
00420 
00421 function trackers_data_get_field_predefined_values ($field, $group_id=false, $checked=false,$by_field_id=false,$active_only=true)
00422 {
00423 
00424   /*
00425              Return all possible values for a select box field
00426              Rk: if the checked value is given then it means that we want this value
00427                   in the list in any case (even if it is hidden and active_only is requested)
00428   */
00429   $field_id = ($by_field_id ? $field : trackers_data_get_field_id($field));
00430   $field_name = ($by_field_id ? trackers_data_get_field_name($field) : $field);
00431 
00432   # The "Assigned_to" box requires some special processing
00433   # because possible values  are project members) and they are
00434   # not stored in the trackers_field_value table but in the user_group table
00435   if ($field_name == 'assigned_to')
00436     {
00437       $res_value = trackers_data_get_technicians($group_id);
00438     }
00439   else if ($field_name == 'submitted_by')
00440     {
00441       $res_value = trackers_data_get_submitters($group_id);
00442     }
00443   else
00444     {
00445 
00446       # If only active field
00447       if ($active_only)
00448         {
00449           if ($checked)
00450             {
00451               $status_cond = "AND  (status IN ('A','P') OR value_id='$checked') ";
00452             }
00453           else
00454             {
00455               $status_cond = "AND  status IN ('A','P') ";
00456             }
00457         }
00458 
00459       # CAUTION !! the fields value_id and value must be first in the
00460       # select statement because the output is used in the html_build_select_box
00461       # function
00462 
00463       # yeupou@gnu.org 2003-11-24
00464       # FIXME!!!!! WHAT IS THIS CRAP!
00465       # It _on purpose_ ignores the permanent values for the
00466       # system when a group have his own values.
00467       # And  when creating group specific values, it insert the permanent
00468       # system values in the group specific values.
00469       #
00470       # Can someone bring a reasonnable explanation for such a behavior?
00471       #   - permanent field must by nature be permanent, in any case!
00472       #   - database must never duplicates information without good reason
00473       #
00474       # When improving this code, please change that so it uses the permanent
00475       # values in any case, whatever the group specific values may be.
00476 
00477       # Look for project specific values first
00478       $sql="SELECT value_id,value,bug_fv_id,bug_field_id,group_id,description,order_id,status ".
00479          "FROM ".ARTIFACT."_field_value ".
00480          "WHERE group_id=$group_id AND bug_field_id=$field_id ".
00481          $status_cond." ORDER BY order_id,value ASC";
00482       $res_value = db_query($sql);
00483       $rows=db_numrows($res_value);
00484 
00485       # If no specific value for this group then look for default values
00486       if ($rows == 0)
00487         {
00488           $sql="SELECT value_id,value,bug_fv_id,bug_field_id,group_id,description,order_id,status ".
00489              "FROM ".ARTIFACT."_field_value ".
00490              "WHERE group_id=100 AND bug_field_id=$field_id ".
00491              $status_cond." ORDER BY order_id,value ASC";
00492           $res_value = db_query($sql);
00493           $rows=db_numrows($res_value);
00494         }
00495     }
00496 
00497   return($res_value);
00498 
00499 }
00500 
00501 function trackers_data_use_field_predefined_values ($field, $group_id)
00502 {
00503   # Check whether a group field values are the default one or not.
00504   # If no entry in the database for the relevant field value belong to the
00505   # group, then it uses default values (fallback)
00506   $field_id = trackers_data_get_field_id($field);
00507   $sql="SELECT bug_fv_id FROM ".ARTIFACT."_field_value ".
00508              "WHERE group_id=".$group_id." AND bug_field_id=$field_id";
00509 
00510   $result = db_query($sql);
00511   return db_numrows($result);
00512 }
00513 
00514 
00515 function trackers_data_is_custom($field, $by_field_id=false)
00516 {
00517   global $BF_USAGE_BY_ID,$BF_USAGE_BY_NAME;
00518   return($by_field_id ? $BF_USAGE_BY_ID[$field]['custom']: $BF_USAGE_BY_NAME[$field]['custom']);
00519 }
00520 
00521 function trackers_data_is_special($field, $by_field_id=false)
00522 {
00523   global $BF_USAGE_BY_ID,$BF_USAGE_BY_NAME;
00524   return($by_field_id ? $BF_USAGE_BY_ID[$field]['special']: $BF_USAGE_BY_NAME[$field]['special']);
00525 }
00526 
00527 # deprecated
00528 function trackers_data_is_empty_ok ($field, $by_field_id=false)
00529 {
00530   return trackers_data_mandatory_flag($field, $by_field_id);
00531 }
00532 
00533 function trackers_data_mandatory_flag ($field, $by_field_id=false)
00534 {
00535   # 1 = not mandatory
00536   # 0 = relaxed mandatory (mandatory if it was to the submitter)
00537   # 3 = mandatory whenever possible
00538   global $BF_USAGE_BY_ID,$BF_USAGE_BY_NAME;
00539   if ($by_field_id)
00540     {
00541       $val = $BF_USAGE_BY_ID[$field]['custom_empty_ok'];
00542       if (!isset($val))
00543         { $val = $BF_USAGE_BY_ID[$field]['empty_ok']; }
00544     }  else
00545       {
00546         $val = $BF_USAGE_BY_NAME[$field]['custom_empty_ok'];
00547         if (!isset($val))
00548           { $val = $BF_USAGE_BY_NAME[$field]['empty_ok']; }
00549       }
00550   return($val);
00551 }
00552 
00553 
00554 function trackers_data_do_keep_history($field, $by_field_id=false)
00555 {
00556   global $BF_USAGE_BY_ID,$BF_USAGE_BY_NAME;
00557   if ($by_field_id)
00558     {
00559       $val = $BF_USAGE_BY_ID[$field]['custom_keep_history'];
00560       if (!isset($val))
00561         { $val = $BF_USAGE_BY_ID[$field]['empty_keep_history']; }
00562     }  else
00563       {
00564         $val = $BF_USAGE_BY_NAME[$field]['custom_keep_history'];
00565         if (!isset($val))
00566           { $val = $BF_USAGE_BY_NAME[$field]['keep_history']; }
00567       }
00568   return($val);
00569 }
00570 
00571 function trackers_data_is_required($field, $by_field_id=false)
00572 {
00573   global $BF_USAGE_BY_ID,$BF_USAGE_BY_NAME;
00574   return($by_field_id ? $BF_USAGE_BY_ID[$field]['required']: $BF_USAGE_BY_NAME[$field]['required']);
00575 }
00576 
00577 function trackers_data_is_used($field, $by_field_id=false)
00578 {
00579   global $BF_USAGE_BY_ID,$BF_USAGE_BY_NAME;
00580   return($by_field_id ? $BF_USAGE_BY_ID[$field]['use_it']: $BF_USAGE_BY_NAME[$field]['use_it']);
00581 }
00582 
00583 function trackers_data_is_showed_on_query($field)
00584 {
00585   global $BF_USAGE_BY_ID,$BF_USAGE_BY_NAME;
00586   return($by_field_id ? $BF_USAGE_BY_ID[$field]['show_on_query']: $BF_USAGE_BY_NAME[$field]['show_on_query']);
00587 
00588 }
00589 
00590 function trackers_data_is_showed_on_result($field)
00591 {
00592   global $BF_USAGE_BY_ID,$BF_USAGE_BY_NAME;
00593   return($by_field_id ? $BF_USAGE_BY_ID[$field]['show_on_result']: $BF_USAGE_BY_NAME[$field]['show_on_result']);
00594 }
00595 
00596 # return a TRUE value if non project members who still are
00597 # logged in users should be able to access this field
00598 # (first bit of show_on_add set)
00599 function trackers_data_is_showed_on_add($field, $by_field_id=false)
00600 {
00601   global $BF_USAGE_BY_ID,$BF_USAGE_BY_NAME;
00602   return($by_field_id ? $BF_USAGE_BY_ID[$field]['show_on_add'] & 1: $BF_USAGE_BY_NAME[$field]['show_on_add'] & 1);
00603 }
00604 
00605 # return a TRUE value if non logged in users should be able to
00606 # access this field (second bit of show_on_add set)
00607 function trackers_data_is_showed_on_add_nologin($field, $by_field_id=false)
00608 {
00609   global $BF_USAGE_BY_ID,$BF_USAGE_BY_NAME;
00610   return($by_field_id ? $BF_USAGE_BY_ID[$field]['show_on_add'] & 2: $BF_USAGE_BY_NAME[$field]['show_on_add'] & 2);
00611 }
00612 
00613 # return a TRUE value if project members should be able to
00614 # access this field
00615 function trackers_data_is_showed_on_add_members($field, $by_field_id=false)
00616 {
00617   global $BF_USAGE_BY_ID,$BF_USAGE_BY_NAME;
00618   return($by_field_id ? $BF_USAGE_BY_ID[$field]['show_on_add_members']: $BF_USAGE_BY_NAME[$field]['show_on_add_members']);
00619 }
00620 
00621 function trackers_data_is_date_field($field, $by_field_id=false)
00622 {
00623   return(trackers_data_get_display_type($field, $by_field_id) == 'DF');
00624 }
00625 
00626 function trackers_data_is_text_field($field, $by_field_id=false)
00627 {
00628   return(trackers_data_get_display_type($field, $by_field_id) == 'TF');
00629 }
00630 
00631 function trackers_data_is_text_area($field, $by_field_id=false)
00632 {
00633   return(trackers_data_get_display_type($field, $by_field_id) == 'TA');
00634 }
00635 
00636 function trackers_data_is_select_box($field, $by_field_id=false)
00637 {
00638   return(trackers_data_get_display_type($field, $by_field_id) == 'SB');
00639 }
00640 
00641 function trackers_data_is_username_field($field, $by_field_id=false)
00642 {
00643   global $BF_USAGE_BY_ID;
00644   if ($by_field_id)
00645     {
00646       $field = trackers_data_get_field_name($field);
00647     }
00648   return(($field == 'assigned_to') || ($field == 'submitted_by'));
00649 }
00650 
00651 function trackers_data_is_project_scope($field, $by_field_id=false)
00652 {
00653   global $BF_USAGE_BY_ID,$BF_USAGE_BY_NAME;
00654   if ($by_field_id)
00655     {
00656       return($BF_USAGE_BY_ID[$field]['scope'] == 'P');
00657     }
00658   else
00659     {
00660       return($BF_USAGE_BY_NAME[$field]['scope'] == 'P');
00661     }
00662 }
00663 
00664 function trackers_data_is_status_closed($status)
00665 {
00666   if ($status == '3')
00667     { return 1; }
00668   return 0;
00669 }
00670 
00671 function trackers_data_get_field_name($field_id)
00672 {
00673   global $BF_USAGE_BY_ID;
00674   return($BF_USAGE_BY_ID[$field_id]['field_name']);
00675 }
00676 
00677 function trackers_data_get_field_id($field_name)
00678 {
00679   global $BF_USAGE_BY_NAME;
00680   return($BF_USAGE_BY_NAME[$field_name]['bug_field_id']);
00681 }
00682 
00683 function trackers_data_get_group_id($field, $by_field_id=false)
00684 {
00685   global $BF_USAGE_BY_ID,$BF_USAGE_BY_NAME;
00686   return($by_field_id ? $BF_USAGE_BY_ID[$field]['group_id'] : $BF_USAGE_BY_NAME[$field]['group_id']);
00687 }
00688 
00689 function trackers_data_get_label($field, $by_field_id=false)
00690 {
00691   global $BF_USAGE_BY_ID,$BF_USAGE_BY_NAME;
00692   if ($by_field_id)
00693     {
00694       $lbl = $BF_USAGE_BY_ID[$field]['custom_label'];
00695       if (!isset($lbl))
00696         { $lbl = $BF_USAGE_BY_ID[$field]['label']; }
00697     }  else
00698       {
00699         $lbl = $BF_USAGE_BY_NAME[$field]['custom_label'];
00700         if (!isset($lbl))
00701           { $lbl = $BF_USAGE_BY_NAME[$field]['label']; }
00702       }
00703   return($lbl);
00704 }
00705 
00706 function trackers_data_get_description($field, $by_field_id=false)
00707 {
00708   global $BF_USAGE_BY_ID,$BF_USAGE_BY_NAME;
00709   if ($by_field_id)
00710     {
00711       $desc = $BF_USAGE_BY_ID[$field]['custom_description'];
00712       if (!isset($desc))
00713         { $desc = $BF_USAGE_BY_ID[$field]['description']; }
00714     }  else
00715       {
00716         $desc = $BF_USAGE_BY_NAME[$field]['custom_description'];
00717         if (!isset($desc))
00718           { $desc = $BF_USAGE_BY_NAME[$field]['description']; }
00719       }
00720   return($desc);
00721 }
00722 
00723 function trackers_data_get_display_type($field, $by_field_id=false)
00724 {
00725   global $BF_USAGE_BY_ID,$BF_USAGE_BY_NAME;
00726   return($by_field_id ? $BF_USAGE_BY_ID[$field]['display_type'] : $BF_USAGE_BY_NAME[$field]['display_type']);
00727 }
00728 
00729 function trackers_data_get_display_type_in_clear($field, $by_field_id=false)
00730 {
00731   if (trackers_data_is_select_box($field, $by_field_id))
00732     {
00733       return 'Select Box';
00734     }
00735   else if (trackers_data_is_text_field($field, $by_field_id))
00736     {
00737       return 'Text Field';
00738     }
00739   else if (trackers_data_is_text_area($field, $by_field_id))
00740     {
00741       return 'Text Area';
00742     }
00743   else if (trackers_data_is_date_field($field, $by_field_id))
00744     {
00745       return 'Date Field';
00746     }
00747   else
00748     {
00749       return '?';
00750     }
00751 }
00752 
00753 
00754 function trackers_data_get_keep_history($field, $by_field_id=false)
00755 {
00756   global $BF_USAGE_BY_ID,$BF_USAGE_BY_NAME;
00757   if ($by_field_id)
00758     {
00759       $val = $BF_USAGE_BY_ID[$field]['custom_keep_history'];
00760       if (!isset($val))
00761         { $val = $BF_USAGE_BY_ID[$field]['keep_history']; }
00762     }  else
00763       {
00764         $val = $BF_USAGE_BY_NAME[$field]['custom_keep_history'];
00765         if (!isset($val))
00766           { $val = $BF_USAGE_BY_NAME[$field]['keep_history']; }
00767       }
00768   return($val);
00769 }
00770 
00771 function trackers_data_get_place($field, $by_field_id=false)
00772 {
00773   global $BF_USAGE_BY_ID,$BF_USAGE_BY_NAME;
00774   return($by_field_id ? $BF_USAGE_BY_ID[$field]['place'] : $BF_USAGE_BY_NAME[$field]['place']);
00775 }
00776 
00777 function trackers_data_get_scope($field, $by_field_id=false)
00778 {
00779   global $BF_USAGE_BY_ID,$BF_USAGE_BY_NAME;
00780   return($by_field_id ? $BF_USAGE_BY_ID[$field]['scope'] : $BF_USAGE_BY_NAME[$field]['scope']);
00781 }
00782 
00783 function trackers_data_get_col_width($field, $by_field_id=false)
00784 {
00785   global $BF_USAGE_BY_ID,$BF_USAGE_BY_NAME;
00786   return($by_field_id ? $BF_USAGE_BY_ID[$field]['col_width'] : $BF_USAGE_BY_NAME[$field]['col_width']);
00787 }
00788 
00789 function trackers_data_get_display_size($field, $by_field_id=false)
00790 {
00791   global $BF_USAGE_BY_ID,$BF_USAGE_BY_NAME;
00792   if ($by_field_id)
00793     {
00794       $val = $BF_USAGE_BY_ID[$field]['custom_display_size'];
00795       if (!isset($val))
00796         { $val = $BF_USAGE_BY_ID[$field]['display_size']; }
00797     }  else
00798       {
00799         $val = $BF_USAGE_BY_NAME[$field]['custom_display_size'];
00800         if (!isset($val))
00801           { $val = $BF_USAGE_BY_NAME[$field]['display_size']; }
00802       }
00803   return(explode('/',$val));
00804 }
00805 
00806 function trackers_data_get_default_value($field,  $by_field_id=false)
00807 {
00808   global $BF_USAGE_BY_ID,$BF_USAGE_BY_NAME;
00809   /*
00810       Return the default value associated to a field_name as defined in the
00811       bug table (SQL definition)
00812   */
00813   if ($by_field_id)
00814     {
00815       $field = trackers_data_get_field_name($field);
00816     }
00817 
00818   $result = db_query('describe bug '.$field);
00819   return (db_result($result,0,'Default'));
00820 
00821 }
00822 
00823 function trackers_data_get_max_value_id($field, $group_id, $by_field_id=false)
00824 {
00825 
00826   /*
00827       Find the maximum value for the value_id of a field for a given group
00828       Return -1 if  no value exist yet
00829   */
00830 
00831   if (!$by_field_id)
00832     {
00833       $field_id = trackers_data_get_field_id($field);
00834     }
00835 
00836   $sql="SELECT max(value_id) as max FROM ".ARTIFACT."_field_value ".
00837      "WHERE bug_field_id='$field_id' AND group_id='$group_id' ";
00838   $res = db_query($sql);
00839   $rows = db_numrows($res);
00840 
00841   # If no max value found then it means it's the first value for this field
00842   # in this group. Return -1 in this case
00843   if ($rows == 0)
00844     {
00845       return(-1);
00846     }  else
00847       {
00848         return(db_result($res,0,'max'));
00849       }
00850 
00851 }
00852 
00853 function trackers_data_is_value_set_empty($field, $group_id, $by_field_id=false)
00854 {
00855 
00856   /*
00857       Return true if there is an existing set of values for given field for a
00858       given group and false if it is empty
00859   */
00860 
00861   if (!$by_field_id)
00862     {
00863       $field_id = trackers_data_get_field_id($field);
00864     }
00865   $sql="SELECT value_id FROM ".ARTIFACT."_field_value ".
00866      "WHERE bug_field_id='$field_id' AND group_id='$group_id' ";
00867   $res = db_query($sql);
00868   $rows=db_numrows($res);
00869 
00870   return (($rows<=0));
00871 }
00872 
00873 
00874 function trackers_data_copy_default_values($field, $group_id, $by_field_id=false)
00875 {
00876   /*
00877       Initialize the set of values for a given field for a given group by using
00878       the system default (default values belong to group_id 'None' =100)
00879   */
00880 
00881   if (!$by_field_id)
00882     {
00883       $field_id = trackers_data_get_field_id($field);
00884     }
00885 
00886   # if group_id=100 (None) it is a null operation
00887   # because default values belong to group_id 100 by definition
00888   if ($group_id != 100)
00889     {
00890 
00891       # First delete the exisiting value if any
00892       $sql="DELETE FROM ".ARTIFACT."_field_value ".
00893          "WHERE bug_field_id='$field_id' AND group_id='$group_id' ";
00894       $res = db_query($sql);
00895 
00896       # Second insert default values (if any) from group 'None'
00897       # Rk: The target table of the INSERT statement cannot appear in
00898       # the FROM clause of the SELECT part of the query because it's forbidden
00899       # in ANSI SQL to SELECT . So do it by hand !
00900       #
00901 
00902       $sql = "SELECT value_id,value,description,order_id,status ".
00903          "FROM ".ARTIFACT."_field_value ".
00904          "WHERE bug_field_id='$field_id' AND group_id='100'";
00905       $res = db_query($sql);
00906       $rows = db_numrows($res);
00907 
00908       for ($i=0; $i<$rows; $i++)
00909         {
00910 
00911           $value_id = addslashes(db_result($res,$i,'value_id'));
00912           $value = db_result($res,$i,'value');
00913           $description = addslashes(db_result($res,$i,'description'));
00914           $order_id = db_result($res,$i,'order_id');
00915           $status  = db_result($res,$i,'status');
00916 
00917 
00918           $sql="INSERT INTO ".ARTIFACT."_field_value ".
00919              "(bug_field_id,group_id,value_id,value,description,order_id,status) ".
00920              "VALUES ('$field_id','$group_id','$value_id','$value','$description','$order_id','$status')";
00921           #print "<BR>DBG - $sql";
00922           $res_insert = db_query($sql);
00923 
00924           if (db_affected_rows($res_insert) < 1)
00925             {
00926               fb(_("Insert of default value failed."), 0);
00927               db_error();
00928             }
00929         }
00930     }
00931 }
00932 
00933 function trackers_data_get_cached_field_value($field,$group_id,$value_id)
00934 {
00935   global $BF_VALUE_BY_NAME;
00936 
00937   if (!isset($BF_VALUE_BY_NAME[$field][$value_id]))
00938     {
00939       $res = trackers_data_get_field_predefined_values ($field, $group_id,false,false,false);
00940 
00941       while ($fv_array = db_fetch_array($res))
00942         {
00943           # $fv_array[0] has the value_id and [1] is the value
00944           $BF_VALUE_BY_NAME[$field][$fv_array['value_id']] = $fv_array[1];
00945         }
00946     }
00947 
00948   return $BF_VALUE_BY_NAME[$field][$value_id];
00949 }
00950 
00951 function trackers_data_get_field_value ($item_fv_id)
00952 {
00953   /*
00954       Get all the columns associated to a given field value
00955   */
00956 
00957   $sql = "SELECT * FROM ".ARTIFACT."_field_value WHERE bug_fv_id='$item_fv_id'";
00958   $res = db_query($sql);
00959   return($res);
00960 }
00961 
00962 function trackers_data_is_default_value ($item_fv_id)
00963 {
00964   /*
00965       See if this field value belongs to group None (100). In this case
00966       it is a so called default value.
00967   */
00968 
00969   $sql = "SELECT bug_field_id,value_id FROM ".ARTIFACT."_field_value WHERE bug_fv_id='$item_fv_id' AND group_id='100'";
00970   $res = db_query($sql);
00971 
00972   return ( (db_numrows($res) >= 1) ? $res : false);
00973 }
00974 
00975 function trackers_data_create_value ($field, $group_id, $value, $description,$order_id,$status='A',$by_field_id=false)
00976 {
00977 
00978   global $feedback,$ffeedback;
00979 
00980   /*
00981       Insert a new value for a given field for a given group
00982   */
00983 
00984   # An empty field value is not allowed
00985   if (preg_match ("/^\s*$/", $value))
00986     {
00987       fb(_("Empty field value not allowed"), 0);
00988       return;
00989     }
00990 
00991   if (!$by_field_id)
00992     {
00993       $field_id = trackers_data_get_field_id($field);
00994     }
00995 
00996   # if group_id=100 (None) then do nothing
00997   # because no real project should have the group number '100'
00998   if ($group_id != 100)
00999     {
01000 
01001       # if the current value set for this project is empty
01002       # then copy the default values first (if any)
01003       if (trackers_data_is_value_set_empty($field,$group_id))
01004         {
01005           trackers_data_copy_default_values($field,$group_id);
01006         }
01007 
01008       # Find the next value_id to give to this new value. (Start arbitrarily
01009       # at 200 if no value exists (and therefore max is undefined)
01010       $max_value_id = trackers_data_get_max_value_id($field, $group_id);
01011 
01012       if ($max_value_id < 0)
01013         {
01014           $value_id = 200;
01015         }
01016       else
01017         {
01018           $value_id = $max_value_id +1;
01019         }
01020 
01021 
01022       $sql = "INSERT INTO ".ARTIFACT."_field_value ".
01023          "(bug_field_id,group_id,value_id,value,description,order_id,status) ".
01024          "VALUES ('$field_id','$group_id','$value_id','$value','$description','$order_id','$status')";
01025       db_query($sql);
01026 
01027       if (db_affected_rows($result) < 1)
01028         {
01029           fb(_("Insert failed."), 0);
01030           ' - '.db_error();
01031         }
01032       else
01033 
01034         {
01035           fb(_("New field value inserted."));
01036         }
01037     }
01038 }
01039 
01040 
01041 function trackers_data_update_value ($item_fv_id,$field,$group_id,$value,$description,$order_id,$status='A')
01042 {
01043 
01044   global $feedback,$ffeedback;
01045   /*
01046       Insert a new value for a given field for a given group
01047   */
01048 
01049   # An empty field value is not allowed
01050   if (preg_match ("/^\s*$/", $value))
01051     {
01052       fb(_("Empty field value not allowed"), 0);
01053       return;
01054     }
01055 
01056   # Updating a bug field value that belong to group 100 (None) is
01057   # forbidden. These are default values that cannot be changed so
01058   # make sure to copy the default values first in the project context first
01059 
01060   if ($res = trackers_data_is_default_value($item_fv_id))
01061     {
01062       trackers_data_copy_default_values($field,$group_id);
01063 
01064       $arr = db_fetch_array($res);
01065       $where_cond = 'bug_field_id='.$arr['bug_field_id'].
01066          ' AND value_id='.$arr['value_id']." AND group_id='$group_id' ";
01067     }
01068   else
01069     {
01070       $where_cond = "bug_fv_id='$item_fv_id' AND group_id<>'100'";
01071     }
01072 
01073   # Now perform the value update
01074   $sql = "UPDATE ".ARTIFACT."_field_value ".
01075      "SET value='$value',description='$description',order_id='$order_id',status='$status' ".
01076      "WHERE $where_cond";
01077   $result = db_query($sql);
01078 
01079   #print "<BR>DBG - $sql";
01080 
01081   if (db_affected_rows($result) < 1)
01082     {
01083       fb(_("Update of field value failed."));
01084     }
01085   else
01086     {
01087       fb(_("New field value updated."));
01088     }
01089 }
01090 
01091 function trackers_data_reset_usage($field_name,$group_id)
01092 {
01093   global $feedback;
01094   /*
01095       Reset a field settings to its defaults usage (values are untouched). The defaults
01096       always belong to group_id 100 (None) so make sure we don;t delete entries for
01097       group 100
01098   */
01099   $field_id = trackers_data_get_field_id($field_name);
01100   if ($group_id != 100)
01101     {
01102       $sql = "DELETE FROM ".ARTIFACT."_field_usage ".
01103          "WHERE group_id='$group_id' AND bug_field_id='$field_id'";
01104       db_query($sql);
01105       fb(_("Field value successfully reset to defaults."));
01106 
01107     }
01108 }
01109 
01110 function trackers_data_update_usage($field_name,
01111                                     $group_id,
01112                                     $label,
01113                                     $description,
01114                                     $use_it,
01115                                     $rank,
01116                                     $display_size,
01117                                     $empty_ok,
01118                                     $keep_history,
01119                                     $show_on_add_members=0,
01120                                     $show_on_add=0,
01121                                     $transition_default_auth='A')
01122 
01123 {
01124 
01125   /*
01126       Update a field settings in the trackers_usage_table
01127       Rk: All the show_on_xxx boolean parameters are set to 0 by default because their
01128            values come from checkboxes and if not checked the form variable
01129            is not set at all. It must be 0 to be ok with the SQL statement
01130   */
01131 
01132   # if it's a required field then make sure the use_it flag is true
01133   if (trackers_data_is_required($field_name))
01134     {
01135       $use_it = 1;
01136     }
01137 
01138   $field_id = trackers_data_get_field_id($field_name);
01139 
01140   # if it's a custom field then take label into account else store NULL
01141   #    if (trackers_data_is_custom($field_name))  {
01142   $lbl = isset($label) ? "'$label'" : 'NULL';
01143   $desc = isset($description) ? "'$description'" : 'NULL';
01144   $disp_size = isset($display_size) ? "'$display_size'" : 'NULL';
01145   $empty = isset($empty_ok) ? "'$empty_ok'" : 'NULL';
01146   $keep_hist = isset($keep_history) ? "'$keep_history'" : 'NULL';
01147   #    }  else    {
01148   #     $lbl = $desc = $disp_size = $empty = $keep_hist = "NULL";
01149   #    }
01150 
01151   # See if this field usage exists in the table for this project
01152   $sql = 'SELECT bug_field_id FROM '.ARTIFACT.'_field_usage '.
01153      "WHERE bug_field_id='$field_id' AND group_id='$group_id'";
01154   $result = db_query($sql);
01155   $rows = db_numrows($result);
01156 
01157   # if it does exist then update it else insert a new usage entry for this field.
01158   if ($rows)
01159     {
01160       $sql = 'UPDATE '.ARTIFACT.'_field_usage '.
01161          "SET use_it='$use_it',show_on_add='$show_on_add',".
01162          "show_on_add_members='$show_on_add_members',place='$rank', ".
01163          "custom_label=$lbl,  custom_description=$desc,".
01164          "custom_display_size=$disp_size,  custom_empty_ok=$empty,".
01165          "custom_keep_history=$keep_hist, ".
01166          "transition_default_auth='$transition_default_auth' ".
01167          "WHERE bug_field_id='$field_id' AND group_id='$group_id'";
01168       $result = db_query($sql);
01169     }
01170   else
01171     {
01172       $sql = 'INSERT INTO '.ARTIFACT.'_field_usage '.
01173          "VALUES ('$field_id','$group_id','$use_it','$show_on_add',".
01174          "'$show_on_add_members','$rank',$lbl,$desc,$disp_size,$empty,$keep_hist,'$transition_default_auth')";
01175       $result = db_query($sql);
01176     }
01177 
01178   if (db_affected_rows($result) < 1)
01179     { fb(_("Update of field usage failed."), 1); }
01180   else
01181     { fb(_("Field usage updated.")); }
01182 
01183 }
01184 
01185 # Get a list of technicians for a tracker
01186 function trackers_data_get_technicians ($group_id)
01187 {
01188   # FIXME: The cleanest thing would be to issue one SQL command.
01189   # But we have to handle the fact that "no setting" = get back
01190   # to the group, or even group type, setting.
01191 
01192   # In fact, this is terrible, we cannot return something else than
01193   # a mysql result if we do not want to rewrite 25 functions.
01194   # So we get the appropriate list of users... and finally issue a
01195   # mysql command only to be able to return a mysql result.
01196   # Please, propose something better at savannah-dev@gnu.org
01197 
01198 
01199   # Get list of members
01200   $members_sql =  "SELECT user.user_id AS user_id "
01201      . "FROM user,user_group "
01202      . "WHERE user.user_id=user_group.user_id AND user_group.group_id=$group_id ";
01203   $members_res = db_query($members_sql);
01204   # Build the sql command
01205   $sql = "SELECT user_id,user_name FROM user WHERE ";
01206   while ($member = db_fetch_array($members_res))
01207     {
01208       if (member_check($member['user_id'], $group_id, member_create_tracker_flag(ARTIFACT).'1'))
01209         {
01210           if ($notfirst)
01211             { $sql .= " OR "; }
01212           $sql .= " user_id='".$member['user_id']."'";
01213           $notfirst = 1;
01214         }
01215     }
01216   $sql .= " ORDER BY user_name";
01217   return db_query($sql);
01218 }
01219 
01220 # Get transitions valid for a given tracker as an array
01221