View Issue Details

IDProjectCategoryView StatusLast Update
0011097mantisbtcustom fieldspublic2010-04-23 23:22
Reporterliebscher Assigned Tovboctor  
PriorityhighSeverityminorReproducibilityalways
Status closedResolutionduplicate 
PlatformLinux 
Product Version1.1.6 
Summary0011097: Offer Custom Fields (String) with maxLength > 255 characters and displayed as TEXTAREA
Description

Custom fields should have a maxLength of 1024 characters.
Custom fileds with a maxLength > 255 characters should be displayed as TEXTAREA.

Steps To Reproduce

Custom fields can be set to a length > 255 characters, but are always displayed as single line INPUT and cut at 255 characters during save.

Additional Information

We customized our Mantis installation this way:
Extend max length with PHPMyAdmin in database bugtracker from 255 to 1024 for the table columns:
mantis_custom_field_string_table.value
mantis_bug_history_table.old_value
mantis_bug_history_table.new_value

Modify the file mantis/core/custom_field_api.php (changed marked with '# MX'):
function print_custom_field_input( $p_field_def, $p_bug_id = null ) {
...
case CUSTOM_FIELD_TYPE_STRING:

MX START: treat maxLength > 255 as textarea

  if( 255 < $p_field_def['length_max'] ) {
    echo '<textarea cols="80" rows="10" name="custom_field_' . $t_id . '">';
    echo '' . $t_custom_field_value .'';
    echo '</textarea>';
  } else {
  # MX END
    echo '<input ', helper_get_tab_index(), ' type="text" name="custom_field_' . $t_id . '" size="80"';
    if( 0 < $p_field_def['length_max'] ) {
      echo ' maxlength="' . $p_field_def['length_max'] . '"';
    } else {
      echo ' maxlength="255"';
    }
    echo ' value="' . $t_custom_field_value .'"></input>';
  } # MX
  break ;
Tagspatch
Attached Files
custom_field_api.php.patch (93,489 bytes)   
--- C:/mX_fileshares/Projects/mobileX-MIP/Misc/Mantis/custom_field_api.php	Mi Okt 28 07:36:07 2009
+++ C:/mX_fileshares/Projects/mobileX-MIP/Misc/Mantis/custom_field_api_1.1.6.php	Di Dez  9 20:20:28 2008
@@ -1,1340 +1,1332 @@
-<?php
-# Mantis - a php based bugtracking system
-
-# Copyright (C) 2000 - 2002  Kenzaburo Ito - kenito@300baud.org
-# Copyright (C) 2002 - 2007  Mantis Team   - mantisbt-dev@lists.sourceforge.net
-
-# Mantis is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 2 of the License, or
-# (at your option) any later version.
-#
-# Mantis is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Mantis.  If not, see <http://www.gnu.org/licenses/>.
-
-	# --------------------------------------------------------
-	# $Id: custom_field_api.php,v 1.66.2.1 2007-10-13 22:35:21 giallu Exp $
-	# --------------------------------------------------------
-
-	$t_core_dir = dirname( __FILE__ ).DIRECTORY_SEPARATOR;
-
-	require_once( $t_core_dir . 'bug_api.php' );
-	require_once( $t_core_dir . 'helper_api.php' );
-	require_once( $t_core_dir . 'date_api.php' );
-
-	### Custom Fields API ###
-
-#*******************************************
-#	TODO
-#	- add an object to store field data like BugData and UserPrefs ?
-#	- add caching functions like user, bug, etc
-#	- make existing api functions use caching functions
-#	- add functions to return individual db columns for a field definition
-#*******************************************
-
-	#===================================
-	# Caching
-	#===================================
-
-	#########################################
-	# SECURITY NOTE: cache globals are initialized here to prevent them
-	#   being spoofed if register_globals is turned on
-
-	$g_cache_custom_field = array();
-	$g_cache_cf_list = NULL;
-	$g_cache_cf_linked = array();
-
-	# Cache a custom field row if necessary and return the cached copy
-	#  If the second parameter is true (default), trigger an error
-	#  if the field can't be found.  If the second parameter is
-	#  false, return false if the field can't be found.
-	function custom_field_cache_row( $p_field_id, $p_trigger_errors=true ) {
-		global $g_cache_custom_field;
-
-		$c_field_id = db_prepare_int( $p_field_id );
-
-		$t_custom_field_table = config_get( 'mantis_custom_field_table' );
-
-		if ( isset ( $g_cache_custom_field[$c_field_id] ) ) {
-			return $g_cache_custom_field[$c_field_id];
-		}
-
-		$query = "SELECT *
-				  FROM $t_custom_field_table
-				  WHERE id='$c_field_id'";
-		$result = db_query( $query );
-
-		if ( 0 == db_num_rows( $result ) ) {
-			if ( $p_trigger_errors ) {
-				error_parameters( 'Custom ' . $p_field_id );
-				trigger_error( ERROR_CUSTOM_FIELD_NOT_FOUND, ERROR );
-			} else {
-				return false;
-			}
-		}
-
-		$row = db_fetch_array( $result );
-
-		$g_cache_custom_field[$c_field_id] = $row;
-
-		return $row;
-	}
-
-	# --------------------
-	# Clear the custom field cache (or just the given id if specified)
-	function custom_field_clear_cache( $p_field_id = null ) {
-		global $g_cache_custom_field, $g_cached_custom_field_lists;
-
-		$g_cached_custom_field_lists = null;
-
-		if ( null === $p_field_id ) {
-			$g_cache_custom_field = array();
-		} else {
-			$c_field_id = db_prepare_int( $p_field_id );
-			unset( $g_cache_custom_field[$c_field_id] );
-		}
-
-		return true;
-	}
-
-
-	#===================================
-	# Boolean queries and ensures
-	#===================================
-
-	# --------------------
-	# Check to see whether the field is included in the given project
-	#  return true if the field is included, false otherwise
-	#
-	function custom_field_is_linked( $p_field_id, $p_project_id ) {
-		$c_project_id	= db_prepare_int( $p_project_id );
-		$c_field_id		= db_prepare_int( $p_field_id );
-
-		# figure out if this bug_id/field_id combination exists
-		$t_custom_field_project_table = config_get( 'mantis_custom_field_project_table' );
-		$query = "SELECT COUNT(*)
-				FROM $t_custom_field_project_table
-				WHERE field_id='$c_field_id' AND
-					  project_id='$c_project_id'";
-		$result = db_query( $query );
-		$count = db_result( $result );
-
-		if ( $count > 0 ) {
-			return true;
-		} else {
-			return false;
-		}
-	}
-
-	# --------------------
-	# Check to see whether the field id is defined
-	#  return true if the field is defined, false otherwise
-	function custom_field_exists( $p_field_id ) {
-		if ( false == custom_field_cache_row( $p_field_id, false ) ) {
-			return false;
-		} else {
-			return true;
-		}
-	}
-
-	# --------------------
-	# Return the type of a custom field if it exists.
-	function custom_field_type( $p_field_id ) {
-		$t_field = custom_field_cache_row( $p_field_id, false ) ;
-		if ( $t_field == false ) {
-			return -1 ;
-		} else {
-			return $t_field[ 'type' ] ;
-		}
-	}
-
-	# --------------------
-	# Check to see whether the field id is defined
-	#  return true if the field is defined, error otherwise
-	function custom_field_ensure_exists( $p_field_id ) {
-		if ( custom_field_exists( $p_field_id ) ) {
-			return true;
-		} else {
-			error_parameters( 'Custom ' . $p_field_id );
-			trigger_error( ERROR_CUSTOM_FIELD_NOT_FOUND, ERROR );
-		}
-	}
-
-	# --------------------
-	# Check to see whether the name is unique
-	#  return false if a field with the name already exists, true otherwise
-	#  if an id is specified, then the corresponding record is excluded from the
-	#  uniqueness test.
-	function custom_field_is_name_unique( $p_name, $p_custom_field_id = null ) {
-		$c_name	= db_prepare_string( $p_name );
-
-		$t_custom_field_table = config_get( 'mantis_custom_field_table' );
-		$query = "SELECT COUNT(*)
-				  FROM $t_custom_field_table
-				  WHERE name='$c_name'";
-		if ( $p_custom_field_id !== null ) {
-			$c_id = db_prepare_int( $p_custom_field_id );
-			$query .= " AND (id <> $c_id)";
-		}
-		$result = db_query( $query );
-		$count = db_result( $result );
-
-		if ( $count > 0 ) {
-			return false;
-		} else {
-			return true;
-		}
-	}
-
-	# --------------------
-	# Check to see whether the name is unique
-	#  return true if the name has not been used, error otherwise
-	function custom_field_ensure_name_unique( $p_name ) {
-		if ( custom_field_is_name_unique( $p_name ) ) {
-			return true;
-		} else {
-			trigger_error( ERROR_CUSTOM_FIELD_NAME_NOT_UNIQUE, ERROR );
-		}
-	}
-
-	# --------------------
-	# Return true if the user can read the value of the field for the given bug,
-	#  false otherwise.
-	function custom_field_has_read_access( $p_field_id, $p_bug_id, $p_user_id = null ) {
-		custom_field_ensure_exists( $p_field_id );
-
-		if ( null === $p_user_id ) {
-			$p_user_id = auth_get_current_user_id();
-		}
-
-		$t_access_level_r = custom_field_get_field( $p_field_id, 'access_level_r' );
-
-		$t_project_id = bug_get_field( $p_bug_id, 'project_id' );
-
-        return access_has_project_level( $t_access_level_r, $t_project_id, $p_user_id );
-	}
-
-	# --------------------
-	# Return true if the user can modify the value of the field for the given project,
-	#  false otherwise.
-	function custom_field_has_write_access_to_project( $p_field_id, $p_project_id, $p_user_id = null ) {
-		custom_field_ensure_exists( $p_field_id );
-
-		if ( null === $p_user_id ) {
-			$p_user_id = auth_get_current_user_id();
-		}
-
-		$t_access_level_rw = custom_field_get_field( $p_field_id, 'access_level_rw' );
-
-        return access_has_project_level( $t_access_level_rw, $p_project_id, $p_user_id );
-	}
-
-	# --------------------
-	# Return true if the user can modify the value of the field for the given bug,
-	#  false otherwise.
-	function custom_field_has_write_access( $p_field_id, $p_bug_id, $p_user_id = null ) {
-		$t_project_id = bug_get_field( $p_bug_id, 'project_id' );
-		return ( custom_field_has_write_access_to_project( $p_field_id, $t_project_id, $p_user_id ) );
-	}
-
-	#===================================
-	# Creation / Deletion / Updating
-	#===================================
-
-	# --------------------
-	# create a new custom field with the name $p_name
-	# the definition are the default values and can be changes later
-	# return the ID of the new definition
-	function custom_field_create( $p_name ) {
-		if ( string_contains_scripting_chars( $p_name ) ) {
-			trigger_error( ERROR_CUSTOM_FIELD_INVALID_DEFINITION, ERROR );
-		}
-
-		$c_name = db_prepare_string( trim( $p_name ) );
-
-		if ( is_blank( $c_name ) ) {
-			error_parameters( 'name' );
-			trigger_error( ERROR_EMPTY_FIELD, ERROR );
-		}
-
-		custom_field_ensure_name_unique( $c_name );
-
-		$t_custom_field_table = config_get( 'mantis_custom_field_table' );
-		$query = "INSERT INTO $t_custom_field_table
-					( name )
-				  VALUES
-					( '$c_name' )";
-
-		db_query( $query );
-
-		return db_insert_id( $t_custom_field_table );
-	}
-
-	# --------------------
-	# Update the field definition
-	#  return true on success, false on failure
-	function custom_field_update( $p_field_id, $p_def_array ) {
-		if ( string_contains_scripting_chars( $p_def_array['name'] ) ) {
-			trigger_error( ERROR_CUSTOM_FIELD_INVALID_DEFINITION, ERROR );
-		}
-
-		$c_field_id			= db_prepare_int( $p_field_id );
-		$c_name				= db_prepare_string( trim( $p_def_array['name'] ) );
-		$c_type				= db_prepare_int(    $p_def_array['type']            );
-		$c_possible_values	= db_prepare_string( $p_def_array['possible_values'] );
-		$c_default_value	= db_prepare_string( $p_def_array['default_value']   );
-		$c_valid_regexp		= db_prepare_string( $p_def_array['valid_regexp']    );
-		$c_access_level_r	= db_prepare_int(    $p_def_array['access_level_r']  );
-		$c_access_level_rw	= db_prepare_int(    $p_def_array['access_level_rw'] );
-		$c_length_min		= db_prepare_int(    $p_def_array['length_min']      );
-		$c_length_max		= db_prepare_int(    $p_def_array['length_max']      );
-		$c_advanced			= db_prepare_bool(   $p_def_array['advanced']        );
-		$c_display_report	= db_prepare_bool( 	 $p_def_array['display_report'] );
-		$c_display_update	= db_prepare_bool( 	 $p_def_array['display_update'] );
-		$c_display_resolved	= db_prepare_bool( 	 $p_def_array['display_resolved'] );
-		$c_display_closed	= db_prepare_bool( 	 $p_def_array['display_closed']   );
-		$c_require_report	= db_prepare_bool( 	 $p_def_array['require_report']  );
-		$c_require_update	= db_prepare_bool( 	 $p_def_array['require_update']  );
-		$c_require_resolved = db_prepare_bool( 	 $p_def_array['require_resolved'] );
-		$c_require_closed	= db_prepare_bool( 	 $p_def_array['require_closed']   );
-
-		if ( is_blank( $c_name ) ) {
-			error_parameters( 'name' );
-			trigger_error( ERROR_EMPTY_FIELD, ERROR );
-		}
-
-		if (( $c_access_level_rw < $c_access_level_r ) ||
-			( $c_length_min < 0 ) ||
-			( ( $c_length_max != 0 ) && ( $c_length_min > $c_length_max ) ) ) {
-			trigger_error( ERROR_CUSTOM_FIELD_INVALID_DEFINITION, ERROR );
-		}
-
-		if ( $c_advanced == true && ( $c_require_report == true || $c_require_update ) ) {
-			trigger_error( ERROR_CUSTOM_FIELD_INVALID_DEFINITION, ERROR );
-		}
-
-		if ( !custom_field_is_name_unique( $c_name, $c_field_id ) ) {
-			trigger_error( ERROR_CUSTOM_FIELD_NAME_NOT_UNIQUE, ERROR );
-		}
-
-		$t_update_something = false;
-		$t_mantis_custom_field_table = config_get( 'mantis_custom_field_table' );
-		$query = "UPDATE $t_mantis_custom_field_table
-				  SET ";
-		if( array_key_exists( 'name', $p_def_array ) ) {
-			if ( !$t_update_something ) {
-				$t_update_something = true;
-			} else {
-				$query .= ', ';
-			}
-			$query .= "name='$c_name'";
-		}
-		if( array_key_exists( 'type', $p_def_array ) ) {
-			if ( !$t_update_something ) {
-				$t_update_something = true;
-			} else {
-				$query .= ', ';
-			}
-			$query .= "type='$c_type'";
-		}
-		if( array_key_exists( 'possible_values', $p_def_array ) ) {
-			if ( !$t_update_something ) {
-				$t_update_something = true;
-			} else {
-				$query .= ', ';
-			}
-			$query .= "possible_values='$c_possible_values'";
-		}
-		if( array_key_exists( 'default_value', $p_def_array ) ) {
-			if ( !$t_update_something ) {
-				$t_update_something = true;
-			} else {
-				$query .= ', ';
-			}
-			$query .= "default_value='$c_default_value'";
-		}
-		if( array_key_exists( 'valid_regexp', $p_def_array ) ) {
-			if ( !$t_update_something ) {
-				$t_update_something = true;
-			} else {
-				$query .= ', ';
-			}
-			$query .= "valid_regexp='$c_valid_regexp'";
-		}
-		if( array_key_exists( 'access_level_r', $p_def_array ) ) {
-			if ( !$t_update_something ) {
-				$t_update_something = true;
-			} else {
-				$query .= ', ';
-			}
-			$query .= "access_level_r='$c_access_level_r'";
-		}
-		if( array_key_exists( 'access_level_rw', $p_def_array ) ) {
-			if ( !$t_update_something ) {
-				$t_update_something = true;
-			} else {
-				$query .= ', ';
-			}
-			$query .= "access_level_rw='$c_access_level_rw'";
-		}
-		if( array_key_exists( 'length_min', $p_def_array ) ) {
-			if ( !$t_update_something ) {
-				$t_update_something = true;
-			} else {
-				$query .= ', ';
-			}
-			$query .= "length_min='$c_length_min'";
-		}
-		if( array_key_exists( 'length_max', $p_def_array ) ) {
-			if ( !$t_update_something ) {
-				$t_update_something = true;
-			} else {
-				$query .= ', ';
-			}
-			$query .= "length_max='$c_length_max'";
-		}
-		if( array_key_exists( 'advanced', $p_def_array ) ) {
-			if ( !$t_update_something ) {
-				$t_update_something = true;
-			} else {
-				$query .= ', ';
-			}
-			$query .= "advanced='$c_advanced'";
-		}
-		if( array_key_exists( 'display_report', $p_def_array ) ) {
-			if ( !$t_update_something ) {
-				$t_update_something = true;
-			} else {
-				$query .= ', ';
-			}
-			$query .= "display_report='$c_display_report'";
-		}
-		if( array_key_exists( 'display_update', $p_def_array ) ) {
-			if ( !$t_update_something ) {
-				$t_update_something = true;
-			} else {
-				$query .= ', ';
-			}
-			$query .= "display_update='$c_display_update'";
-		}
-		if( array_key_exists( 'display_resolved', $p_def_array ) ) {
-			if ( !$t_update_something ) {
-				$t_update_something = true;
-			} else {
-				$query .= ', ';
-			}
-			$query .= "display_resolved='$c_display_resolved'";
-		}
-		if( array_key_exists( 'display_closed', $p_def_array ) ) {
-			if ( !$t_update_something ) {
-				$t_update_something = true;
-			} else {
-				$query .= ', ';
-			}
-			$query .= "display_closed='$c_display_closed'";
-		}
-		if( array_key_exists( 'require_report', $p_def_array ) ) {
-			if ( !$t_update_something ) {
-				$t_update_something = true;
-			} else {
-				$query .= ', ';
-			}
-			$query .= "require_report='$c_require_report'";
-		}
-		if( array_key_exists( 'require_update', $p_def_array ) ) {
-			if ( !$t_update_something ) {
-				$t_update_something = true;
-			} else {
-				$query .= ', ';
-			}
-			$query .= "require_update='$c_require_update'";
-		}
-		if( array_key_exists( 'require_resolved', $p_def_array ) ) {
-			if ( !$t_update_something ) {
-				$t_update_something = true;
-			} else {
-				$query .= ', ';
-			}
-			$query .= "require_resolved='$c_require_resolved'";
-		}
-		if( array_key_exists( 'require_closed', $p_def_array ) ) {
-			if ( !$t_update_something ) {
-				$t_update_something = true;
-			} else {
-				$query .= ', ';
-			}
-			$query .= "require_closed='$c_require_closed'";
-		}
-
-
-		$query .= " WHERE id='$c_field_id'";
-
-		if( $t_update_something ) {
-			db_query( $query );
-			custom_field_clear_cache( $p_field_id );
-		} else {
-			return false;   # there is nothing to update...
-		}
-
-		# db_query() errors on failure so:
-		return true;
-	}
-
-	# --------------------
-	# Add a custom field to a project
-	#  return true on success, false on failure or if already added
-	function custom_field_link( $p_field_id, $p_project_id ) {
-		$c_field_id		= db_prepare_int( $p_field_id );
-		$c_project_id	= db_prepare_int( $p_project_id );
-
-		custom_field_ensure_exists( $p_field_id );
-		project_ensure_exists( $p_project_id );
-
-		if ( custom_field_is_linked( $p_field_id, $p_project_id ) ) {
-			return false;
-		}
-
-		$t_custom_field_project_table = config_get( 'mantis_custom_field_project_table' );
-		$query = "INSERT INTO $t_custom_field_project_table
-					( field_id, project_id )
-				  VALUES
-					( '$c_field_id', '$c_project_id' )";
-		db_query( $query );
-
-		# db_query() errors on failure so:
-		return true;
-	}
-
-	# --------------------
-	# Remove a custom field from a project
-	#  return true on success, false on failure
-	#
-	# The values for the custom fields are not deleted.  This is to allow for the
-	# case where a bug is moved to another project that has the field, or the
-	# field is linked again to the project.
-	function custom_field_unlink( $p_field_id, $p_project_id ) {
-		$c_field_id		= db_prepare_int( $p_field_id );
-		$c_project_id	= db_prepare_int( $p_project_id );
-
-		$t_custom_field_project_table = config_get( 'mantis_custom_field_project_table' );
-		$query = "DELETE FROM $t_custom_field_project_table
-				  WHERE field_id = '$c_field_id' AND
-				  		project_id = '$c_project_id'";
-		db_query( $query );
-
-		# db_query() errors on failure so:
-		return true;
-	}
-
-	# --------------------
-	# Delete the field definition and all associated values and project
-	#  associations
-	#  return true on success, false on failure
-	function custom_field_destroy( $p_field_id ) {
-		$c_field_id = db_prepare_int( $p_field_id );
-
-		# delete all values
-		$t_custom_field_string_table = config_get( 'mantis_custom_field_string_table' );
-		$query = "DELETE FROM $t_custom_field_string_table
-				  WHERE field_id='$c_field_id'";
-		db_query( $query );
-
-		# delete all project associations
-		$t_custom_field_project_table = config_get( 'mantis_custom_field_project_table' );
-		$query = "DELETE FROM $t_custom_field_project_table
-				  WHERE field_id='$c_field_id'";
-		db_query( $query );
-
-		$t_custom_field_table = config_get( 'mantis_custom_field_table' );
-		# delete the definition
-		$query = "DELETE FROM $t_custom_field_table
-				  WHERE id='$c_field_id'";
-		db_query( $query );
-
-		custom_field_clear_cache( $p_field_id );
-
-		# db_query() errors on failure so:
-		return true;
-	}
-
-	# --------------------
-	# Delete all associations of custom fields to the specified project
-	#  return true on success, false on failure
-	#
-	# To be called from within project_delete().
-	function custom_field_unlink_all( $p_project_id ) {
-		$c_project_id = db_prepare_int( $p_project_id );
-
-		# delete all project associations
-		$t_custom_field_project_table = config_get( 'mantis_custom_field_project_table' );
-		$query = "DELETE FROM $t_custom_field_project_table
-				  WHERE project_id='$c_project_id'";
-		db_query( $query );
-
-		# db_query() errors on failure so:
-		return true;
-	}
-
-	# --------------------
-	# Delete all custom values associated with the specified bug.
-	#  return true on success, false on failure
-	#
-	# To be called from bug_delete().
-	function custom_field_delete_all_values( $p_bug_id ) {
-		$c_bug_id = db_prepare_int( $p_bug_id );
-
-		$t_custom_field_string_table = config_get( 'mantis_custom_field_string_table' );
-		$query = "DELETE FROM $t_custom_field_string_table
-				  WHERE bug_id='$c_bug_id'";
-		db_query( $query );
-
-		#db_query() errors on failure so:
-		return true;
-	}
-
-	#===================================
-	# Data Access
-	#===================================
-
-	# --------------------
-	# Get the id of the custom field with the specified name.
-	# false is returned if no custom field found with the specified name.
-	function custom_field_get_id_from_name( $p_field_name, $p_truncated_length = null ) {
-		if ( $p_field_name == '' ) {
-		  return false;
-		}
-
-		$t_custom_field_table = config_get( 'mantis_custom_field_table' );
-
-		$c_field_name = db_prepare_string( $p_field_name );
-
-		if ( ( null === $p_truncated_length ) || ( strlen( $c_field_name ) != $p_truncated_length ) ) {
-			$query = "SELECT id FROM $t_custom_field_table WHERE name = '$c_field_name'";
-		} else {
-			# @@@ This is to handle the case where we only have a truncated part of the name.  This happens in the case where
-			# we are getting the custom field name from the history logs, since history is 32 and custom field name is 64.
-			# This fix will handle entries already in the database, future entries should be handled by making the field name max lengths match.
-			$query = "SELECT id FROM $t_custom_field_table WHERE name LIKE '$c_field_name%'";
-		}
-
-		$t_result = db_query( $query, 1 );
-
-		if ( db_num_rows( $t_result ) == 0 ) {
-			return false;
-		}
-
-		$row = db_fetch_array( $t_result );
-
-		return $row['id'];
-	}
-
-	# --------------------
-	# Return an array of ids of custom fields bound to the specified project
-	#
-	# The ids will be sorted based on the sequence number associated with the binding
-	function custom_field_get_linked_ids( $p_project_id = ALL_PROJECTS ) {
-	global $g_cache_cf_linked;
-        
-        if ( ! isset( $g_cache_cf_linked[$p_project_id] ) ) {
-        
-     		$t_custom_field_table			= config_get( 'mantis_custom_field_table' );
-     		$t_custom_field_project_table	= config_get( 'mantis_custom_field_project_table' );
-
-    		if ( ALL_PROJECTS == $p_project_id ) {
-                $t_project_user_list_table = config_get( 'mantis_project_user_list_table' );
-                $t_project_table = config_get( 'mantis_project_table' );
-                $t_user_table = config_get( 'mantis_user_table' );
-                $t_user_id = auth_get_current_user_id();
-                $t_pub = VS_PUBLIC;
-                $t_priv = VS_PRIVATE;
-            
-                $t_private_access = config_get( 'private_project_threshold' );
-                if ( is_array( $t_private_access ) ) {
-                    if ( 1 == count( $t_private_access ) ) {
-    				    $t_access_clause = "= " . array_shift( $t_private_access ) . " ";
-                    } else {
-                        $t_access_clause = "IN (" . implode( ',', $t_private_access ) . ")";
-                    }
-                } else {
-                    $t_access_clause = ">= $t_private_access ";
-                }			
-
-            
-                # select only the ids that the user has some access to 
-                #  e.g., all fields in public projects, or private projects where the user is listed
-                #    or private projects where the user is implicitly listed
-                $query = "SELECT cft.id as id, cft.name as name
-                    FROM $t_custom_field_table as cft, $t_user_table ut, $t_project_table pt, $t_custom_field_project_table cfpt
-                        LEFT JOIN $t_project_user_list_table pult 
-                            on cfpt.project_id = pult.project_id and pult.user_id = $t_user_id
-                    WHERE cft.id = cfpt.field_id AND cfpt.project_id = pt.id AND ut.id = $t_user_id AND 
-                        ( pt.view_state = $t_pub OR 
-                        ( pt.view_state = $t_priv and pult.user_id = $t_user_id ) OR 
-                        ( pult.user_id is null and ut.access_level $t_access_clause ) )
-                    GROUP BY cft.id, cft.name
-                    ORDER BY cft.name ASC";
-    		} else {
-                if ( is_array( $p_project_id ) ) {
-                    if ( 1 == count( $p_project_id ) ) {
-    				    $t_project_clause = "= " . array_shift( $p_project_id ) . " ";
-                    } else {
-                        $t_project_clause = "IN (" . implode( ',', $p_project_id ) . ")";
-                    }
-                } else {
-                    $t_project_clause = "= $p_project_id ";
-                }			
-    			$query = "SELECT cft.id, cft.name, cfpt.sequence
-					  FROM $t_custom_field_table cft, $t_custom_field_project_table cfpt
-					  WHERE cfpt.project_id $t_project_clause AND
-							cft.id = cfpt.field_id
-					  ORDER BY sequence ASC, name ASC";
-    		}
-    		$result = db_query( $query );
-    		$t_row_count = db_num_rows( $result );
-    		$t_ids = array();
-
-    		for ( $i=0 ; $i < $t_row_count ; $i++ ) {
-    			$row = db_fetch_array( $result );
-
-    			array_push( $t_ids, $row['id'] );
-    		}
-    		$g_cache_cf_linked[$p_project_id] = $t_ids;
-    	} else {
-    		$t_ids = $g_cache_cf_linked[$p_project_id];
-        }
-        
-		return $t_ids;
-	}
-
-	# --------------------
-	# Return an array all custom field ids sorted by name
-	function custom_field_get_ids( ) {
-        global $g_cache_cf_list;
-       
-        if ( $g_cache_cf_list === NULL ) {
-            $t_custom_field_table			= config_get( 'mantis_custom_field_table' );
-            $query = "SELECT id, name
-				  FROM $t_custom_field_table
-				  ORDER BY name ASC";
-            $result = db_query( $query );
-            $t_row_count = db_num_rows( $result );
-            $t_ids = array();
-
-            for ( $i=0 ; $i < $t_row_count ; $i++ ) {
-                $row = db_fetch_array( $result );
-
-                array_push( $t_ids, $row['id'] );
-            }
-            $g_cache_cf_list = $t_ids;
-
-        } else {
-            $t_ids = $g_cache_cf_list;
-        }
-		return $t_ids;
-	}
-
-	# --------------------
-	# Return an array of ids of projects related to the specified custom field
-	# (the array may be empty)
-	function custom_field_get_project_ids( $p_field_id ) {
-		$c_field_id = db_prepare_int( $p_field_id );
-
-		$t_custom_field_project_table = config_get( 'mantis_custom_field_project_table' );
-		$query = "SELECT project_id
-				  FROM $t_custom_field_project_table
-				  WHERE field_id = '$c_field_id'";
-		$result = db_query( $query );
-
-		$t_row_count = db_num_rows( $result );
-		$t_ids = array();
-
-		for ( $i=0 ; $i < $t_row_count ; $i++ ) {
-			$row = db_fetch_array( $result );
-
-			array_push( $t_ids, $row['project_id'] );
-		}
-
-		return $t_ids;
-	}
-
-	# --------------------
-	# Return a field definition row for the field or error if the field does
-	#  not exist
-	function custom_field_get_definition( $p_field_id ) {
-		return custom_field_cache_row( $p_field_id );
-	}
-
-	# --------------------
-	# Return a single database field from a custom field definition row
-	#  for the field
-	# if the database field does not exist, display a warning and return ''
-	function custom_field_get_field( $p_field_id, $p_field_name ) {
-		$row = custom_field_get_definition( $p_field_id );
-
-		if ( isset( $row[$p_field_name] ) ) {
-			return $row[$p_field_name];
-		} else {
-			error_parameters( $p_field_name );
-			trigger_error( ERROR_DB_FIELD_NOT_FOUND, WARNING );
-			return '';
-		}
-	}
-
-	# --------------------
-	# Get the value of a custom field for the given bug
-	#
-	# @@@ return values are unclear... should we error when access is denied
-	#   and provide an api to check whether it will be?
-	function custom_field_get_value( $p_field_id, $p_bug_id ) {
-		$c_field_id = db_prepare_int( $p_field_id );
-		$c_bug_id   = db_prepare_int( $p_bug_id );
-
-		custom_field_ensure_exists( $p_field_id );
-
-		$t_custom_field_table = config_get( 'mantis_custom_field_table' );
-		$query = "SELECT access_level_r, default_value, type
-				  FROM $t_custom_field_table
-				  WHERE id='$c_field_id'";
-		$result = db_query( $query );
-		$row = db_fetch_array( $result );
-
-		$t_access_level_r	= $row['access_level_r'];
-		$t_default_value	= $row['default_value'];
-
-		if( !custom_field_has_read_access( $p_field_id, $p_bug_id, auth_get_current_user_id() ) ) {
-			return false;
-		}
-
-		$t_custom_field_string_table = config_get( 'mantis_custom_field_string_table' );
-		$query = "SELECT value
-				  FROM $t_custom_field_string_table
-				  WHERE bug_id='$c_bug_id' AND
-				  		field_id='$c_field_id'";
-		$result = db_query( $query );
-
-		if( db_num_rows( $result ) > 0 ) {
-			return custom_field_database_to_value( db_result( $result ) , $row['type'] );
-		} else {
-			return $t_default_value;
-		}
-	}
-
-	# --------------------
-	# Gets the custom fields array for the given bug readable by specified level.
-	# Array keys are custom field names. Array is sorted by custom field sequence number;
-	# Array items are arrays with the next keys:
-	# 'type', 'value', 'access_level_r'
-	function custom_field_get_linked_fields( $p_bug_id, $p_user_access_level ) {
-		$t_custom_fields = custom_field_get_all_linked_fields( $p_bug_id );
-
-		# removing restricted fields
-		foreach ( $t_custom_fields as $t_custom_field_name => $t_custom_field_data ) {
-			if ( $p_user_access_level < $t_custom_field_data['access_level_r'] ) {
-				unset( $t_custom_fields[$t_custom_field_name] );
-			}
-		}
-		return $t_custom_fields;
-	}
-
-	# --------------------
-	# Gets the custom fields array for the given bug. Array keys are custom field names.
-	# Array is sorted by custom field sequence number; Array items are arrays with the next keys:
-	# 'type', 'value', 'access_level_r'
-	function custom_field_get_all_linked_fields( $p_bug_id ) {
-		global $g_cached_custom_field_lists;
-
-		if ( !is_array( $g_cached_custom_field_lists ) ) {
-			$g_cached_custom_field_lists = array();
-		}
-
-		# is the list in cache ?
-		if( !array_key_exists( $p_bug_id, $g_cached_custom_field_lists ) ) {
-			$c_bug_id     = db_prepare_int( $p_bug_id );
-			$c_project_id = db_prepare_int( bug_get_field( $p_bug_id, 'project_id' ) );
-
-			$t_custom_field_project_table = config_get( 'mantis_custom_field_project_table' );
-			$t_custom_field_table         = config_get( 'mantis_custom_field_table' );
-			$t_custom_field_string_table  = config_get( 'mantis_custom_field_string_table' );
-
-			$query = "SELECT f.name, f.type, f.access_level_r, f.default_value, f.type, s.value
-					FROM $t_custom_field_project_table p INNER JOIN $t_custom_field_table f
-						ON p.field_id = f.id
-					LEFT JOIN $t_custom_field_string_table s
-						ON  p.field_id=s.field_id AND s.bug_id='$c_bug_id'
-					WHERE   p.project_id = '$c_project_id'
-					ORDER BY p.sequence ASC, f.name ASC";
-
-			$result = db_query( $query );
-
-			$t_row_count = db_num_rows( $result );
-
-			$t_custom_fields = array();
-
-			for ( $i=0 ; $i < $t_row_count ; ++$i ) {
-				$row = db_fetch_array( $result );
-
-				if( is_null( $row['value'] ) ) {
-					$t_value = $row['default_value'];
-				} else {
-					$t_value = custom_field_database_to_value( $row['value'], $row['type'] );
-				}
-
-				$t_custom_fields[$row['name']] = array( 'type'  => $row['type'],
-														  'value' => $t_value,
-														  'access_level_r' => $row['access_level_r'] );
-			}
-
-			$g_cached_custom_field_lists[$p_bug_id] = $t_custom_fields;
-		}
-
-		return $g_cached_custom_field_lists[$p_bug_id];
-	}
-
-
-	# --------------------
-	# Gets the sequence number for the specified custom field for the specified
-	# project.  Returns false in case of error.
-	function custom_field_get_sequence( $p_field_id, $p_project_id ) {
-		$c_field_id = db_prepare_int( $p_field_id );
-		$c_project_id = db_prepare_int( $p_project_id );
-
-		$t_custom_field_project_table = config_get( 'mantis_custom_field_project_table' );
-		$query = "SELECT sequence
-				  FROM $t_custom_field_project_table
-				  WHERE field_id='$c_field_id' AND
-						project_id='$c_project_id'";
-		$result = db_query( $query, 1 );
-
-		if ( 0 == db_num_rows( $result ) ) {
-			return false;
-		}
-
-		$t_row = db_fetch_array( $result );
-
-		return $t_row['sequence'];
-	}
-
-	# --------------------
-	# Allows the validation of a custom field value without setting it
-	# or needing a bug to exist.
-	function custom_field_validate( $p_field_id, $p_value ) {
-		$c_field_id	= db_prepare_int( $p_field_id );
-		$c_value	= db_prepare_string( $p_value );
-
-		custom_field_ensure_exists( $p_field_id );
-
-		$t_custom_field_table = config_get( 'mantis_custom_field_table' );
-		$query = "SELECT name, type, possible_values, valid_regexp,
-				  		 access_level_rw, length_min, length_max, default_value
-				  FROM $t_custom_field_table
-				  WHERE id='$c_field_id'";
-		$result = db_query( $query );
-		$row = db_fetch_array( $result );
-
-		$t_name				= $row['name'];
-		$t_type				= $row['type'];
-		$t_possible_values	= $row['possible_values'];
-		$t_valid_regexp		= $row['valid_regexp'];
-		$t_length_min		= $row['length_min'];
-		$t_length_max		= $row['length_max'];
-		$t_default_value	= $row['default_value'];
-
-		# check for valid value
-		if ( !is_blank( $t_valid_regexp ) ) {
-			if ( !ereg( $t_valid_regexp, $p_value ) ) {
-				return false;
-			}
-		}
-
-		if ( strlen( $p_value ) < $t_length_min ) {
-			return false;
-		}
-
-		if ( ( 0 != $t_length_max ) && ( strlen( $p_value ) > $t_length_max ) ) {
-			return false;
-		}
-
-		return true;
-	}
-
-	# --------------------
-	# $p_possible_values: possible values to be pre-processed.  If it has enum values,
-	#                     it will be left as is.  If it has a method, it will be replaced
-	#                     by the list.
-	function custom_field_prepare_possible_values( $p_possible_values ) {
-		$t_possible_values = $p_possible_values;
-
-		if ( !is_blank( $t_possible_values ) && ( $t_possible_values[0] == '=' ) ) {
-			$t_possible_values = helper_call_custom_function( 'enum_' . substr( $t_possible_values, 1 ), array() );
-		}
-
-		return $t_possible_values;
-	}
-
-	# --------------------
-	# Get All Possible Values for a Field.
-	function custom_field_distinct_values( $p_field_id, $p_project_id = ALL_PROJECTS ) {
-		$c_field_id						= db_prepare_int( $p_field_id );
-		$c_project_id					= db_prepare_int( $p_project_id );
-		$t_custom_field_string_table	= config_get( 'mantis_custom_field_string_table' );
-		$t_custom_field_table			= config_get( 'mantis_custom_field_table' );
-		$t_mantis_bug_table				= config_get( 'mantis_bug_table' );
-		$t_return_arr					= array();
-
-		$query = "SELECT type, possible_values
-				  FROM $t_custom_field_table
-				  WHERE id='$c_field_id'";
-		$result = db_query( $query );
-
-		$t_row_count = db_num_rows( $result );
-		if ( 0 == $t_row_count ) {
-			return false;
-		}
-		$row = db_fetch_array( $result );
-
-		# If an enumeration type, we get all possible values, not just used values
-		if ( CUSTOM_FIELD_TYPE_ENUM == $row['type'] ||
-			 CUSTOM_FIELD_TYPE_CHECKBOX == $row['type'] ||
-			 CUSTOM_FIELD_TYPE_LIST == $row['type'] ||
-			 CUSTOM_FIELD_TYPE_MULTILIST == $row['type']
-			) {
-			$t_possible_values = custom_field_prepare_possible_values( $row['possible_values'] );
-
-			$t_values_arr = explode( '|', $t_possible_values );
-
-			foreach( $t_values_arr as $t_option ) {
-				array_push( $t_return_arr, $t_option );
-			}
-		} else {
-			$t_where = '';
-			$t_from = $t_custom_field_string_table;
-			if ( ALL_PROJECTS != $p_project_id ) {
-				$t_where = " AND $t_mantis_bug_table.id = $t_custom_field_string_table.bug_id AND
-							$t_mantis_bug_table.project_id = '$p_project_id'";
-				$t_from = $t_from . ", $t_mantis_bug_table";
-			}
-			$query2 = "SELECT $t_custom_field_string_table.value FROM $t_from
-						WHERE $t_custom_field_string_table.field_id='$c_field_id' $t_where
-						GROUP BY $t_custom_field_string_table.value";
-			$result2 = db_query( $query2 );
-			$t_row_count = db_num_rows( $result2 );
-			if ( 0 == $t_row_count ) {
-				return false;
-			}
-
-			for ( $i = 0; $i < $t_row_count; $i++ ) {
-				$row = db_fetch_array( $result2 );
-				if( !is_blank( trim( $row['value'] ) ) ) {
-					array_push( $t_return_arr, $row['value'] );
-				}
-			}
-		}
-		return $t_return_arr;
-	}
-
-	#===================================
-	# Data Modification
-	#===================================
-
- 	# --------------------
-	# Convert the value to save it into the database, depending of the type
-	# return value for database
-	function custom_field_value_to_database( $p_value, $p_type ) {
-		switch ($p_type) {
-		case CUSTOM_FIELD_TYPE_MULTILIST:
-		case CUSTOM_FIELD_TYPE_CHECKBOX:
-			if ( '' == $p_value ) {
-				$result = '';
-			} else {
-				$result = '|' . $p_value . '|';
-			}
-			break;
-		default:
-			$result = $p_value;
-		}
-		return $result;
-	}
-
-	# --------------------
-	# Convert the database-value to value, depending of the type
-	# return value for further operation
-	function custom_field_database_to_value( $p_value, $p_type ) {
-		switch ($p_type) {
-		case CUSTOM_FIELD_TYPE_MULTILIST:
-		case CUSTOM_FIELD_TYPE_CHECKBOX:
-			$result = str_replace( '||', '', '|' . $p_value . '|' );
-			break;
-		default:
-			$result = $p_value;
-		}
-		return $result;
-	}
-
-	# --------------------
-	# Set the value of a custom field for a given bug
-	#  return true on success, false on failure
-	function custom_field_set_value( $p_field_id, $p_bug_id, $p_value ) {
-		$c_field_id	= db_prepare_int( $p_field_id );
-		$c_bug_id	= db_prepare_int( $p_bug_id );
-
-		custom_field_ensure_exists( $p_field_id );
-
-		$t_custom_field_table = config_get( 'mantis_custom_field_table' );
-		$query = "SELECT name, type, possible_values, valid_regexp,
-				  access_level_rw, length_min, length_max, default_value
-				  FROM $t_custom_field_table
-				  WHERE id='$c_field_id'";
-		$result = db_query( $query );
-		$row = db_fetch_array( $result );
-
-		$t_name				= $row['name'];
-		$t_type				= $row['type'];
-		$t_possible_values	= $row['possible_values'];
-		$t_valid_regexp		= $row['valid_regexp'];
-		$t_access_level_rw	= $row['access_level_rw'];
-		$t_length_min		= $row['length_min'];
-		$t_length_max		= $row['length_max'];
-		$t_default_value	= $row['default_value'];
-
-		$c_value	= db_prepare_string( custom_field_value_to_database( $p_value, $t_type ) );
-
-		# check for valid value
-		if ( !is_blank( $t_valid_regexp ) ) {
-			if ( !ereg( $t_valid_regexp, $p_value ) ) {
-				return false;
-			}
-		}
-
-		if ( strlen( $p_value ) < $t_length_min ) {
-			return false;
-		}
-
-		if ( ( 0 != $t_length_max ) && ( strlen( $p_value ) > $t_length_max ) ) {
-			return false;
-		}
-
-		if( !custom_field_has_write_access( $p_field_id, $p_bug_id, auth_get_current_user_id() ) ) {
-			return false;
-		}
-
-		$t_custom_field_string_table = config_get( 'mantis_custom_field_string_table' );
-
-		# do I need to update or insert this value?
-		$query = "SELECT value
-				  FROM $t_custom_field_string_table
-				  WHERE field_id='$c_field_id' AND
-				  		bug_id='$c_bug_id'";
-		$result = db_query( $query );
-
-		if ( db_num_rows( $result ) > 0 ) {
-			$query = "UPDATE $t_custom_field_string_table
-					  SET value='$c_value'
-					  WHERE field_id='$c_field_id' AND
-					  		bug_id='$c_bug_id'";
-			db_query( $query );
-
-			$row = db_fetch_array( $result );
-			history_log_event_direct( $c_bug_id, $t_name, custom_field_database_to_value( $row['value'], $t_type ), $p_value );
-		} else {
-			# Always store the value, even if it's the dafault value
-			# This is important, as the definitions might change but the
-			#  values stored with a bug must not change
-			$query = "INSERT INTO $t_custom_field_string_table
-						( field_id, bug_id, value )
-					  VALUES
-						( '$c_field_id', '$c_bug_id', '$c_value' )";
-			db_query( $query );
-			history_log_event_direct( $c_bug_id, $t_name, '', $p_value );
-		}
-
-		custom_field_clear_cache( $p_field_id );
-
-		#db_query() errors on failure so:
-		return true;
-	}
-
-	# --------------------
-	# Sets the sequence number for the specified custom field for the specified
-	# project.
-	function custom_field_set_sequence( $p_field_id, $p_project_id, $p_sequence ) {
-		$c_field_id = db_prepare_int( $p_field_id );
-		$c_project_id = db_prepare_int( $p_project_id );
-		$c_sequence = db_prepare_int( $p_sequence );
-
-		$t_custom_field_project_table = config_get( 'mantis_custom_field_project_table' );
-
-		$query = "UPDATE $t_custom_field_project_table
-				  SET sequence='$c_sequence'
-				  WHERE field_id='$c_field_id' AND
-				  		project_id='$c_project_id'";
-		$result = db_query( $query );
-
-		custom_field_clear_cache( $p_field_id );
-
-		return true;
-	}
-
-	#===================================
-	# Output
-	#===================================
-
-	# --------------------
-	# Print an input field
-	# $p_field_def contains the definition of the custom field (including it's
-	#              field id
-	# $p_bug_id    contains the bug where this field belongs to. If it's left
-	#              away, it'll default to 0 and thus belongs to a new (i.e.
-	#              non-existant) bug
-	# NOTE: This probably belongs in the print_api.php
-	function print_custom_field_input( $p_field_def, $p_bug_id = null ) {
-		$t_id = $p_field_def['id'];
-
-		if( null === $p_bug_id ) {
-			$t_custom_field_value = $p_field_def['default_value'];
-		} else {
-			$t_custom_field_value = custom_field_get_value( $t_id, $p_bug_id );
-		}
-
-		$t_custom_field_value = string_attribute( $t_custom_field_value );
-
-		switch ($p_field_def['type']) {
-		case CUSTOM_FIELD_TYPE_ENUM:
-		case CUSTOM_FIELD_TYPE_LIST:
-		case CUSTOM_FIELD_TYPE_MULTILIST:
- 			$t_values = explode( '|', custom_field_prepare_possible_values( $p_field_def['possible_values'] ) );
-			$t_list_size = $t_possible_values_count = count( $t_values );
-
-			if ( $t_possible_values_count > 5 ) {
-				$t_list_size = 5;
-			}
-
-			if ( $p_field_def['type'] == CUSTOM_FIELD_TYPE_ENUM ) {
-				$t_list_size = 0;	# for enums the size is 0
-			}
-
-			if ( $p_field_def['type'] == CUSTOM_FIELD_TYPE_MULTILIST ) {
-				echo '<select ', helper_get_tab_index(), ' name="custom_field_' . $t_id . '[]" size="' . $t_list_size . '" multiple="multiple">';
-			} else {
-				echo '<select ', helper_get_tab_index(), ' name="custom_field_' . $t_id . '" size="' . $t_list_size . '">';
-			}
-
-			$t_selected_values = explode( '|', $t_custom_field_value );
- 			foreach( $t_values as $t_option ) {
-				if( in_array( $t_option, $t_selected_values, true ) ) {
- 					echo '<option value="' . $t_option . '" selected="selected"> ' . $t_option . '</option>';
- 				} else {
- 					echo '<option value="' . $t_option . '">' . $t_option . '</option>';
- 				}
- 			}
- 			echo '</select>';
-			break;
-		case CUSTOM_FIELD_TYPE_CHECKBOX:
-			$t_values = explode( '|', custom_field_prepare_possible_values( $p_field_def['possible_values'] ) );
-			$t_checked_values = explode( '|', $t_custom_field_value );
-			foreach( $t_values as $t_option ) {
-				echo '<input ', helper_get_tab_index(), ' type="checkbox" name="custom_field_' . $t_id . '[]"';
-				if( in_array( $t_option, $t_checked_values, true ) ) {
-					echo ' value="' . $t_option . '" checked="checked">&nbsp;' . $t_option . '&nbsp;&nbsp;';
-				} else {
-					echo ' value="' . $t_option . '">&nbsp;' . $t_option . '&nbsp;&nbsp;';
-				}
-			}
- 			break;
-		case CUSTOM_FIELD_TYPE_NUMERIC:
-		case CUSTOM_FIELD_TYPE_FLOAT:
-		case CUSTOM_FIELD_TYPE_EMAIL:
-		case CUSTOM_FIELD_TYPE_STRING:
-		  # START MX: treat maxLength > 255 as textarea
-			if( 255 < $p_field_def['length_max'] ) {
-				echo '<textarea cols="80" rows="10" name="custom_field_' . $t_id . '">';
-				echo '' . $t_custom_field_value .'';
-        echo '</textarea>';
-			} else {
-		  # END MX
-				echo '<input ', helper_get_tab_index(), ' type="text" name="custom_field_' . $t_id . '" size="80"';
-				if( 0 < $p_field_def['length_max'] ) {
-					echo ' maxlength="' . $p_field_def['length_max'] . '"';
-				} else {
-					echo ' maxlength="255"';
-				}
-				echo ' value="' . $t_custom_field_value .'"></input>';
-			} # MX
-			break ;
-
-		case CUSTOM_FIELD_TYPE_DATE:
-			print_date_selection_set("custom_field_" . $t_id, config_get('short_date_format'), $t_custom_field_value, false, true) ;
-			break ;
-		}
-	}
-
-	# --------------------
-	# Prepare a string containing a custom field value for display
-	# $p_def 		contains the definition of the custom field
-	# $p_field_id 	contains the id of the field
-	# $p_bug_id		contains the bug id to display the custom field value for
-	# NOTE: This probably belongs in the string_api.php
-	function string_custom_field_value( $p_def, $p_field_id, $p_bug_id ) {
-		$t_custom_field_value = custom_field_get_value( $p_field_id, $p_bug_id );
-		switch( $p_def['type'] ) {
-			case CUSTOM_FIELD_TYPE_EMAIL:
-				return "<a href=\"mailto:$t_custom_field_value\">$t_custom_field_value</a>";
-				break;
-			case CUSTOM_FIELD_TYPE_ENUM:
-			case CUSTOM_FIELD_TYPE_LIST:
-			case CUSTOM_FIELD_TYPE_MULTILIST:
-			case CUSTOM_FIELD_TYPE_CHECKBOX:
-				return str_replace( '|', ', ', $t_custom_field_value );
-				break;
-			case CUSTOM_FIELD_TYPE_DATE:
-				if ($t_custom_field_value != null) {
-					return date( config_get( 'short_date_format'), $t_custom_field_value) ;
-				}
-				break ;
-			default:
-				return string_display_links( $t_custom_field_value );
-		}
-	}
-
-	# --------------------
-	# Print a custom field value for display
-	# $p_def 		contains the definition of the custom field
-	# $p_field_id 	contains the id of the field
-	# $p_bug_id		contains the bug id to display the custom field value for
-	# NOTE: This probably belongs in the print_api.php
-	function print_custom_field_value( $p_def, $p_field_id, $p_bug_id ) {
-		echo string_custom_field_value( $p_def, $p_field_id, $p_bug_id );
-	}
-
-	# --------------------
-	# Prepare a string containing a custom field value for email
-	# $p_value		value of custom field
-	# $p_type		type of custom field
-	# NOTE: This probably belongs in the string_api.php
-	function string_custom_field_value_for_email( $p_value, $p_type ) {
-		switch( $p_type ) {
-			case CUSTOM_FIELD_TYPE_EMAIL:
-				return 'mailto:'.$p_value;
-				break;
-			case CUSTOM_FIELD_TYPE_ENUM:
-			case CUSTOM_FIELD_TYPE_LIST:
-			case CUSTOM_FIELD_TYPE_MULTILIST:
-			case CUSTOM_FIELD_TYPE_CHECKBOX:
-				return str_replace( '|', ', ', $p_value );
-				break;
-			case CUSTOM_FIELD_TYPE_DATE:
-				if ($p_value != null) {
-					return date( config_get( 'short_date_format' ), $p_value) ;
-				}
-				break ;
-			default:
-				return $p_value;
-		}
-		return $p_value;
-	}
-
-?>
+<?php
+# Mantis - a php based bugtracking system
+
+# Copyright (C) 2000 - 2002  Kenzaburo Ito - kenito@300baud.org
+# Copyright (C) 2002 - 2007  Mantis Team   - mantisbt-dev@lists.sourceforge.net
+
+# Mantis is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 2 of the License, or
+# (at your option) any later version.
+#
+# Mantis is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Mantis.  If not, see <http://www.gnu.org/licenses/>.
+
+	# --------------------------------------------------------
+	# $Id: custom_field_api.php,v 1.66.2.1 2007-10-13 22:35:21 giallu Exp $
+	# --------------------------------------------------------
+
+	$t_core_dir = dirname( __FILE__ ).DIRECTORY_SEPARATOR;
+
+	require_once( $t_core_dir . 'bug_api.php' );
+	require_once( $t_core_dir . 'helper_api.php' );
+	require_once( $t_core_dir . 'date_api.php' );
+
+	### Custom Fields API ###
+
+#*******************************************
+#	TODO
+#	- add an object to store field data like BugData and UserPrefs ?
+#	- add caching functions like user, bug, etc
+#	- make existing api functions use caching functions
+#	- add functions to return individual db columns for a field definition
+#*******************************************
+
+	#===================================
+	# Caching
+	#===================================
+
+	#########################################
+	# SECURITY NOTE: cache globals are initialized here to prevent them
+	#   being spoofed if register_globals is turned on
+
+	$g_cache_custom_field = array();
+	$g_cache_cf_list = NULL;
+	$g_cache_cf_linked = array();
+
+	# Cache a custom field row if necessary and return the cached copy
+	#  If the second parameter is true (default), trigger an error
+	#  if the field can't be found.  If the second parameter is
+	#  false, return false if the field can't be found.
+	function custom_field_cache_row( $p_field_id, $p_trigger_errors=true ) {
+		global $g_cache_custom_field;
+
+		$c_field_id = db_prepare_int( $p_field_id );
+
+		$t_custom_field_table = config_get( 'mantis_custom_field_table' );
+
+		if ( isset ( $g_cache_custom_field[$c_field_id] ) ) {
+			return $g_cache_custom_field[$c_field_id];
+		}
+
+		$query = "SELECT *
+				  FROM $t_custom_field_table
+				  WHERE id='$c_field_id'";
+		$result = db_query( $query );
+
+		if ( 0 == db_num_rows( $result ) ) {
+			if ( $p_trigger_errors ) {
+				error_parameters( 'Custom ' . $p_field_id );
+				trigger_error( ERROR_CUSTOM_FIELD_NOT_FOUND, ERROR );
+			} else {
+				return false;
+			}
+		}
+
+		$row = db_fetch_array( $result );
+
+		$g_cache_custom_field[$c_field_id] = $row;
+
+		return $row;
+	}
+
+	# --------------------
+	# Clear the custom field cache (or just the given id if specified)
+	function custom_field_clear_cache( $p_field_id = null ) {
+		global $g_cache_custom_field, $g_cached_custom_field_lists;
+
+		$g_cached_custom_field_lists = null;
+
+		if ( null === $p_field_id ) {
+			$g_cache_custom_field = array();
+		} else {
+			$c_field_id = db_prepare_int( $p_field_id );
+			unset( $g_cache_custom_field[$c_field_id] );
+		}
+
+		return true;
+	}
+
+
+	#===================================
+	# Boolean queries and ensures
+	#===================================
+
+	# --------------------
+	# Check to see whether the field is included in the given project
+	#  return true if the field is included, false otherwise
+	#
+	function custom_field_is_linked( $p_field_id, $p_project_id ) {
+		$c_project_id	= db_prepare_int( $p_project_id );
+		$c_field_id		= db_prepare_int( $p_field_id );
+
+		# figure out if this bug_id/field_id combination exists
+		$t_custom_field_project_table = config_get( 'mantis_custom_field_project_table' );
+		$query = "SELECT COUNT(*)
+				FROM $t_custom_field_project_table
+				WHERE field_id='$c_field_id' AND
+					  project_id='$c_project_id'";
+		$result = db_query( $query );
+		$count = db_result( $result );
+
+		if ( $count > 0 ) {
+			return true;
+		} else {
+			return false;
+		}
+	}
+
+	# --------------------
+	# Check to see whether the field id is defined
+	#  return true if the field is defined, false otherwise
+	function custom_field_exists( $p_field_id ) {
+		if ( false == custom_field_cache_row( $p_field_id, false ) ) {
+			return false;
+		} else {
+			return true;
+		}
+	}
+
+	# --------------------
+	# Return the type of a custom field if it exists.
+	function custom_field_type( $p_field_id ) {
+		$t_field = custom_field_cache_row( $p_field_id, false ) ;
+		if ( $t_field == false ) {
+			return -1 ;
+		} else {
+			return $t_field[ 'type' ] ;
+		}
+	}
+
+	# --------------------
+	# Check to see whether the field id is defined
+	#  return true if the field is defined, error otherwise
+	function custom_field_ensure_exists( $p_field_id ) {
+		if ( custom_field_exists( $p_field_id ) ) {
+			return true;
+		} else {
+			error_parameters( 'Custom ' . $p_field_id );
+			trigger_error( ERROR_CUSTOM_FIELD_NOT_FOUND, ERROR );
+		}
+	}
+
+	# --------------------
+	# Check to see whether the name is unique
+	#  return false if a field with the name already exists, true otherwise
+	#  if an id is specified, then the corresponding record is excluded from the
+	#  uniqueness test.
+	function custom_field_is_name_unique( $p_name, $p_custom_field_id = null ) {
+		$c_name	= db_prepare_string( $p_name );
+
+		$t_custom_field_table = config_get( 'mantis_custom_field_table' );
+		$query = "SELECT COUNT(*)
+				  FROM $t_custom_field_table
+				  WHERE name='$c_name'";
+		if ( $p_custom_field_id !== null ) {
+			$c_id = db_prepare_int( $p_custom_field_id );
+			$query .= " AND (id <> $c_id)";
+		}
+		$result = db_query( $query );
+		$count = db_result( $result );
+
+		if ( $count > 0 ) {
+			return false;
+		} else {
+			return true;
+		}
+	}
+
+	# --------------------
+	# Check to see whether the name is unique
+	#  return true if the name has not been used, error otherwise
+	function custom_field_ensure_name_unique( $p_name ) {
+		if ( custom_field_is_name_unique( $p_name ) ) {
+			return true;
+		} else {
+			trigger_error( ERROR_CUSTOM_FIELD_NAME_NOT_UNIQUE, ERROR );
+		}
+	}
+
+	# --------------------
+	# Return true if the user can read the value of the field for the given bug,
+	#  false otherwise.
+	function custom_field_has_read_access( $p_field_id, $p_bug_id, $p_user_id = null ) {
+		custom_field_ensure_exists( $p_field_id );
+
+		if ( null === $p_user_id ) {
+			$p_user_id = auth_get_current_user_id();
+		}
+
+		$t_access_level_r = custom_field_get_field( $p_field_id, 'access_level_r' );
+
+		$t_project_id = bug_get_field( $p_bug_id, 'project_id' );
+
+        return access_has_project_level( $t_access_level_r, $t_project_id, $p_user_id );
+	}
+
+	# --------------------
+	# Return true if the user can modify the value of the field for the given project,
+	#  false otherwise.
+	function custom_field_has_write_access_to_project( $p_field_id, $p_project_id, $p_user_id = null ) {
+		custom_field_ensure_exists( $p_field_id );
+
+		if ( null === $p_user_id ) {
+			$p_user_id = auth_get_current_user_id();
+		}
+
+		$t_access_level_rw = custom_field_get_field( $p_field_id, 'access_level_rw' );
+
+        return access_has_project_level( $t_access_level_rw, $p_project_id, $p_user_id );
+	}
+
+	# --------------------
+	# Return true if the user can modify the value of the field for the given bug,
+	#  false otherwise.
+	function custom_field_has_write_access( $p_field_id, $p_bug_id, $p_user_id = null ) {
+		$t_project_id = bug_get_field( $p_bug_id, 'project_id' );
+		return ( custom_field_has_write_access_to_project( $p_field_id, $t_project_id, $p_user_id ) );
+	}
+
+	#===================================
+	# Creation / Deletion / Updating
+	#===================================
+
+	# --------------------
+	# create a new custom field with the name $p_name
+	# the definition are the default values and can be changes later
+	# return the ID of the new definition
+	function custom_field_create( $p_name ) {
+		if ( string_contains_scripting_chars( $p_name ) ) {
+			trigger_error( ERROR_CUSTOM_FIELD_INVALID_DEFINITION, ERROR );
+		}
+
+		$c_name = db_prepare_string( trim( $p_name ) );
+
+		if ( is_blank( $c_name ) ) {
+			error_parameters( 'name' );
+			trigger_error( ERROR_EMPTY_FIELD, ERROR );
+		}
+
+		custom_field_ensure_name_unique( $c_name );
+
+		$t_custom_field_table = config_get( 'mantis_custom_field_table' );
+		$query = "INSERT INTO $t_custom_field_table
+					( name )
+				  VALUES
+					( '$c_name' )";
+
+		db_query( $query );
+
+		return db_insert_id( $t_custom_field_table );
+	}
+
+	# --------------------
+	# Update the field definition
+	#  return true on success, false on failure
+	function custom_field_update( $p_field_id, $p_def_array ) {
+		if ( string_contains_scripting_chars( $p_def_array['name'] ) ) {
+			trigger_error( ERROR_CUSTOM_FIELD_INVALID_DEFINITION, ERROR );
+		}
+
+		$c_field_id			= db_prepare_int( $p_field_id );
+		$c_name				= db_prepare_string( trim( $p_def_array['name'] ) );
+		$c_type				= db_prepare_int(    $p_def_array['type']            );
+		$c_possible_values	= db_prepare_string( $p_def_array['possible_values'] );
+		$c_default_value	= db_prepare_string( $p_def_array['default_value']   );
+		$c_valid_regexp		= db_prepare_string( $p_def_array['valid_regexp']    );
+		$c_access_level_r	= db_prepare_int(    $p_def_array['access_level_r']  );
+		$c_access_level_rw	= db_prepare_int(    $p_def_array['access_level_rw'] );
+		$c_length_min		= db_prepare_int(    $p_def_array['length_min']      );
+		$c_length_max		= db_prepare_int(    $p_def_array['length_max']      );
+		$c_advanced			= db_prepare_bool(   $p_def_array['advanced']        );
+		$c_display_report	= db_prepare_bool( 	 $p_def_array['display_report'] );
+		$c_display_update	= db_prepare_bool( 	 $p_def_array['display_update'] );
+		$c_display_resolved	= db_prepare_bool( 	 $p_def_array['display_resolved'] );
+		$c_display_closed	= db_prepare_bool( 	 $p_def_array['display_closed']   );
+		$c_require_report	= db_prepare_bool( 	 $p_def_array['require_report']  );
+		$c_require_update	= db_prepare_bool( 	 $p_def_array['require_update']  );
+		$c_require_resolved = db_prepare_bool( 	 $p_def_array['require_resolved'] );
+		$c_require_closed	= db_prepare_bool( 	 $p_def_array['require_closed']   );
+
+		if ( is_blank( $c_name ) ) {
+			error_parameters( 'name' );
+			trigger_error( ERROR_EMPTY_FIELD, ERROR );
+		}
+
+		if (( $c_access_level_rw < $c_access_level_r ) ||
+			( $c_length_min < 0 ) ||
+			( ( $c_length_max != 0 ) && ( $c_length_min > $c_length_max ) ) ) {
+			trigger_error( ERROR_CUSTOM_FIELD_INVALID_DEFINITION, ERROR );
+		}
+
+		if ( $c_advanced == true && ( $c_require_report == true || $c_require_update ) ) {
+			trigger_error( ERROR_CUSTOM_FIELD_INVALID_DEFINITION, ERROR );
+		}
+
+		if ( !custom_field_is_name_unique( $c_name, $c_field_id ) ) {
+			trigger_error( ERROR_CUSTOM_FIELD_NAME_NOT_UNIQUE, ERROR );
+		}
+
+		$t_update_something = false;
+		$t_mantis_custom_field_table = config_get( 'mantis_custom_field_table' );
+		$query = "UPDATE $t_mantis_custom_field_table
+				  SET ";
+		if( array_key_exists( 'name', $p_def_array ) ) {
+			if ( !$t_update_something ) {
+				$t_update_something = true;
+			} else {
+				$query .= ', ';
+			}
+			$query .= "name='$c_name'";
+		}
+		if( array_key_exists( 'type', $p_def_array ) ) {
+			if ( !$t_update_something ) {
+				$t_update_something = true;
+			} else {
+				$query .= ', ';
+			}
+			$query .= "type='$c_type'";
+		}
+		if( array_key_exists( 'possible_values', $p_def_array ) ) {
+			if ( !$t_update_something ) {
+				$t_update_something = true;
+			} else {
+				$query .= ', ';
+			}
+			$query .= "possible_values='$c_possible_values'";
+		}
+		if( array_key_exists( 'default_value', $p_def_array ) ) {
+			if ( !$t_update_something ) {
+				$t_update_something = true;
+			} else {
+				$query .= ', ';
+			}
+			$query .= "default_value='$c_default_value'";
+		}
+		if( array_key_exists( 'valid_regexp', $p_def_array ) ) {
+			if ( !$t_update_something ) {
+				$t_update_something = true;
+			} else {
+				$query .= ', ';
+			}
+			$query .= "valid_regexp='$c_valid_regexp'";
+		}
+		if( array_key_exists( 'access_level_r', $p_def_array ) ) {
+			if ( !$t_update_something ) {
+				$t_update_something = true;
+			} else {
+				$query .= ', ';
+			}
+			$query .= "access_level_r='$c_access_level_r'";
+		}
+		if( array_key_exists( 'access_level_rw', $p_def_array ) ) {
+			if ( !$t_update_something ) {
+				$t_update_something = true;
+			} else {
+				$query .= ', ';
+			}
+			$query .= "access_level_rw='$c_access_level_rw'";
+		}
+		if( array_key_exists( 'length_min', $p_def_array ) ) {
+			if ( !$t_update_something ) {
+				$t_update_something = true;
+			} else {
+				$query .= ', ';
+			}
+			$query .= "length_min='$c_length_min'";
+		}
+		if( array_key_exists( 'length_max', $p_def_array ) ) {
+			if ( !$t_update_something ) {
+				$t_update_something = true;
+			} else {
+				$query .= ', ';
+			}
+			$query .= "length_max='$c_length_max'";
+		}
+		if( array_key_exists( 'advanced', $p_def_array ) ) {
+			if ( !$t_update_something ) {
+				$t_update_something = true;
+			} else {
+				$query .= ', ';
+			}
+			$query .= "advanced='$c_advanced'";
+		}
+		if( array_key_exists( 'display_report', $p_def_array ) ) {
+			if ( !$t_update_something ) {
+				$t_update_something = true;
+			} else {
+				$query .= ', ';
+			}
+			$query .= "display_report='$c_display_report'";
+		}
+		if( array_key_exists( 'display_update', $p_def_array ) ) {
+			if ( !$t_update_something ) {
+				$t_update_something = true;
+			} else {
+				$query .= ', ';
+			}
+			$query .= "display_update='$c_display_update'";
+		}
+		if( array_key_exists( 'display_resolved', $p_def_array ) ) {
+			if ( !$t_update_something ) {
+				$t_update_something = true;
+			} else {
+				$query .= ', ';
+			}
+			$query .= "display_resolved='$c_display_resolved'";
+		}
+		if( array_key_exists( 'display_closed', $p_def_array ) ) {
+			if ( !$t_update_something ) {
+				$t_update_something = true;
+			} else {
+				$query .= ', ';
+			}
+			$query .= "display_closed='$c_display_closed'";
+		}
+		if( array_key_exists( 'require_report', $p_def_array ) ) {
+			if ( !$t_update_something ) {
+				$t_update_something = true;
+			} else {
+				$query .= ', ';
+			}
+			$query .= "require_report='$c_require_report'";
+		}
+		if( array_key_exists( 'require_update', $p_def_array ) ) {
+			if ( !$t_update_something ) {
+				$t_update_something = true;
+			} else {
+				$query .= ', ';
+			}
+			$query .= "require_update='$c_require_update'";
+		}
+		if( array_key_exists( 'require_resolved', $p_def_array ) ) {
+			if ( !$t_update_something ) {
+				$t_update_something = true;
+			} else {
+				$query .= ', ';
+			}
+			$query .= "require_resolved='$c_require_resolved'";
+		}
+		if( array_key_exists( 'require_closed', $p_def_array ) ) {
+			if ( !$t_update_something ) {
+				$t_update_something = true;
+			} else {
+				$query .= ', ';
+			}
+			$query .= "require_closed='$c_require_closed'";
+		}
+
+
+		$query .= " WHERE id='$c_field_id'";
+
+		if( $t_update_something ) {
+			db_query( $query );
+			custom_field_clear_cache( $p_field_id );
+		} else {
+			return false;   # there is nothing to update...
+		}
+
+		# db_query() errors on failure so:
+		return true;
+	}
+
+	# --------------------
+	# Add a custom field to a project
+	#  return true on success, false on failure or if already added
+	function custom_field_link( $p_field_id, $p_project_id ) {
+		$c_field_id		= db_prepare_int( $p_field_id );
+		$c_project_id	= db_prepare_int( $p_project_id );
+
+		custom_field_ensure_exists( $p_field_id );
+		project_ensure_exists( $p_project_id );
+
+		if ( custom_field_is_linked( $p_field_id, $p_project_id ) ) {
+			return false;
+		}
+
+		$t_custom_field_project_table = config_get( 'mantis_custom_field_project_table' );
+		$query = "INSERT INTO $t_custom_field_project_table
+					( field_id, project_id )
+				  VALUES
+					( '$c_field_id', '$c_project_id' )";
+		db_query( $query );
+
+		# db_query() errors on failure so:
+		return true;
+	}
+
+	# --------------------
+	# Remove a custom field from a project
+	#  return true on success, false on failure
+	#
+	# The values for the custom fields are not deleted.  This is to allow for the
+	# case where a bug is moved to another project that has the field, or the
+	# field is linked again to the project.
+	function custom_field_unlink( $p_field_id, $p_project_id ) {
+		$c_field_id		= db_prepare_int( $p_field_id );
+		$c_project_id	= db_prepare_int( $p_project_id );
+
+		$t_custom_field_project_table = config_get( 'mantis_custom_field_project_table' );
+		$query = "DELETE FROM $t_custom_field_project_table
+				  WHERE field_id = '$c_field_id' AND
+				  		project_id = '$c_project_id'";
+		db_query( $query );
+
+		# db_query() errors on failure so:
+		return true;
+	}
+
+	# --------------------
+	# Delete the field definition and all associated values and project
+	#  associations
+	#  return true on success, false on failure
+	function custom_field_destroy( $p_field_id ) {
+		$c_field_id = db_prepare_int( $p_field_id );
+
+		# delete all values
+		$t_custom_field_string_table = config_get( 'mantis_custom_field_string_table' );
+		$query = "DELETE FROM $t_custom_field_string_table
+				  WHERE field_id='$c_field_id'";
+		db_query( $query );
+
+		# delete all project associations
+		$t_custom_field_project_table = config_get( 'mantis_custom_field_project_table' );
+		$query = "DELETE FROM $t_custom_field_project_table
+				  WHERE field_id='$c_field_id'";
+		db_query( $query );
+
+		$t_custom_field_table = config_get( 'mantis_custom_field_table' );
+		# delete the definition
+		$query = "DELETE FROM $t_custom_field_table
+				  WHERE id='$c_field_id'";
+		db_query( $query );
+
+		custom_field_clear_cache( $p_field_id );
+
+		# db_query() errors on failure so:
+		return true;
+	}
+
+	# --------------------
+	# Delete all associations of custom fields to the specified project
+	#  return true on success, false on failure
+	#
+	# To be called from within project_delete().
+	function custom_field_unlink_all( $p_project_id ) {
+		$c_project_id = db_prepare_int( $p_project_id );
+
+		# delete all project associations
+		$t_custom_field_project_table = config_get( 'mantis_custom_field_project_table' );
+		$query = "DELETE FROM $t_custom_field_project_table
+				  WHERE project_id='$c_project_id'";
+		db_query( $query );
+
+		# db_query() errors on failure so:
+		return true;
+	}
+
+	# --------------------
+	# Delete all custom values associated with the specified bug.
+	#  return true on success, false on failure
+	#
+	# To be called from bug_delete().
+	function custom_field_delete_all_values( $p_bug_id ) {
+		$c_bug_id = db_prepare_int( $p_bug_id );
+
+		$t_custom_field_string_table = config_get( 'mantis_custom_field_string_table' );
+		$query = "DELETE FROM $t_custom_field_string_table
+				  WHERE bug_id='$c_bug_id'";
+		db_query( $query );
+
+		#db_query() errors on failure so:
+		return true;
+	}
+
+	#===================================
+	# Data Access
+	#===================================
+
+	# --------------------
+	# Get the id of the custom field with the specified name.
+	# false is returned if no custom field found with the specified name.
+	function custom_field_get_id_from_name( $p_field_name, $p_truncated_length = null ) {
+		if ( $p_field_name == '' ) {
+		  return false;
+		}
+
+		$t_custom_field_table = config_get( 'mantis_custom_field_table' );
+
+		$c_field_name = db_prepare_string( $p_field_name );
+
+		if ( ( null === $p_truncated_length ) || ( strlen( $c_field_name ) != $p_truncated_length ) ) {
+			$query = "SELECT id FROM $t_custom_field_table WHERE name = '$c_field_name'";
+		} else {
+			# @@@ This is to handle the case where we only have a truncated part of the name.  This happens in the case where
+			# we are getting the custom field name from the history logs, since history is 32 and custom field name is 64.
+			# This fix will handle entries already in the database, future entries should be handled by making the field name max lengths match.
+			$query = "SELECT id FROM $t_custom_field_table WHERE name LIKE '$c_field_name%'";
+		}
+
+		$t_result = db_query( $query, 1 );
+
+		if ( db_num_rows( $t_result ) == 0 ) {
+			return false;
+		}
+
+		$row = db_fetch_array( $t_result );
+
+		return $row['id'];
+	}
+
+	# --------------------
+	# Return an array of ids of custom fields bound to the specified project
+	#
+	# The ids will be sorted based on the sequence number associated with the binding
+	function custom_field_get_linked_ids( $p_project_id = ALL_PROJECTS ) {
+	global $g_cache_cf_linked;
+        
+        if ( ! isset( $g_cache_cf_linked[$p_project_id] ) ) {
+        
+     		$t_custom_field_table			= config_get( 'mantis_custom_field_table' );
+     		$t_custom_field_project_table	= config_get( 'mantis_custom_field_project_table' );
+
+    		if ( ALL_PROJECTS == $p_project_id ) {
+                $t_project_user_list_table = config_get( 'mantis_project_user_list_table' );
+                $t_project_table = config_get( 'mantis_project_table' );
+                $t_user_table = config_get( 'mantis_user_table' );
+                $t_user_id = auth_get_current_user_id();
+                $t_pub = VS_PUBLIC;
+                $t_priv = VS_PRIVATE;
+            
+                $t_private_access = config_get( 'private_project_threshold' );
+                if ( is_array( $t_private_access ) ) {
+                    if ( 1 == count( $t_private_access ) ) {
+    				    $t_access_clause = "= " . array_shift( $t_private_access ) . " ";
+                    } else {
+                        $t_access_clause = "IN (" . implode( ',', $t_private_access ) . ")";
+                    }
+                } else {
+                    $t_access_clause = ">= $t_private_access ";
+                }			
+
+            
+                # select only the ids that the user has some access to 
+                #  e.g., all fields in public projects, or private projects where the user is listed
+                #    or private projects where the user is implicitly listed
+                $query = "SELECT cft.id as id, cft.name as name
+                    FROM $t_custom_field_table as cft, $t_user_table ut, $t_project_table pt, $t_custom_field_project_table cfpt
+                        LEFT JOIN $t_project_user_list_table pult 
+                            on cfpt.project_id = pult.project_id and pult.user_id = $t_user_id
+                    WHERE cft.id = cfpt.field_id AND cfpt.project_id = pt.id AND ut.id = $t_user_id AND 
+                        ( pt.view_state = $t_pub OR 
+                        ( pt.view_state = $t_priv and pult.user_id = $t_user_id ) OR 
+                        ( pult.user_id is null and ut.access_level $t_access_clause ) )
+                    GROUP BY cft.id, cft.name
+                    ORDER BY cft.name ASC";
+    		} else {
+                if ( is_array( $p_project_id ) ) {
+                    if ( 1 == count( $p_project_id ) ) {
+    				    $t_project_clause = "= " . array_shift( $p_project_id ) . " ";
+                    } else {
+                        $t_project_clause = "IN (" . implode( ',', $p_project_id ) . ")";
+                    }
+                } else {
+                    $t_project_clause = "= $p_project_id ";
+                }			
+    			$query = "SELECT cft.id, cft.name, cfpt.sequence
+					  FROM $t_custom_field_table cft, $t_custom_field_project_table cfpt
+					  WHERE cfpt.project_id $t_project_clause AND
+							cft.id = cfpt.field_id
+					  ORDER BY sequence ASC, name ASC";
+    		}
+    		$result = db_query( $query );
+    		$t_row_count = db_num_rows( $result );
+    		$t_ids = array();
+
+    		for ( $i=0 ; $i < $t_row_count ; $i++ ) {
+    			$row = db_fetch_array( $result );
+
+    			array_push( $t_ids, $row['id'] );
+    		}
+    		$g_cache_cf_linked[$p_project_id] = $t_ids;
+    	} else {
+    		$t_ids = $g_cache_cf_linked[$p_project_id];
+        }
+        
+		return $t_ids;
+	}
+
+	# --------------------
+	# Return an array all custom field ids sorted by name
+	function custom_field_get_ids( ) {
+        global $g_cache_cf_list;
+       
+        if ( $g_cache_cf_list === NULL ) {
+            $t_custom_field_table			= config_get( 'mantis_custom_field_table' );
+            $query = "SELECT id, name
+				  FROM $t_custom_field_table
+				  ORDER BY name ASC";
+            $result = db_query( $query );
+            $t_row_count = db_num_rows( $result );
+            $t_ids = array();
+
+            for ( $i=0 ; $i < $t_row_count ; $i++ ) {
+                $row = db_fetch_array( $result );
+
+                array_push( $t_ids, $row['id'] );
+            }
+            $g_cache_cf_list = $t_ids;
+
+        } else {
+            $t_ids = $g_cache_cf_list;
+        }
+		return $t_ids;
+	}
+
+	# --------------------
+	# Return an array of ids of projects related to the specified custom field
+	# (the array may be empty)
+	function custom_field_get_project_ids( $p_field_id ) {
+		$c_field_id = db_prepare_int( $p_field_id );
+
+		$t_custom_field_project_table = config_get( 'mantis_custom_field_project_table' );
+		$query = "SELECT project_id
+				  FROM $t_custom_field_project_table
+				  WHERE field_id = '$c_field_id'";
+		$result = db_query( $query );
+
+		$t_row_count = db_num_rows( $result );
+		$t_ids = array();
+
+		for ( $i=0 ; $i < $t_row_count ; $i++ ) {
+			$row = db_fetch_array( $result );
+
+			array_push( $t_ids, $row['project_id'] );
+		}
+
+		return $t_ids;
+	}
+
+	# --------------------
+	# Return a field definition row for the field or error if the field does
+	#  not exist
+	function custom_field_get_definition( $p_field_id ) {
+		return custom_field_cache_row( $p_field_id );
+	}
+
+	# --------------------
+	# Return a single database field from a custom field definition row
+	#  for the field
+	# if the database field does not exist, display a warning and return ''
+	function custom_field_get_field( $p_field_id, $p_field_name ) {
+		$row = custom_field_get_definition( $p_field_id );
+
+		if ( isset( $row[$p_field_name] ) ) {
+			return $row[$p_field_name];
+		} else {
+			error_parameters( $p_field_name );
+			trigger_error( ERROR_DB_FIELD_NOT_FOUND, WARNING );
+			return '';
+		}
+	}
+
+	# --------------------
+	# Get the value of a custom field for the given bug
+	#
+	# @@@ return values are unclear... should we error when access is denied
+	#   and provide an api to check whether it will be?
+	function custom_field_get_value( $p_field_id, $p_bug_id ) {
+		$c_field_id = db_prepare_int( $p_field_id );
+		$c_bug_id   = db_prepare_int( $p_bug_id );
+
+		custom_field_ensure_exists( $p_field_id );
+
+		$t_custom_field_table = config_get( 'mantis_custom_field_table' );
+		$query = "SELECT access_level_r, default_value, type
+				  FROM $t_custom_field_table
+				  WHERE id='$c_field_id'";
+		$result = db_query( $query );
+		$row = db_fetch_array( $result );
+
+		$t_access_level_r	= $row['access_level_r'];
+		$t_default_value	= $row['default_value'];
+
+		if( !custom_field_has_read_access( $p_field_id, $p_bug_id, auth_get_current_user_id() ) ) {
+			return false;
+		}
+
+		$t_custom_field_string_table = config_get( 'mantis_custom_field_string_table' );
+		$query = "SELECT value
+				  FROM $t_custom_field_string_table
+				  WHERE bug_id='$c_bug_id' AND
+				  		field_id='$c_field_id'";
+		$result = db_query( $query );
+
+		if( db_num_rows( $result ) > 0 ) {
+			return custom_field_database_to_value( db_result( $result ) , $row['type'] );
+		} else {
+			return $t_default_value;
+		}
+	}
+
+	# --------------------
+	# Gets the custom fields array for the given bug readable by specified level.
+	# Array keys are custom field names. Array is sorted by custom field sequence number;
+	# Array items are arrays with the next keys:
+	# 'type', 'value', 'access_level_r'
+	function custom_field_get_linked_fields( $p_bug_id, $p_user_access_level ) {
+		$t_custom_fields = custom_field_get_all_linked_fields( $p_bug_id );
+
+		# removing restricted fields
+		foreach ( $t_custom_fields as $t_custom_field_name => $t_custom_field_data ) {
+			if ( $p_user_access_level < $t_custom_field_data['access_level_r'] ) {
+				unset( $t_custom_fields[$t_custom_field_name] );
+			}
+		}
+		return $t_custom_fields;
+	}
+
+	# --------------------
+	# Gets the custom fields array for the given bug. Array keys are custom field names.
+	# Array is sorted by custom field sequence number; Array items are arrays with the next keys:
+	# 'type', 'value', 'access_level_r'
+	function custom_field_get_all_linked_fields( $p_bug_id ) {
+		global $g_cached_custom_field_lists;
+
+		if ( !is_array( $g_cached_custom_field_lists ) ) {
+			$g_cached_custom_field_lists = array();
+		}
+
+		# is the list in cache ?
+		if( !array_key_exists( $p_bug_id, $g_cached_custom_field_lists ) ) {
+			$c_bug_id     = db_prepare_int( $p_bug_id );
+			$c_project_id = db_prepare_int( bug_get_field( $p_bug_id, 'project_id' ) );
+
+			$t_custom_field_project_table = config_get( 'mantis_custom_field_project_table' );
+			$t_custom_field_table         = config_get( 'mantis_custom_field_table' );
+			$t_custom_field_string_table  = config_get( 'mantis_custom_field_string_table' );
+
+			$query = "SELECT f.name, f.type, f.access_level_r, f.default_value, f.type, s.value
+					FROM $t_custom_field_project_table p INNER JOIN $t_custom_field_table f
+						ON p.field_id = f.id
+					LEFT JOIN $t_custom_field_string_table s
+						ON  p.field_id=s.field_id AND s.bug_id='$c_bug_id'
+					WHERE   p.project_id = '$c_project_id'
+					ORDER BY p.sequence ASC, f.name ASC";
+
+			$result = db_query( $query );
+
+			$t_row_count = db_num_rows( $result );
+
+			$t_custom_fields = array();
+
+			for ( $i=0 ; $i < $t_row_count ; ++$i ) {
+				$row = db_fetch_array( $result );
+
+				if( is_null( $row['value'] ) ) {
+					$t_value = $row['default_value'];
+				} else {
+					$t_value = custom_field_database_to_value( $row['value'], $row['type'] );
+				}
+
+				$t_custom_fields[$row['name']] = array( 'type'  => $row['type'],
+														  'value' => $t_value,
+														  'access_level_r' => $row['access_level_r'] );
+			}
+
+			$g_cached_custom_field_lists[$p_bug_id] = $t_custom_fields;
+		}
+
+		return $g_cached_custom_field_lists[$p_bug_id];
+	}
+
+
+	# --------------------
+	# Gets the sequence number for the specified custom field for the specified
+	# project.  Returns false in case of error.
+	function custom_field_get_sequence( $p_field_id, $p_project_id ) {
+		$c_field_id = db_prepare_int( $p_field_id );
+		$c_project_id = db_prepare_int( $p_project_id );
+
+		$t_custom_field_project_table = config_get( 'mantis_custom_field_project_table' );
+		$query = "SELECT sequence
+				  FROM $t_custom_field_project_table
+				  WHERE field_id='$c_field_id' AND
+						project_id='$c_project_id'";
+		$result = db_query( $query, 1 );
+
+		if ( 0 == db_num_rows( $result ) ) {
+			return false;
+		}
+
+		$t_row = db_fetch_array( $result );
+
+		return $t_row['sequence'];
+	}
+
+	# --------------------
+	# Allows the validation of a custom field value without setting it
+	# or needing a bug to exist.
+	function custom_field_validate( $p_field_id, $p_value ) {
+		$c_field_id	= db_prepare_int( $p_field_id );
+		$c_value	= db_prepare_string( $p_value );
+
+		custom_field_ensure_exists( $p_field_id );
+
+		$t_custom_field_table = config_get( 'mantis_custom_field_table' );
+		$query = "SELECT name, type, possible_values, valid_regexp,
+				  		 access_level_rw, length_min, length_max, default_value
+				  FROM $t_custom_field_table
+				  WHERE id='$c_field_id'";
+		$result = db_query( $query );
+		$row = db_fetch_array( $result );
+
+		$t_name				= $row['name'];
+		$t_type				= $row['type'];
+		$t_possible_values	= $row['possible_values'];
+		$t_valid_regexp		= $row['valid_regexp'];
+		$t_length_min		= $row['length_min'];
+		$t_length_max		= $row['length_max'];
+		$t_default_value	= $row['default_value'];
+
+		# check for valid value
+		if ( !is_blank( $t_valid_regexp ) ) {
+			if ( !ereg( $t_valid_regexp, $p_value ) ) {
+				return false;
+			}
+		}
+
+		if ( strlen( $p_value ) < $t_length_min ) {
+			return false;
+		}
+
+		if ( ( 0 != $t_length_max ) && ( strlen( $p_value ) > $t_length_max ) ) {
+			return false;
+		}
+
+		return true;
+	}
+
+	# --------------------
+	# $p_possible_values: possible values to be pre-processed.  If it has enum values,
+	#                     it will be left as is.  If it has a method, it will be replaced
+	#                     by the list.
+	function custom_field_prepare_possible_values( $p_possible_values ) {
+		$t_possible_values = $p_possible_values;
+
+		if ( !is_blank( $t_possible_values ) && ( $t_possible_values[0] == '=' ) ) {
+			$t_possible_values = helper_call_custom_function( 'enum_' . substr( $t_possible_values, 1 ), array() );
+		}
+
+		return $t_possible_values;
+	}
+
+	# --------------------
+	# Get All Possible Values for a Field.
+	function custom_field_distinct_values( $p_field_id, $p_project_id = ALL_PROJECTS ) {
+		$c_field_id						= db_prepare_int( $p_field_id );
+		$c_project_id					= db_prepare_int( $p_project_id );
+		$t_custom_field_string_table	= config_get( 'mantis_custom_field_string_table' );
+		$t_custom_field_table			= config_get( 'mantis_custom_field_table' );
+		$t_mantis_bug_table				= config_get( 'mantis_bug_table' );
+		$t_return_arr					= array();
+
+		$query = "SELECT type, possible_values
+				  FROM $t_custom_field_table
+				  WHERE id='$c_field_id'";
+		$result = db_query( $query );
+
+		$t_row_count = db_num_rows( $result );
+		if ( 0 == $t_row_count ) {
+			return false;
+		}
+		$row = db_fetch_array( $result );
+
+		# If an enumeration type, we get all possible values, not just used values
+		if ( CUSTOM_FIELD_TYPE_ENUM == $row['type'] ||
+			 CUSTOM_FIELD_TYPE_CHECKBOX == $row['type'] ||
+			 CUSTOM_FIELD_TYPE_LIST == $row['type'] ||
+			 CUSTOM_FIELD_TYPE_MULTILIST == $row['type']
+			) {
+			$t_possible_values = custom_field_prepare_possible_values( $row['possible_values'] );
+
+			$t_values_arr = explode( '|', $t_possible_values );
+
+			foreach( $t_values_arr as $t_option ) {
+				array_push( $t_return_arr, $t_option );
+			}
+		} else {
+			$t_where = '';
+			$t_from = $t_custom_field_string_table;
+			if ( ALL_PROJECTS != $p_project_id ) {
+				$t_where = " AND $t_mantis_bug_table.id = $t_custom_field_string_table.bug_id AND
+							$t_mantis_bug_table.project_id = '$p_project_id'";
+				$t_from = $t_from . ", $t_mantis_bug_table";
+			}
+			$query2 = "SELECT $t_custom_field_string_table.value FROM $t_from
+						WHERE $t_custom_field_string_table.field_id='$c_field_id' $t_where
+						GROUP BY $t_custom_field_string_table.value";
+			$result2 = db_query( $query2 );
+			$t_row_count = db_num_rows( $result2 );
+			if ( 0 == $t_row_count ) {
+				return false;
+			}
+
+			for ( $i = 0; $i < $t_row_count; $i++ ) {
+				$row = db_fetch_array( $result2 );
+				if( !is_blank( trim( $row['value'] ) ) ) {
+					array_push( $t_return_arr, $row['value'] );
+				}
+			}
+		}
+		return $t_return_arr;
+	}
+
+	#===================================
+	# Data Modification
+	#===================================
+
+ 	# --------------------
+	# Convert the value to save it into the database, depending of the type
+	# return value for database
+	function custom_field_value_to_database( $p_value, $p_type ) {
+		switch ($p_type) {
+		case CUSTOM_FIELD_TYPE_MULTILIST:
+		case CUSTOM_FIELD_TYPE_CHECKBOX:
+			if ( '' == $p_value ) {
+				$result = '';
+			} else {
+				$result = '|' . $p_value . '|';
+			}
+			break;
+		default:
+			$result = $p_value;
+		}
+		return $result;
+	}
+
+	# --------------------
+	# Convert the database-value to value, depending of the type
+	# return value for further operation
+	function custom_field_database_to_value( $p_value, $p_type ) {
+		switch ($p_type) {
+		case CUSTOM_FIELD_TYPE_MULTILIST:
+		case CUSTOM_FIELD_TYPE_CHECKBOX:
+			$result = str_replace( '||', '', '|' . $p_value . '|' );
+			break;
+		default:
+			$result = $p_value;
+		}
+		return $result;
+	}
+
+	# --------------------
+	# Set the value of a custom field for a given bug
+	#  return true on success, false on failure
+	function custom_field_set_value( $p_field_id, $p_bug_id, $p_value ) {
+		$c_field_id	= db_prepare_int( $p_field_id );
+		$c_bug_id	= db_prepare_int( $p_bug_id );
+
+		custom_field_ensure_exists( $p_field_id );
+
+		$t_custom_field_table = config_get( 'mantis_custom_field_table' );
+		$query = "SELECT name, type, possible_values, valid_regexp,
+				  access_level_rw, length_min, length_max, default_value
+				  FROM $t_custom_field_table
+				  WHERE id='$c_field_id'";
+		$result = db_query( $query );
+		$row = db_fetch_array( $result );
+
+		$t_name				= $row['name'];
+		$t_type				= $row['type'];
+		$t_possible_values	= $row['possible_values'];
+		$t_valid_regexp		= $row['valid_regexp'];
+		$t_access_level_rw	= $row['access_level_rw'];
+		$t_length_min		= $row['length_min'];
+		$t_length_max		= $row['length_max'];
+		$t_default_value	= $row['default_value'];
+
+		$c_value	= db_prepare_string( custom_field_value_to_database( $p_value, $t_type ) );
+
+		# check for valid value
+		if ( !is_blank( $t_valid_regexp ) ) {
+			if ( !ereg( $t_valid_regexp, $p_value ) ) {
+				return false;
+			}
+		}
+
+		if ( strlen( $p_value ) < $t_length_min ) {
+			return false;
+		}
+
+		if ( ( 0 != $t_length_max ) && ( strlen( $p_value ) > $t_length_max ) ) {
+			return false;
+		}
+
+		if( !custom_field_has_write_access( $p_field_id, $p_bug_id, auth_get_current_user_id() ) ) {
+			return false;
+		}
+
+		$t_custom_field_string_table = config_get( 'mantis_custom_field_string_table' );
+
+		# do I need to update or insert this value?
+		$query = "SELECT value
+				  FROM $t_custom_field_string_table
+				  WHERE field_id='$c_field_id' AND
+				  		bug_id='$c_bug_id'";
+		$result = db_query( $query );
+
+		if ( db_num_rows( $result ) > 0 ) {
+			$query = "UPDATE $t_custom_field_string_table
+					  SET value='$c_value'
+					  WHERE field_id='$c_field_id' AND
+					  		bug_id='$c_bug_id'";
+			db_query( $query );
+
+			$row = db_fetch_array( $result );
+			history_log_event_direct( $c_bug_id, $t_name, custom_field_database_to_value( $row['value'], $t_type ), $p_value );
+		} else {
+			# Always store the value, even if it's the dafault value
+			# This is important, as the definitions might change but the
+			#  values stored with a bug must not change
+			$query = "INSERT INTO $t_custom_field_string_table
+						( field_id, bug_id, value )
+					  VALUES
+						( '$c_field_id', '$c_bug_id', '$c_value' )";
+			db_query( $query );
+			history_log_event_direct( $c_bug_id, $t_name, '', $p_value );
+		}
+
+		custom_field_clear_cache( $p_field_id );
+
+		#db_query() errors on failure so:
+		return true;
+	}
+
+	# --------------------
+	# Sets the sequence number for the specified custom field for the specified
+	# project.
+	function custom_field_set_sequence( $p_field_id, $p_project_id, $p_sequence ) {
+		$c_field_id = db_prepare_int( $p_field_id );
+		$c_project_id = db_prepare_int( $p_project_id );
+		$c_sequence = db_prepare_int( $p_sequence );
+
+		$t_custom_field_project_table = config_get( 'mantis_custom_field_project_table' );
+
+		$query = "UPDATE $t_custom_field_project_table
+				  SET sequence='$c_sequence'
+				  WHERE field_id='$c_field_id' AND
+				  		project_id='$c_project_id'";
+		$result = db_query( $query );
+
+		custom_field_clear_cache( $p_field_id );
+
+		return true;
+	}
+
+	#===================================
+	# Output
+	#===================================
+
+	# --------------------
+	# Print an input field
+	# $p_field_def contains the definition of the custom field (including it's
+	#              field id
+	# $p_bug_id    contains the bug where this field belongs to. If it's left
+	#              away, it'll default to 0 and thus belongs to a new (i.e.
+	#              non-existant) bug
+	# NOTE: This probably belongs in the print_api.php
+	function print_custom_field_input( $p_field_def, $p_bug_id = null ) {
+		$t_id = $p_field_def['id'];
+
+		if( null === $p_bug_id ) {
+			$t_custom_field_value = $p_field_def['default_value'];
+		} else {
+			$t_custom_field_value = custom_field_get_value( $t_id, $p_bug_id );
+		}
+
+		$t_custom_field_value = string_attribute( $t_custom_field_value );
+
+		switch ($p_field_def['type']) {
+		case CUSTOM_FIELD_TYPE_ENUM:
+		case CUSTOM_FIELD_TYPE_LIST:
+		case CUSTOM_FIELD_TYPE_MULTILIST:
+ 			$t_values = explode( '|', custom_field_prepare_possible_values( $p_field_def['possible_values'] ) );
+			$t_list_size = $t_possible_values_count = count( $t_values );
+
+			if ( $t_possible_values_count > 5 ) {
+				$t_list_size = 5;
+			}
+
+			if ( $p_field_def['type'] == CUSTOM_FIELD_TYPE_ENUM ) {
+				$t_list_size = 0;	# for enums the size is 0
+			}
+
+			if ( $p_field_def['type'] == CUSTOM_FIELD_TYPE_MULTILIST ) {
+				echo '<select ', helper_get_tab_index(), ' name="custom_field_' . $t_id . '[]" size="' . $t_list_size . '" multiple="multiple">';
+			} else {
+				echo '<select ', helper_get_tab_index(), ' name="custom_field_' . $t_id . '" size="' . $t_list_size . '">';
+			}
+
+			$t_selected_values = explode( '|', $t_custom_field_value );
+ 			foreach( $t_values as $t_option ) {
+				if( in_array( $t_option, $t_selected_values, true ) ) {
+ 					echo '<option value="' . $t_option . '" selected="selected"> ' . $t_option . '</option>';
+ 				} else {
+ 					echo '<option value="' . $t_option . '">' . $t_option . '</option>';
+ 				}
+ 			}
+ 			echo '</select>';
+			break;
+		case CUSTOM_FIELD_TYPE_CHECKBOX:
+			$t_values = explode( '|', custom_field_prepare_possible_values( $p_field_def['possible_values'] ) );
+			$t_checked_values = explode( '|', $t_custom_field_value );
+			foreach( $t_values as $t_option ) {
+				echo '<input ', helper_get_tab_index(), ' type="checkbox" name="custom_field_' . $t_id . '[]"';
+				if( in_array( $t_option, $t_checked_values, true ) ) {
+					echo ' value="' . $t_option . '" checked="checked">&nbsp;' . $t_option . '&nbsp;&nbsp;';
+				} else {
+					echo ' value="' . $t_option . '">&nbsp;' . $t_option . '&nbsp;&nbsp;';
+				}
+			}
+ 			break;
+		case CUSTOM_FIELD_TYPE_NUMERIC:
+		case CUSTOM_FIELD_TYPE_FLOAT:
+		case CUSTOM_FIELD_TYPE_EMAIL:
+		case CUSTOM_FIELD_TYPE_STRING:
+			echo '<input ', helper_get_tab_index(), ' type="text" name="custom_field_' . $t_id . '" size="80"';
+			if( 0 < $p_field_def['length_max'] ) {
+				echo ' maxlength="' . $p_field_def['length_max'] . '"';
+			} else {
+				echo ' maxlength="255"';
+			}
+			echo ' value="' . $t_custom_field_value .'"></input>';
+			break ;
+
+		case CUSTOM_FIELD_TYPE_DATE:
+			print_date_selection_set("custom_field_" . $t_id, config_get('short_date_format'), $t_custom_field_value, false, true) ;
+			break ;
+		}
+	}
+
+	# --------------------
+	# Prepare a string containing a custom field value for display
+	# $p_def 		contains the definition of the custom field
+	# $p_field_id 	contains the id of the field
+	# $p_bug_id		contains the bug id to display the custom field value for
+	# NOTE: This probably belongs in the string_api.php
+	function string_custom_field_value( $p_def, $p_field_id, $p_bug_id ) {
+		$t_custom_field_value = custom_field_get_value( $p_field_id, $p_bug_id );
+		switch( $p_def['type'] ) {
+			case CUSTOM_FIELD_TYPE_EMAIL:
+				return "<a href=\"mailto:$t_custom_field_value\">$t_custom_field_value</a>";
+				break;
+			case CUSTOM_FIELD_TYPE_ENUM:
+			case CUSTOM_FIELD_TYPE_LIST:
+			case CUSTOM_FIELD_TYPE_MULTILIST:
+			case CUSTOM_FIELD_TYPE_CHECKBOX:
+				return str_replace( '|', ', ', $t_custom_field_value );
+				break;
+			case CUSTOM_FIELD_TYPE_DATE:
+				if ($t_custom_field_value != null) {
+					return date( config_get( 'short_date_format'), $t_custom_field_value) ;
+				}
+				break ;
+			default:
+				return string_display_links( $t_custom_field_value );
+		}
+	}
+
+	# --------------------
+	# Print a custom field value for display
+	# $p_def 		contains the definition of the custom field
+	# $p_field_id 	contains the id of the field
+	# $p_bug_id		contains the bug id to display the custom field value for
+	# NOTE: This probably belongs in the print_api.php
+	function print_custom_field_value( $p_def, $p_field_id, $p_bug_id ) {
+		echo string_custom_field_value( $p_def, $p_field_id, $p_bug_id );
+	}
+
+	# --------------------
+	# Prepare a string containing a custom field value for email
+	# $p_value		value of custom field
+	# $p_type		type of custom field
+	# NOTE: This probably belongs in the string_api.php
+	function string_custom_field_value_for_email( $p_value, $p_type ) {
+		switch( $p_type ) {
+			case CUSTOM_FIELD_TYPE_EMAIL:
+				return 'mailto:'.$p_value;
+				break;
+			case CUSTOM_FIELD_TYPE_ENUM:
+			case CUSTOM_FIELD_TYPE_LIST:
+			case CUSTOM_FIELD_TYPE_MULTILIST:
+			case CUSTOM_FIELD_TYPE_CHECKBOX:
+				return str_replace( '|', ', ', $p_value );
+				break;
+			case CUSTOM_FIELD_TYPE_DATE:
+				if ($p_value != null) {
+					return date( config_get( 'short_date_format' ), $p_value) ;
+				}
+				break ;
+			default:
+				return $p_value;
+		}
+		return $p_value;
+	}
+
+?>
custom_field_api.php.patch (93,489 bytes)   

Relationships

duplicate of 0006626 closeddaryn Support "Memo" custom field type 

Activities

vboctor

vboctor

2009-10-31 04:33

manager   ~0023511

@liebscher, thanks for your contribution.

Why does it look like each line in the file has changed? Will you be able to provide a new patch that doesn't have this issue?

vboctor

vboctor

2009-10-31 04:35

manager   ~0023512

Resolved as duplicate of 0006626. Please add the new patch there.