<?php 

	/* 
	** File: addressFunctions
	** Description: This is a set of functions to do things like 1) ouput
	**   form fields to get address info from the user 2) output form fields
	**   to edit address info 3) simply output an address in a nice little 
	**   table 4) verify required fields do indeed have values (this is used 
	**   by actions).
	** Version: $Revision: 1.13 $
	** Created: 8/8/99
	** Author: Shannon -jj Behrens
	** Email: jj@clearink.com
	** CVS Author: $Author: leon $
	** Last Revised: $Date: 1999/12/21 19:08:52 $
	**
	** Log : $Log: addressFunctions,v $
	** Log : Revision 1.13  1999/12/21 19:08:52  leon
	** Log : Created new billing module that handles operations on the billing table.
	** Log : Encorporated it into the two action modules that need to use it.
	** Log :
	** Log : Revision 1.12  1999/12/15 17:23:27  leon
	** Log : Added functionality from Mari Bester to translate displayed StateProv
	** Log : and Country address fields from codes into names.
	** Log :
	** Log : Revision 1.11  1999/12/08 00:55:08  leon
	** Log : Pulled functions for creating table rows out of addressFunctions and
	** Log : generalized them.  I'm leaving wrappers for the old functions, but I
	** Log : will removed them in the coming weeks.
	** Log :
	** Log : Revision 1.10  1999/12/06 21:17:23  leon
	** Log : ECML compliance
	** Log : Overhauled address functions to use ECML form field names.  Ditto with
	** Log : the billing fields on the checkout forms.  Note the change to build.sql.
	** Log : Yes, the address table changed to accomodate new fields.  The billing
	** Log : table changed too.
	** Log :
	** Log : Revision 1.9  1999/11/08 22:32:18  leon
	** Log : Added prepareText() function to use everywhere we were using htmlentities.
	** Log :
	** Log : Revision 1.8  1999/11/04 21:35:33  leon
	** Log : Cleaned up the use of paths.  Paths are now all set in index.php3 as
	** Log : constants.  Example settings for Apache/Unix, Apache/Win32, and IIS.
	** Log :
	** Log : Revision 1.7  1999/10/12 23:46:05  leon
	** Log : Moved string constants from addressFunctions into english module
	** Log :
	** Log : Revision 1.6  1999/10/12 16:18:34  leon
	** Log : Pulled text out of addressFunctions in preparation for localization.
	** Log :
	** Log : Revision 1.5  1999/10/11 23:04:02  leon
	** Log : Removed all require()'s, added block to stop double include()'s
	** Log :
	** Log : Require wasn't giving any performance advantage because it was always
	** Log : being called with a variable.  Futhermore, using return inside a
	** Log : require()'d file does not work in PHP4.
	** Log :
	** Log : Revision 1.4  1999/09/10 00:14:14  jj
	** Log : Wrapped everything in basically an ifndef.
	** Log :
	** Log : Revision 1.3  1999/08/18 22:32:03  leon
	** Log : Returning opening PHP tag to XML-friendly tag
	** Log :
	** Log : Revision 1.2  1999/08/17 18:11:53  jj
	** Log : Added CVS variables to include/addressFunctions
	** Log :
	** Copyright (c) 1999 Working Dogs. All rights reserved. 
	*/


	/*
	** Ensure that these functions aren't included twice
	*/

	$included_flag = 'INCLUDE_' . basename(__FILE__);
	
	if(defined($included_flag))
		//if this module has been included already, then the
		//constant will be defined.  Note the unusual use of
		//the return statement here.  Control will return to
		//the file that included it.
		return;
	
	define($included_flag, TRUE);	



	/* 
	** <select>'s for state and country fields
	*/
	include (APPLICATION_ROOT . "/modules/include/makeCountrySelector");
	include (APPLICATION_ROOT . "/modules/include/makeStateSelector");


	/*
	** Array of fields in the address table matched to
	** labels and default form field names.  Form fields
	** comply with ECML so that if you add an appropriate
	** prefix you get valid ECML field names.
	*/
	//text with which to label the field
	define("ADDR_LABEL", 0);
	
	//name of the form field (sans prefix of course)
	define("ADDR_VAR", 1);
	
	//error message to display for missing fields
	define("ADDR_ERROR", 2);

	$AddressInfo = array(
		"Name_Prefix"=>array(
			ADDR_LABEL=>L_ADDRESSFUNC_PREFIX, 
			ADDR_VAR=>"Postal_Name_Prefix",
			ADDR_ERROR=>L_ADDRESSFUNC_PREFIX_ERROR),
		"Name_First"=>array(
			ADDR_LABEL=>L_ADDRESSFUNC_FIRSTNAME, 
			ADDR_VAR=>"Postal_Name_First",
			ADDR_ERROR=>L_ADDRESSFUNC_FIRSTNAME_ERROR),
		"Name_Middle"=>array(
			ADDR_LABEL=>L_ADDRESSFUNC_MIDDLENAME, 
			ADDR_VAR=>"Postal_Name_Middle",
			ADDR_ERROR=>L_ADDRESSFUNC_MIDDLE_ERROR),
		"Name_Last"=>array(
			ADDR_LABEL=>L_ADDRESSFUNC_LASTNAME, 
			ADDR_VAR=>"Postal_Name_Last",
			ADDR_ERROR=>L_ADDRESSFUNC_LASTNAME_ERROR),
		"Name_Suffix"=>array(
			ADDR_LABEL=>L_ADDRESSFUNC_SUFFIX, 
			ADDR_VAR=>"Postal_Name_Suffix",
			ADDR_ERROR=>L_ADDRESSFUNC_SUFFIX_ERROR),
		"Company"=>array(
			ADDR_LABEL=>L_ADDRESSFUNC_COMPANY, 
			ADDR_VAR=>"Postal_Company",
			ADDR_ERROR=>L_ADDRESSFUNC_COMPANY_ERROR),
		"Street1"=>array(
			ADDR_LABEL=>L_ADDRESSFUNC_ADDRESS1, 
			ADDR_VAR=>"Postal_Street_Line1",
			ADDR_ERROR=>L_ADDRESSFUNC_ADDRESS1_ERROR),
		"Street2"=>array(
			ADDR_LABEL=>L_ADDRESSFUNC_ADDRESS2, 
			ADDR_VAR=>"Postal_Street_Line2",
			ADDR_ERROR=>L_ADDRESSFUNC_ADDRESS2_ERROR),
		"Street3"=>array(
			ADDR_LABEL=>L_ADDRESSFUNC_ADDRESS3, 
			ADDR_VAR=>"Postal_Street_Line3",
			ADDR_ERROR=>L_ADDRESSFUNC_ADDRESS3_ERROR),
		"City"=>array(
			ADDR_LABEL=>L_ADDRESSFUNC_CITY, 
			ADDR_VAR=>"Postal_City",
			ADDR_ERROR=>L_ADDRESSFUNC_CITY_ERROR),
		"StateProv"=>array(
			ADDR_LABEL=>L_ADDRESSFUNC_STATE, 
			ADDR_VAR=>"Postal_StateProv",
			ADDR_ERROR=>L_ADDRESSFUNC_STATE_ERROR),
		"PostalCode"=>array(
			ADDR_LABEL=>L_ADDRESSFUNC_ZIP, 
			ADDR_VAR=>"Postal_PostalCode",
			ADDR_ERROR=>L_ADDRESSFUNC_ZIP_ERROR),
		"CountryCode"=>array(
			ADDR_LABEL=>L_ADDRESSFUNC_COUNTRY, 
			ADDR_VAR=>"Postal_CountryCode",
			ADDR_ERROR=>L_ADDRESSFUNC_COUNTRY_ERROR),
		"Phone1"=>array(
			ADDR_LABEL=>L_ADDRESSFUNC_PHONE1, 
			ADDR_VAR=>"Telecom_Phone_Number",
			ADDR_ERROR=>L_ADDRESSFUNC_PHONE1_ERROR),
		"Phone2"=>array(
			ADDR_LABEL=>L_ADDRESSFUNC_PHONE2, 
			ADDR_VAR=>"Telecom_Phone_Number2",
			ADDR_ERROR=>L_ADDRESSFUNC_PHONE2_ERROR),
		"Fax"=>array(
			ADDR_LABEL=>L_ADDRESSFUNC_FAX, 
			ADDR_VAR=>"Telecom_Fax_Number",
			ADDR_ERROR=>L_ADDRESSFUNC_FAX_ERROR),
		"Email"=>array(
			ADDR_LABEL=>L_ADDRESSFUNC_EMAIL, 
			ADDR_VAR=>"Online_Email",
			ADDR_ERROR=>L_ADDRESSFUNC_EMAIL_ERROR)
		);




	/*
	** Function: printAddressFields
	** Input: 
	**
	**  Array [$Value] - An associative array of the form 
	**     "Name_First"=>"Shannon".  These will be used as the default values
	**     for each of the fields.  If it is 0, there will be no default
	**     values. Whenever appropriate, you can just use $UserInfo.
	** 
	**	String [$Prefix] - The string to be prepended to each of the NAME tags
	**     of the html form fields. For instance, $prepend="ship_" will 
	**     produce <INPUT TYPE=\"text\" NAME=\"ship_Name_First\" VALUE=\"">.
	**
	**	String [$Field] - This may either be the string "ALL" (in which case
	**     all of the fields will be asked for), or it may be an array of
	**     field names (you can get the list of valid names from the database).
	**     The keys are the fields from $AddressFields, the values are the
	**     names to use for the form fields.  
	**     Note, this variable only determines which fields to ask for, not 
	**     which fields to require.
	**
	**  String [$SubmitLabel, $ResetLabel] - The names of the submit and reset
	**     buttons. If left out, they will have default values. If 0 is 
	**     used, for either, that button will not be created.
	**
	**  Integer [$CreateTable] - This is TRUE by default.  It if it set to FALSE,
	**     we will assume that we are already in a table, and we need not 
	**     ouput the opening or closing table tags.
	** 
	**  Output: None (uses print)
	**  Description: Outputs the fields of a form (note: it does not actually
	**     start the form or end the form) to either allow a user to edit an 
	**     address ($values better be full) or to create an address (it would 
	**     be nice if you gave $values default values).
	*/
	function printAddressFields(
		$Value=0, 
		$Prefix="", 
		$Field="ALL", 
		$SubmitLabel="Submit", 
		$ResetLabel="Reset", 
		$CreateTable=TRUE)
	{
	
		global $AddressInfo;

		//create empty values if none given
		if( ! is_array($Value))
		{
			//clean out variable
			unset($Value);
		
			//get list of all address fields
			//from the AddressInfo array
			reset($AddressInfo);
			while(list($key) = each($AddressInfo))
			{
				$Value[$key] = '';
			}
		}

		//copy complete list of fields if necessary
		if( is_string($Field) AND ($Field == "ALL") )
		{
			//clean out variable
			unset($Field);
		
			//get list of all address fields
			//from the AddressInfo array
			reset($AddressInfo);
			while(list($key) = each($AddressInfo))
			{
				$Field[] = $key;
			}
		}


		// Start the table if necessary
		if($CreateTable)
		{
			print("<TABLE>\n");
		}


		//loop through fields
		reset($Field);
		while(list($key, $FieldName) = each($Field))
		{
			if($FieldName == "StateProv")
			{
				print("<TR>\n");
				print("<TD>".$AddressInfo[$FieldName][ADDR_LABEL]."</TD>\n");
				print("<TD>");
				makeStateSelector(($Prefix . $AddressInfo[$FieldName][ADDR_VAR]), 
					$Value[$FieldName]);
				print("</TD>\n");
				print("</TR>\n");
			}
			elseif($FieldName == "CountryCode")
			{
				print("<TR>\n");
				print("<TD>".$AddressInfo[$FieldName][ADDR_LABEL]."</TD>\n");
				print("<TD>");
				makeCountrySelector(($Prefix . $AddressInfo[$FieldName][ADDR_VAR]), 
					$Value[$FieldName]);
				print("</TD>\n");
				print("</TR>\n");
			}
			else
			{
				printEditRow(
					$AddressInfo[$FieldName][ADDR_LABEL],
					($Prefix . $AddressInfo[$FieldName][ADDR_VAR]), 
					$Value[$FieldName]);
			}
		}


		// Do submit and reset buttons
		if( $SubmitLabel OR $ResetLabel )
		{
			print("<TR>\n");
			print("<TD COLSPAN=\"2\">\n");
			if ( $SubmitLabel )
			{
				print("<INPUT TYPE=\"submit\" VALUE=\"$SubmitLabel\">\n");
			}
			if ( $ResetLabel )
			{
				print("<INPUT TYPE=\"reset\" VALUE=\"$ResetLabel\">\n");
			}
			print("</TD>\n");
			print("</TR>\n");
		}


		//close table if necessary
		if($CreateTable)
		{
			print("</TABLE>\n");
		}
	}


	/*
	** Function: outputAddress
	** Input: Associative Array $value - the array members should have the 
	**   form "FirstName"=>"Shannon". $noTable - do not do the opening and 
	**   closing table tags.
	** Ouput: None (uses print).
	** Description: Output the address (whichever members of it we have) in 
	**   a nice little table. If you insist on outputing a blank field, 
	**   just define the value as "".
	*/
	function outputAddress($Value, $Field="ALL", $CreateTable=TRUE)
	{
		global $AddressInfo;

		//copy complete list of fields if necessary
		if( is_string($Field) AND ($Field == "ALL") )
		{
			//clean out variable
			unset($Field);
		
			//get list of all address fields
			//from the AddressInfo array
			reset($AddressInfo);
			while(list($key) = each($AddressInfo))
			{
				$Field[] = $key;
			}
		}


		if($CreateTable) 
		{ 
			print("<TABLE>\n"); 
		}


		//loop through fields
		reset($Field);
		while(list($key, $FieldName) = each($Field))
		{
			//StateProv and CountryCode need to be de-coded
			if($FieldName == "StateProv")
			{
				printTableRow($AddressInfo[$FieldName][ADDR_LABEL],   
					getStateName($Value[$FieldName]));
			}
			elseif($FieldName == "CountryCode")
			{
				printTableRow($AddressInfo[$FieldName][ADDR_LABEL],   
					getCountryName($Value[$FieldName]));
			}
			else
			{
				printTableRow($AddressInfo[$FieldName][ADDR_LABEL],   
					$Value[$FieldName]);
			}
		}

	
		if($CreateTable)
		{	
			print("</TABLE>\n");
		}
	}



	/*
	** Function: verifyAddress
	** Input:
	**	$required - array of fields to require 
	**	$address - an associative array whose members are of the form
	**   "Name_First"=>"Shannon".
	**	$description - text describing errors, passed by reference
	**
	** Output: "" on success, a non-null string on error.  The non-null string 
	**     will be something like:
	**     "You must fill in a first name.<BR>You must fill in a last name."
	** Description: This function may be used by action modules to check for
	**     required fields.
	*/
	function verifyAddress($required, $address, &$description)
	{
		global $AddressInfo;
		
		//init error message
		$description = "";
		$status = TRUE;
		
		reset($required);
		while(list($key, $field_name) = each($required))
		{
			if(trim($address[$field_name]) == "")
			{
				$description .= $AddressInfo[$field_name][ADDR_ERROR] . "<BR>\n";
				$status = FALSE;
			}
		}
		
		return($status);
	}


	/*
	** Function: getAddress
	** Input: 
	**
	**  $addressID - The ID of the address
	**
	**  [$Field] - An associative array of the form "FirstName"=>0. The
	**   associative array will be returned with all the 0's filled in with
	**   the appropriate values. The default for $fields (i.e. what you get
	**   if you leave $fields out) is to return all fields in an assoc. array.
	**
	** Output: An associative array of the form "FirstName"=>"Shannon". If 
	**   $addressID is not a valid address ID, 0 will be returned.
	** Description: Given an address ID, use this function to retrieve all
	**   of the information about that address from the database.
	*/
	function getAddress($addressID)
	{
		global $DatabaseLink;

		if($addressID <= 0)
		{
			print("Warning: Invalid address ID ($addressID)!<BR>\n");
			return(0);
		}

		$Query = "SELECT a.* ";
		$Query .= "FROM address a ";
		$Query .= "WHERE a.ID = $addressID ";
		$DatabaseResult = mysql_query($Query, $DatabaseLink);
		$DatabaseRow = mysql_fetch_object($DatabaseResult);

		//user's personal address
		$ReturnValue["ID"] = $DatabaseRow->ID;
		$ReturnValue["Name_Prefix"] = $DatabaseRow->Name_Prefix;
		$ReturnValue["Name_First"] = $DatabaseRow->Name_First;
		$ReturnValue["Name_Middle"] = $DatabaseRow->Name_Middle;
		$ReturnValue["Name_Last"] = $DatabaseRow->Name_Last;
		$ReturnValue["Name_Suffix"] = $DatabaseRow->Name_Suffix;
		$ReturnValue["Company"] = $DatabaseRow->Company;
		$ReturnValue["Street1"] = $DatabaseRow->Street1;
		$ReturnValue["Street2"] = $DatabaseRow->Street2;
		$ReturnValue["Street3"] = $DatabaseRow->Street3;
		$ReturnValue["City"] = $DatabaseRow->City;
		$ReturnValue["StateProv"] = $DatabaseRow->StateProv;
		$ReturnValue["PostalCode"] = $DatabaseRow->PostalCode;
		$ReturnValue["CountryCode"] = $DatabaseRow->CountryCode;
		$ReturnValue["Phone1"] = $DatabaseRow->Phone1;
		$ReturnValue["Phone2"] = $DatabaseRow->Phone2;
		$ReturnValue["Fax"] = $DatabaseRow->Fax;
		$ReturnValue["Email"] = $DatabaseRow->Email;
		
		return($ReturnValue);
	}



	/*
	** Function insertAddress
	** Input: $address - an array of the form "FirstName"=>"Shannon". Any fields
	**   that are missing will be given the value of "".
	** Return: The ID of the new address row, or 0 on error.
	*/
	function insertAddress($address)
	{
		/* Setup all the variables. */
		global $DatabaseLink;
		global $AddressInfo;
		
		$QuerySpec = "INSERT INTO address (";
		$QueryValues = "VALUES (";

		reset($AddressInfo);
		while(list($FieldName) = each($AddressInfo))
		{
			$QuerySpec .= $FieldName . ",";
			$QueryValues .= "'" . $address[$FieldName] . "',";
		}
		
		//strip trailing commas and add closing parenthesis
		//(note that using -1 in the third argument of substr()
		//means one less than total length)
		$QuerySpec = substr($QuerySpec, 0, -1) . ") ";
		$QueryValues = substr($QueryValues, 0, -1) . ") ";
		

		/* Do the query. */
		$query = $QuerySpec . $QueryValues;
		$DatabaseResult = mysql_query($query, $DatabaseLink);
		if(!$DatabaseResult)
		{
			print("<!-- Unable to create address record!\n");
			print("$Query -->\n");
			return(0);
		}

		//returns 0 on error
		return(mysql_insert_id($DatabaseLink)); 
	}


	/*
	** Function getAddressFromEnvironment
	** Input: $Prefix - prefix used to generate address form
	** Return: array suitable for addressFields
	*/
	function getAddressFromEnvironment($Prefix)
	{
		global $AddressInfo;
		
		//get list of all address fields
		//from the AddressInfo array
		reset($AddressInfo);
		while(list($field, $info) = each($AddressInfo))
		{
			$ReturnValue[$field] = trim($GLOBALS[($Prefix . $info[ADDR_VAR])]);
		}

		return($ReturnValue);	
	}
	

	/*
	** Function updateAddress
	** Input: $ID -- address row to update 
	** $address - an array of the form "Name_First"=>"Shannon". Any fields
	**   that are missing will be given the value of "".
	** Return: TRUE or FALSE
	*/
	function updateAddress($ID, $address)
	{
		// Setup all the variables
		global $DatabaseLink;
		global $AddressInfo;
		
		$Query = "UPDATE address SET ";

		reset($AddressInfo);
		while(list($FieldName) = each($AddressInfo))
		{
			$Query .= $FieldName . "='" . addslashes($address[$FieldName]) . "',";
		}
		
		//strip trailing commas and add closing parenthesis
		//(note that using -1 in the third argument of substr()
		//means one less than total length)
		$Query = substr($Query, 0, -1) . " ";
		
		$Query .= "WHERE ID=$ID ";

		// Do the query
		$DatabaseResult = mysql_query($Query, $DatabaseLink);
		if(!$DatabaseResult)
		{
			print("<!-- Unable to update address record! -->\n");
			return(FALSE);
		}

		return(TRUE); 
	}


	/*
	** Function: destroyAddress
	** Input: INTEGER address
	** Ouput: BOOLEAN
	** Description: destroys a row in the address table
	*/
	//this function may be useful, but don't code it until necessary

	/*
	** Function: destroyAddressList
	** Input: ARRAY list
	** Ouput: BOOLEAN
	** Description: destroys all address records in a set
	*/
	function destroyAddressList($list)
	{
		global $DatabaseLink;
		
		$Query = "DELETE FROM address ";
		$Query .= "WHERE ID in ($list) ";
		if(!mysql_query($Query, $DatabaseLink))
		{
			//PANIC
			//The query didn't work!
			//(A call to the future log functionality should go here)
			print("\n\n<!-- ($Query) failed! \n" . 
				mysql_errno() . ": " . mysql_error() . "-->\n\n");

			return(FALSE);
		}
		else
		{
			return(TRUE);
		}
	
	}
	
?>
