<?php

	/*
	** File: standard_library
	** Description: This module contains functions that are needed in at least
	** 75% of all page views.  Most of these functions were in global_settings
	** at one time.
	**
	** Version: $Revision: 1.16 $
	** Created: 10/4/99
	** Author: Leon Atkinson
	** Email: leon@clearink.com
	** CVS Author: $Author: leon $
	** Last Revised: $Date: 2000/03/13 17:37:30 $
	** Log : $Log: standard_library,v $
	** Log : Revision 1.16  2000/03/13 17:37:30  leon
	** Log : OK, really fixing it.
	** Log :
	** Log : Revision 1.14  2000/02/02 18:59:46  leon
	** Log : Fixing bugs reported by Ted Henigson.
	** Log :
	** Log : Revision 1.13  1999/12/17 22:08:30  leon
	** Log : Added function to print invoice totals, consequently updated printTableRow
	** Log : to allow passing of styles.
	** Log :
	** Log : Revision 1.12  1999/12/16 23:58:16  leon
	** Log : Created new function for checking for required global variables.  I've
	** Log : converted a few actions to use this new function.  At some point we should
	** Log : convert them all.
	** Log :
	** Log : Revision 1.11  1999/12/09 23:23:33  leon
	** Log : Changed ActionResults use so that it's an array instead of a
	** Log : continually-growing string.  Note the little function in standard_library
	** Log : for printing out all the action results.
	** Log :
	** Log : Revision 1.10  1999/12/09 04:11:36  jj
	** Log : Cleaned up the comments for startForm a wee bit.
	** Log :
	** Log : Revision 1.9  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.8  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.7  1999/11/08 22:32:18  leon
	** Log : Added prepareText() function to use everywhere we were using htmlentities.
	** Log :
	** Log : Revision 1.6  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.5  1999/10/12 00:33:36  leon
	** Log : Last change should not have been committed.  Crap.
	** Log :
	** Log : Revision 1.4  1999/10/12 00:28:58  leon
	** Log : Added some checking for weirdness related to Apache for Windows.
	** Log :
	** Log : Revision 1.3  1999/10/04 22:09:55  leon
	** Log : Removed getInvoiceID.  The active invoice is now added to $UserInfo
	** Log : by the check sid functionality in init.
	** Log :
	** Log : Revision 1.2  1999/10/04 20:21:05  leon
	** Log : Add log to comment block
	** Log :
	**
	** Copyright (c) 1999 Working Dogs.  All rights reserved.
	*/


	/*
	** Function: ScreenURL
	** Input: $screen, [$secure], [$extra]
	** Output: Function that adds session id and screen to URL.  If $secure is
	**   TRUE, then the URL returned will force SSL mode. Returns something
	**   like:
	**   "http://jjinux/practice/index.php3?sid=kajsdfsdflokjsf&SCREEN=Home"
	**
	**	The extra argument should be an associative array of form variables.
	*/
	function ScreenURL($screen, $secure=FALSE, $extra='')
	{
		global $sid;
		global $UserInfo;

		if(USE_SSL AND $secure)
		{
			$URL = "https://";
		}
		else
		{
			$URL = "http://";
		}

		$URL .= SERVER_NAME . EXTERNAL_PATH . SCRIPT_NAME . "?SCREEN=$screen";

		if((!USE_COOKIES) OR (!COOKIE_FOUND))
		{
			$URL .= "&amp;sid=$sid";
		}

		if(is_array($extra))
		{
			for(reset($extra); $key=key($extra); next($extra))
			{
				$URL .= "&amp;$key=" . prepareText($extra[$key]);
			}
		}


		return($URL);
	}


	/*
	** Function: StartForm
	** Input: $screen, [$method], [$action], [$secure], [$extra],
	**   [$windowName], [$encodingType], [$formName], [$onReset], [$onSubmit]
	** Output: String
	** Description: Returns necessary form tags to start a form, including SCREEN,
	**   ACTION, and sid hidden variables.  If $secure==TRUE, then https will be
	**   used.  If $extra is an array, then key/value pairs will be used to make
	**   extra hidden variables.  The last six arguments are for the case when
	**   you need to override the default tags for some reason.  Empty values will
	**   cause the attributes to be excluded from the FORM tag.
	**
	** Two common encodingTypes are
	**   application/x-www-form-urlencoded	(default)
	**   multipart/form-data	      				(for uploads)
	*/
	function StartForm($screen, $method='get', $action='', $secure=FALSE, $extra='',
		$windowName='', $encodingType='', $formName='', $onReset='', $onSubmit='')
	{
		global $sid;

		if(USE_SSL AND $secure)
		{
			$URL = "https://";
		}
		else
		{
			$URL = "http://";
		}

		$URL .= SERVER_NAME . EXTERNAL_PATH . SCRIPT_NAME;

		/*
		** opening form tag
		*/
		$FormHead = "<FORM ACTION=\"$URL\" ";
		$FormHead .= "METHOD=\"$method\" ";

		if($windowName != '')
		{
			$FormHead .= "TARGET=\"$windowName\" ";
		}
		if($encodingType != '')
		{
			$FormHead .= "ENCTYPE=\"$encodingType\" ";
		}
		if($formName != '')
		{
			$FormHead .= "NAME=\"$formName\" ";
		}
		if($onReset != '')
		{
			$FormHead .= "ONRESET=\"$onReset\" ";
		}
		if($onSubmit != '')
		{
			$FormHead .= "ONSUBMIT=\"$onSubmit\" ";
		}

		$FormHead .= ">\n";

		/*
		** session ID
		*/
		if((!USE_COOKIES) OR (!COOKIE_FOUND))
		{
			$FormHead .= "<INPUT TYPE=\"hidden\" NAME=\"sid\" VALUE=\"$sid\">\n";
		}


		/*
		** SCREEN
		*/
		$FormHead .= "<INPUT TYPE=\"hidden\" NAME=\"SCREEN\" VALUE=\"$screen\">\n";

		/*
		** ACTION
		*/
		if($action != '')
		{
			$FormHead .= "<INPUT TYPE=\"hidden\" NAME=\"ACTION\" VALUE=\"$action\">\n";
		}

		/*
		** Extra hidden vars
		*/
		if(is_array($extra))
		{
			for(reset($extra); $key=key($extra); next($extra))
			{
				$FormHead .= "<INPUT TYPE=\"hidden\" NAME=\"$key\" VALUE=\"";
				$FormHead .= prepareText($extra[$key]) . "\">\n";
			}
		}

		return($FormHead);
	}


	//returns associative array of user information
	//this function should be renamed with a leading lowercase letter
	function GetUserInfo($userID)
	{
		global $DatabaseLink;

		if($userID > 0)
		{

			$ReturnValue["ID"] = $userID;

			$Query = "SELECT u.Login, u.Password, a.* ";
			$Query .= "FROM address a, user u ";
			$Query .= "WHERE a.ID = u.Address ";
			$Query .= "AND u.ID = $userID ";
			$DatabaseResult = mysql_query($Query, $DatabaseLink);
			$DatabaseRow = mysql_fetch_object($DatabaseResult);

			//columns in user table
			$ReturnValue["Login"] = $DatabaseRow->Login;
			$ReturnValue["Password"] = $DatabaseRow->Password;

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


			//get permissions
			$Query = "SELECT p.Name ";
			$Query .= "FROM user_permission up, permission p ";
			$Query .= "WHERE up.User=$userID ";
			$Query .= "AND up.Permission = p.ID ";
			$DatabaseResult = mysql_query($Query, $DatabaseLink);
			while($DatabaseRow = mysql_fetch_row($DatabaseResult))
			{
				$ReturnValue["Permission"][($DatabaseRow[0])] = TRUE;
			}
		}
		else
		{
			/*
			** Default values for users who aren't logged in.
			*/
			$ReturnValue["ID"] = 0;
			
			//it's nice to zero these 
			$ReturnValue["Address"]["ID"] = "";
			$ReturnValue["Address"]["Name_Prefix"] = "";
			$ReturnValue["Address"]["Name_First"] = "";
			$ReturnValue["Address"]["Name_Middle"] = "";
			$ReturnValue["Address"]["Name_Last"] = "";
			$ReturnValue["Address"]["Name_Suffix"] = "";
			$ReturnValue["Address"]["Company"] = "";
			$ReturnValue["Address"]["Street1"] = "";
			$ReturnValue["Address"]["Street2"] = "";
			$ReturnValue["Address"]["Street3"] = "";
			$ReturnValue["Address"]["City"] = "";
			$ReturnValue["Address"]["StateProv"] = "";
			$ReturnValue["Address"]["PostalCode"] = "";
			$ReturnValue["Address"]["CountryCode"] = "";
			$ReturnValue["Address"]["Phone1"] = "";
			$ReturnValue["Address"]["Phone2"] = "";
			$ReturnValue["Address"]["Fax"] = "";
			$ReturnValue["Address"]["Email"] = "";
		}

		return($ReturnValue);
	}


	/*
	** Function: prepareText
	** Input: $text, $type
	** Output: modified text
	**
	** If you are using Latin characters, using PT_ENTITIES
	** may be your best choice.  Unicode sites will need
	** to use PT_SPECIAL to avoid mangling characters.
	** If you need to do some other kind of filtering, add
	** it here.
	*/

	define("PT_SPECIAL", 0);
	define("PT_ENTITIES", 1);
	define("PT_PLAIN", 2);

	function prepareText($text, $type=PT_ENTITIES)
	{
		//prepare text according to use
		switch($type)
		{
			case PT_SPECIAL:
				$text = htmlspecialchars($text);
				break;

			case PT_ENTITIES:
				$text = htmlentities($text);
				break;

			case PT_PLAIN:
				//do nothing
				break;
		}

		//return the modified text
		return($text);
	}


	/*
	** Function: printTableRow
	** Input: STRING label, STRING/ARRAY field, BOOLEAN prepare,
	**	STRING rowStyle, STRING colStyle
	** Ouput: prints table row
	** Description: Outputs a table row with the given label and 
	**	unlimited values as an array or not.  The prepare argument
	**	controls whether prepareText is called on the fields. The
	**	labelStyle and fieldStyle arguments will be used inside 
	**	style="" attributes if they aren't empty.
	**
	**	Uses prepareText() on the field value.
	*/
	function printTableRow($label, $field, $prepare=TRUE, $labelStyle="", $fieldStyle="")
	{
		print("<TR>\n");
		
		/*
		** label
		*/
		print("<TD");
		if($labelStyle != "")
		{
			print(" style=\"$labelStyle\"");
		}
		print(">");
		print($label);
		print("</TD>\n");
		
		/*
		** fields
		*/
		if(is_array($field))
		{
			/*
			** Array of values
			*/

			while(list($key, $value) = each($field))
			{
				print("<TD");
				if($fieldStyle != "")
				{
					print(" style=\"$fieldStyle\"");
				}
				print(">");
				if($prepare)
				{
					print(prepareText($value));
				}
				else
				{
					print($value);
				}
				print("</TD>\n");
			}
		}
		else
		{
			/*
			** Single value
			*/
		
			print("<TD");
			if($fieldStyle != "")
			{
				print(" style=\"$fieldStyle\"");
			}
			print(">");
			if($prepare)
			{
				print(prepareText($field));
			}
			else
			{
				print($field);
			}
			print("</TD>\n");
		}
		
		print("</TR>\n");
	}


	/*
	** Function: printEditRow
	** Input: $label, $field, $value
	** Description: Outputs a table row to allow a user to edit a particular
	**   field. Uses prepareText() when outputing $value.
	*/
	function printEditRow($label, $field, $value, $size=32, $max=FALSE)
	{
		print("<TR>\n");

		print("<TD>");
		print($label);
		print("</TD>\n");
		
		print("<TD>");
		print("<INPUT TYPE=\"text\" ");
		print("NAME=\"$field\" ");
		print("SIZE=\"32\" ");

		if($max)
		{
			print("MAXLENGTH=\"$max\" ");
		}

		print("VALUE=\"" . prepareText($value) . "\">");
		print("</TD>\n");
		
		print("</TR>\n");
	}

	//blank out ActionResults
	$ActionResults = "";
	
	//This function is used by layout modules to show
	//any info passed back by action modules.
	//If you want something fancier than just a list,
	//tweak this code.
	function printActionResults()
	{
		global $ActionResults;
		
		if(is_array($ActionResults) AND count($ActionResults))
		{
			for($i=0; $i < count($ActionResults); $i++)
			{
				print($ActionResults[$i] . "<BR>\n");
			}
		}
	}



	/*
	** Function: haveGlobals
	** Input: ARRAY variable
	** Output: BOOLEAN
	** Description: return TRUE if all variables named in the
	** input array are present in the global scope.  This 
	** function may be used by both action and screen modules to 
	** make sure all the expected form fields were submitted.
	*/
	function haveGlobals($variable)
	{
		//loop over input array
		reset($variable);
		while(list($var, $type) = each($variable))
		{
			if(!isset($GLOBALS[$var]))
			{
				//missing variable, return immediately
				return(FALSE);
			}
			else
			{
				//force type if one of the scalar types
				//we can't force an array type
				if(($type=='string') OR
					($type=='integer') OR
					($type=='double'))
				{
					settype($GLOBALS[$var], $type);
				}
			}	
		}

		return(TRUE);		
	}
?>
