TWIG 2.0 Code Specifications
March 13, 2000

FUTURE
======
    By structuring TWIG as an information framework, PHP can be extended to
    allow rapid application development and deployment that will be able to
    work within a highly integrated, mutli-user environment.

STRUCTURE
=========
    TWIG is designed to be highly and easily extended.  It does this by
    providing an application framework which allows "feature modules" to be
    plugged in and take full advantage of the overall API, authentication,
    session variable management, and virtualhosting configurability.

    The framework is provided by the main index.php3 file, which reads in the
    configuration files, function libraries, and feature modules.  The output
    is generally wrapped in a custom header and footer that the admin can
    define.

General File Conventions
========================

    Some general guidelines for file naming are as follows:

	- All files that php will parse must end in .php3
	- Files which are not top level php files but instead
	  are included for functions should end in .inc.php3

    Where applicable all include file should use if( !$included[filename] ) 
    to  ensure that the same include file is not included more than once.

FILES AND DIRECTORIES
=====================

    index.php3
	- Includes core library
	- Includes and parses config files
	- Initializes essential variables to defaults if not already set
	- Includes features/$feature/$feature.inc.php3
	- Authenticates user if necessary
	- Outputs HTML headers if necessary
	- Displays menu if necessary
	- Includes features/$feature/$feature.feature
	- Outputs HTML footers if necessary

    config/
	announcments.inc.php3
		- Site specific file displayed on the default page if it
		exists
	config.inc.php3
		- Basic configuration options
	dbconfig.inc.php3
		- Database configuration options
	footer.inc.php3
	header.inc.php3 
		- Site specific header and footer placed on every page
	images.inc.php3
		- Define IMG tags or text for images
	login.form.php3
		- Customizable template for form used in forms based login
		(to allow sites to easily create customized login screens)
	login.footer.inc.php3
		- footer for login.form
	login.header.inc.php3
		- header for login.form
	mainmenu.inc.php3
		- defines the options that appear in the main menu
	newusergroups.inc.php3
		- acl groups to add new users to

	(header.inc.php3, footer.inc.php3, announcements.inc.php3, and 
	 login.form.php3 can all include HTML and PHP tags)

    docs/
	- Contains all documentation except the README file.
	
    docs/AdminManual
	- Contains an html administrative manual

    features/
	- Contains $feature/ for each major feature in TWIG (mail,
	schedule, contacts, etc.)
	- Contains files needed by every page, such as twig.header.inc.php3,
	twig.footer.inc.php3, and goto.inc.php3

    features/$feature/
	- Contains *.inc.php3 for $feature

	features/$feature/*.feature.php3
		- Defines functions used by all parts of that feature
		- Parses $action
		- Includes appropriate features/$feature/????.inc.php3 file

	features/$feature/$feature.inc.php3
		- Defines commonly used constants and functions for that feature
		to be included by index.php3 before anything else loads

	features/$feature/strings/$config[language].strings.php3
		- Defines $TWIGphrase[] array common to files in $feature.
		- Loaded directly from index.php3 before the feature is
		  included

	features/$feature/help/$config[language]/$topic.$subtopic.help.php3
		- Helpful information goes here

    features/shared/
	- Contains code shared by multiple features (such as listing and
	editing routines)

    features/prefs/modules
	- contains the prefs files for each feature

    images/
	- Images directory, overridable in config.inc.php3

    lib/
	- Contains files to be included by much of TWIG
	
    lib/auth
	- Contains the authentication systems that TWIG supports

    lib/db/
	- Contains the database specific include files
	$dbconfig["sqltype"].inc.php3

    lib/db/sqltxt
	- Contains files for the sqldbase support code

    lib/groups
	- Contains the group providers

    lib/login
	- Contains files for the various login storage systems

    lib/mail
	- Contains files for the mail providers

    lib/prevnext
 	- Contains the prev/next style code

    lib/security
	- Contains files for the various security providers

    lib/session
	- Contains files for the various sessions/context storage
	  systems

    lib/strings/$config[language].strings.php3
	- Defines $TWIGphrase[] array for phrases used by all of TWIG
	- $TWIGphrase[] phrases used in only one feature go into
	  features/$feature/strings/$config[language].strings.php3

    setup/
	- Contains twig.table.<sqltype> files and any setup scripts

    setup/Strings
	- contains three scripts:
		1. generate.strings.php3
		2. populate.strings.pl
		3. strings.layout.php3

	  1 is used to convert the files in setup/Strings/SourceFiles
	  in to the individual feature string files, which are outputed
	  to setup/Strings/Output.  See docs/languages.txt for more 
	  details on how to use this script.

	  2 is used to move the files from setup/Strings/Output to the
	  appropriate directories.

	  3 supports 1, by defining what strings are required for each
	  of the features.

    setup/Strings/Output
	- Where the output from generate.strings.php3 is stored, this
	  directory must be writable by the user the web server is 
	  running as.

    setup/Strings/SourceFiles
	- The string definitions for each language

    setup/upgrade/
	- Contains scripts to upgrade from the last major version
	  of TWIG

    setup/upgrade/Pre-1.0
	- Contains scripts to upgrade between previous versions of TWIG

    setup/upgrade/x.y.0
	- Contains scripts to upgrade between previous version of TWIG

GLOBAL VARIABLES
================
    $context[] 	= any information specific to the current page
    			$context["feature"] = which major TWIG feature is 
    					      being used
    			$context["action"]  = what command is being passed 
    					      to $feature.feature

    $config[] 	= array of configuration variables
    			$config["debug"] = specific element of $config[] 
    					   array which controls the
    					   level of debugging information 
    					   that is shown.  Setting
    					   $config["debug"] to 10 will show 
    					   all debugging info but break any
    					   Header() or SetCookie() calls, 
    					   which are required for
    					   authentication.  A setting of 9 
    					   will bypass debug messages which
    					   keep authentication from happening.  
    					   The default debuglevel for
    					   the debug function is 10.

			$config["defaults"][$feature][$item]
					   These items define the defaults used
					   throughout TWIG.

    $vhosts[] 	= array of configuration variables for virtual hosts

    $dbconfig[] = array of database configuration variables

    $disabled[] = array of disabled features, this has been replaced by the use
		  of the security functions except in a few specific areas.

    $login[] 	= array storing current username and password of user after 
		  they have been authenticated

    $session[] 	= array to store state.  There is also a session() function for
    		  creating the session string to use both GET and POST type 
		  forms.

    		  Current mailbox, current group, current sorting order, and 
		  current page in the mailbox view are some of the items for 
		  which $session[] is often used.

    $included[] = array of included files.  This should be used to make
    		  sure files are not included twice.

    $pagetitle	= title of the current page, set in $feature.inc.php3
    
FUNCTIONS
=========
    Here are a few functions that will be present that might be useful.

    TWIGPrintError( $string )
	- Outputs a string in the standard error format.

    TWIGDebugLevel( $level = 10 )
	- Returns TRUE if user or system debug level is >= $level and
	  FALSE otherwise.

    TWIGDebug( $string, $level = 10 )
	- Outputs $string if user or system debug level >= $level.
	- The debug function should be called madly.

    TWIGCheckAdmin( $username )
	- Checks to see if $username is an administrator of the current
	  TWIG installation.
    
    TWIGLink( $text, $feature, $action, $params, $linkparams, $sother, $cother )
	- Creates a hyperlink $text to the given $feature and $action with
	$params parameters.  It also adds the session information to the
	link after checking that none of that information is specified by
	$params.

	$linkparams can be used to add additional parameters to the link,
	for example you can add " target=_blank" to have a new window
	opened for the page.

	$sother and $cother pass through to TWIGSession() and TWIGContext(), as
	the $other parameter.

    TWIGMailto( $address, $fullname = $address )
	- Checks to see if you have rights to send an email in TWIG. If so,
	  returns a TWIGLink( ) to Compose Mail. If not, returns a link
	  to "mailto:$address".
	- $fullname is always used as the link text, unless it is not set, in
	  which case $address is used instead.

    TWIGImage( $image="", $alt="", $tip="", $border="0", $height="", $width="", $align="", $valign="" ) 
	- Creates an <IMG> html tag.
	- Does some sanity checking to make sure that the HTML output is valid.
	- Generates tooltips that are compatible with older HTML 3 browsers as
	  well as newer browsers that follow HTML 4 fairly strictly.
	- $tip will default to $alt unless you specifically want an HTML 4
	  style tooltip that's too long for an ordinary 'alt' property.
	- Arguments with the same name as properties of the IMG tag go right into
	  the HTML stream as the values for those properties, respectively.

    TWIGSession( $type="get", $other )
	- Outputs current session array in form appropriate for GET or
	POST style forms.
	- $other is a 2 dimensional array where:
		$other[0]["item"] is an entry in $session.
		$other[0]["value"] is the value for the above.
	  This allows for custom session types.

    TWIGContext( $type="get", $feature, $action, $other )
	- Outputs current context array in form appropriate for GET or
	POST style forms.
	- if $feature/$action are specified, outputs those instead of
	current context array.
	- $other is a 2 dimensional array where:
		$other[0]["item"] is an entry in $context.
		$other[0]["value"] is the value for the above.
	  This allows for custom context types.

    TWIGPrevNext( $currentlow, $total, $pagesize, $context, $linkoption, $displaytype="arrows" )
	- Displays previous/next buttons, arrows, menus, etc.

    GetPref( $prefname, $preftable, $default ) 
    PutPref( $prefname, $value, $preftable )
    	- Retrieves or stores a preference in a database
	- $prefname is the name of the preference
	- $preftable is the db table to retrieve from (should be one of 
	  $dbconfig[tablename])

    TWIGGenerateMenu( $contents, $menutype, $imagepage = "primary" )
	- takes a 2 dim. array ($contents) and generates a command bar
	  in a style
		- the first dim. of $contents is a number from 0 > x
		- the second dim contains the following items:
			"command"
			"desc"
			"action"
			"options"
			"target"
			"image"
	- $menutype allows for the menu to be generated in a given style:
		0 - traditional TWIG text
		1 - Drop Down List
		2 - Button Bar
		3 - traditional TWIG secondary bar
		4 - vertical bulleted list
		5 - tab list

	- $imagepath defines what set of images to load

    TWIGGenerateTable( $headers, $contents, $columns, $width = "100%", $align = "" )
	- takes an array $headers to display in the first line, this
	  can also be a 2 dim. array as follows:
		$header[]["header"] =  cell contents
		$header[]["bgcolor"] = background color of cell
		$header[]["colspan"] = number of columns to span
		$header[]["align"] = cell alignment
		$header[]["valign"] = vertical cell alignment
		$header[]["nowrap"] = don't wrap the cell
	- takes a 2 dim. array ($contents) and generates a table as follows:
		$contents[row][column] = cell contents
	  or this may be a 3 dim. array as follows:
		$contents[][]["contents"] = cell contents
		$contents[][]["bgcolor"] = background color of cell
		$contents[][]["colspan"] = number of columns to span
		$contents[][]["align"] = cell alignment
		$contents[][]["valign"] = vertical cell alignment
		$contents[][]["nowrap"] = don't wrap the cell
	- $columns is the total number of columns found in the table, this
	  is sometimes necessary if colspan is used in headers, if not it
	  can be left blank.
	- $width is the width of the table. The value may be a percentage or a
	  number of pixels, though pixels are *highly* discouraged.
	- $align is the alignment of the table. The value may be "left",
	  "right", or "center". It is recommended to be used only for
	  centering, however.

    TWIGGenerateTabs( $contents )
	- takes an array $contents and returns an html segment that
	  displays $contents in a "tab" format.

    TWIGGenerateLeftRightOptions( &$left, &$right, $name, $lefthead, $righthead, $size = 5 )
    	- $name is the prefix to use for the following variables:
	    $name_left
	    $name_right
	    $name_orig_left
	    $name_orig_right
	- $lefthead is the title text for the left box
	- $righthead is the title text for the right box
	- $size is the vertical size of the boxes

    TWIGProcessLeftRightOptions( $name )
        - This function processes the form data from a LeftRightOptions
	  to update the variables based on how the user has rearranged
	  the form's contents
    	- $name is the prefix for the following variables:
	    $name_left
	    $name_right
	    $name_orig_left
	    $name_orig_right
	- the variables $name_left/right should not be operated upon, but
	  should simply be passed back into the GenerateLeftRightOptions for
	  the next page show
	- the variables $name_orig_left/right may be munged as desired. they
	  contain the current items on the left and on the right as updated by
	  this function

    TWIGLoadLanguageFile( $filepath, $filename, $lang )
	- loads a language file, if the desired language is not found
	  then an english version is loaded.
	- $filepath needs to have a trailing / on it

    TWIGdate( $format, $timestamp )
	- a replacement for PHP's date() function that translates day
	  and month names into the current language

    TWIGFindHTML( $string )
	- scans through string and finds any http:/ftp:/mailto: links (or
	  text that looks like one) and adds in the appropriate <a>'s.

    TWIGProcessGPCString( $string )
	- takes a $string that has been passed in to TWIG through a 
	  GET, POST or COOKIE and strips the added slashes if required

    TWIGProcessGPCtoSQL( $string )
	- takes a $string that has been passed in to TWIG through a 
	  GET, POST or COOKIE and converts it for use in a SQL statement

    TWIGBytesToText( $size = 0 )
	- Takes a $size and returns a string representing the number in 
	  bytes, k, mb, etc.

    TWIGExecuteServerCommands( $opencon, $CmdArray )

	Once a connection has been opened to a server on the desired port, this
	function will take a series of commands and execute them.

	$opencon is the connection handle to use.

	$CmdArray is a multi-dimensional array of the following format:
	
		$CmdArray[$i][0] = Command to write, empty command are not 
				   written but a response can be expected.
		$CmdArray[$i][1] = The response to expect back, empty 
				   responses are acceptable.  Partial
				   responses are matched against the first
				   part of the response and then returned.

	On success the function will TRUE, otherwise it will return the last 
	response from the server.

Security Functions
==================

    TWIG Version 2.0 introduced the concept of security providers.  These
    providers allowed more granularity in the access a user had to various
    parts of TWIG.

    At this time there are two security providers available for TWIG:

	- basic
	- advanced

    Basic emulates the functionality of TWIG 1 by using $disabled to define
    on a global scale what features are available.  Basic is the default
    security provider.

    Advanced introduces the concept of Access Control Lists (ACL's) to TWIG
    which allows for an admin to define either individuals or groups various
    access levels to the items in TWIG.  Unlike basic, advanced uses db tables
    to hold this information and additional steps are required to configure 
    it.

    One additional note should be made, there is a fundamental difference
    between the two providers; basic assumes everything is accessible unless 
    specifically disabled, advanced assumes nothing is accessible unless
    specifically enabled.

    TWIG's security system uses several security 'levels', they include; none,
    read, write, delete, sidadmin, owner, admin.  These levels are 'human' 
    readable however all of the security functions require the internal 
    representation of these items.  It is therefore required to call
    TWIGConvertAccess() on these.

    For example, to check to see if a user has read access on a sid, use the
    following function call:

	TWIGCheckACL( $login["username"], 2001, TWIGConvertAccess( "read" ) );

    As you have just seen the security systems share a common set of functions 
    that are used through out TWIG, these functions allow for TWIG to support
    multiple security providers without rewriting the code for each one.

    TWIGGenerateSID( $owner )
		
	Creates a unique SID for use in assigning security to an item and 
	assigns $owner as the owner of the SID.  If $owner is not defined
	then $login["username"] is used as the owner.

    TWIGCheckACL( $login["username"]/$group, $sid, $access )

	Check to see if $login['username"] or $group has $access to the 
	given $sid object.

    TWIGGetACL( $login["username"]/$group, $sid )

	Retrieve the access level for $login["username"]/$group for the given 
	$sid object.

    TWIGModifyACL( $login["username"]/$group, $sid )

	Build an HTML section for modifying  $sid as $login["username"]/$group.

    TWIGDisplayACL( $login["username"]/$group, $sid )

	Build an HTML section for displaying $sid as $login["username"]/$group.

    TWIGIsMemberOfACLGroup( $name, $groupname )

	Checks to see if $name is a member of $groupname.

    TWIGConvertAccess( $access )

	Converts an access type (name or number) in to the opposite.

    TWIGCreateACLGroup( $name, $groupname )

	Creates an ACL group ($groupname) with $name as the owner.

    TWIGDeleteACLGroup( $name, $groupname )

	Deletes an ACL group ($groupname), it checks to see if $name has 
	permissions before it is deleted.

	This function will delete the group and associated acl list entries.

    TWIGGetSID( $name )

	Retrieve a SID for the user/group $name.

    TWIGAddACLEntry( $user, $addname, $sid, $access )

	Add $addname to the $sid object with $access it checks to see if 
	$name has permissions to change	the acl before it is added.

    TWIGGetACLUsers()

	Get a list of current valid users in the system	and returns them as an
	array.

    TWIGGetACLGroups()

	Get a list of current valid groups in the system and returns them as 
	an array.

    TWIGGetACLGroupMembers( $group )

	Get a list of current members of a group and returns them as an array.
		
    TWIGAddACLGroupMember( $username, $usernametoadd, $groupname )

	Adds $usernametoadd to group $groupname as user $username.

    TWIGRemoveACLGroupMember( $username, $usernametoremove, $groupname )

	Removes $usernametoremove from group $groupname as user	$username.

    TWIGProcessACLModify()
	
	Processes information submitted by the form generated by TWIGModifyACL().  
	This should be called at the beginning of a page that uses TWIGModifyACL().

Group Functions
===============

    TWIG 2.0.3 removed the direct access to the groups functions from the code
    base and abstracted them to allow for new types of group functionality to be
    created.  To this end the groups abstraction layer consists of the following
    functions:

    TWIGGroupsCreateSQLGroupQuery( $username, $grouplist, $table="", $perms=0 )

	This function returns a sql query string (at least the WHERE portion 
	of it) that will select $username's items that are in the groups
	listed in $grouplist to which the user has at least $perms access
	(if the groups system supports access levels).  The optional $table
	parameter causes the query to be formatted as '$table.groupid' and
	'$table.username' rather than simply 'groupid' and 'username'.

    TWIGGroupsGetName( $gid ) 
	
	Given $gid this function will return the name of the group.

    TWIGGroupsMemberOf( $gid, $perms=0 ) 
	
	Given $gid this function will return true/false if $login["username"] is
	a member of $gid with at least $perms access (where permissions
	are supported).
	
    TWIGGroupsMembers( $gid, $perms=0 ) 
	
	Returns an array of all members of group $gid with $perms level
	access (where permissions are supported).

    TWIGGroupsMembership( $user, $perms=0 ) 
	
	Returns an array of all of which groups $user is a member with at
	least $perms access (where permissions are supported).
	
    TWIGGroupsSelect( $username = "", $gid = "" , $is_listoption = "", $perms=0) 
		
	Returns a string which contains a series of <option> tags that represent
	all groups $username belongs to.  $gid will select that group as the 
	currently selected group in the list.  

	If $is_listopiton is empty then the ALL group will be included in the
	list.

	If $perms are defined then only those groups to which the user has
	$perms access will be included.

    TWIGGroupsSelector( $Username = "", $GID = "", $IsListOption = "", $OptionName = "data_thisGroup", $GoName = "TWIGChangeGroup", $perms=0 )
	
	Returns a string that has a complete <form> section in it representing
	the current list of groups the user has access to.

	See TWIGGroupSelect() for the first three options.

	$OptionName can be passed in to define a nonstandard name for the 
	select tag.

	$GoName can be passed in to define a nonstandard name for the go
	input tag.

	$perms can be passed to restrict the list of groups to those to which
	the user has at least $perms access.

    $groupquery = "username='" . $login["username"] . "'";
	
	While not actually a function, this needs to be defined so that various
	select statements will function correctly.  Use of this variable
	has been depreciated, and it will likely be removed in future
	versions.

Database Functions
==================

    TWIG uses it's own database abstraction layer which allows it to be quickly
    ported to new db servers.  This layer provides basic functionality for 
    querying a SQL server and then manipulating the results.

    TWIGProcessSQLString( $string )

	This function takes a string returned from a SQL query and strips
	slashes (or anything else) as required.

    SQLString( $string ) 

	This function take a string and prepares it for use in a SQL query.

    createSqlDate( $year, $month, $day ) 

	This function returns a string used to store dates in the db.

    createSqlDateTime( $year, $month, $day, $hour, $min, $sec ) 

	This function returns a string used to store dates in the db.
 
    convertSQLTimetoUTime( $sqldate ) 

	This function converts the db's time/date structure in to a Unix time
	stamp.

    MakeInsertString( $data ) 

	This function takes an array $data and creates a partial insert query.

    MakeUpdateString( $data )

	This function takes an array $data and creates a partial update query.

    dbQuery( $statement ) 

	This function executes $statement on the sql server and returns the 
  	results.

    dbResult( $result, $i, $field ) 

	This function takes a $result returned by dbQuery and returns the value
	of $field on row $i.  

	NOTE: This function should not be used if you want to retrieve values
	      for more than on field on a row.  Instead use dbResultArray().

    dbNumRows( $result ) 
	
	This function returns the number of rows in $result.

    dbResultArray( $result, $i ) 

	This function returns an array of all fields in row $i of $result.

Authentication Functions
========================

    TWIG uses two 'levels' of auth providers:

	- front end
	- back end

    The front end provider is what the user sees, either a form or a standard
    http auth message.

    The back end providers actually do the work at authenticating what the 
    front end gets from the user.

    Front End Providers
    -------------------

	include( "lib/auth/" . $config["auth_provider"] . ".authpro.inc.php3" );

		The first thing that the front end providers need to do is to 
		include the back end providers, otherwise they will not be
		able to properly authenticate the user.

	TWIGLogout( $realm )

		This function will logout the user from the system, clearing 
		any stored information.

		This function should call exit and never return.

	TWIGAuth( $realm = "TWIG", $logout = "" ) 
		
		This function will pass the user/pass to the backend system
		and then store the credentials as required.

		This function should return FALSE when successful, otherwise
		it should call exit and end the script.

    Back End Providers
    ------------------

	TWIGCheckAuth( $mbox, $logout = "" )

		This function will check to see if $login["username"] has
		access to the system, passing in $logout will undo any
		access that was setup while logging in.

		$mbox is mostly passed in for historical reasons, it should
		not be used in any new auth providers.

		This function should return an array with two elements, the 
		first should be true/false based upon if the user has been
		auth'd or not.  The second should always be false (again for
		historical reasons).

Login Provider Functions
========================

    TWIG's login providers allow the admin to select where persistent
    login information is stored.  The login providers use the following
    functions:

    TWIGGetLogin() 

	This function will retrieve the login information from storage.

	This function should not return an array containing the username 
	and password elements.

    TWIGStoreLogin( $username, $password, $expire, $delete = 0 )

	This function will store the login information in to storage.

	$expire is the number of seconds after storage until the login 
	information should be considered invalid and deleted.

	If $delete is set then the login information should be deleted from
	storage and the user not allowed to login.

	This function should not return any value.

Session Provider Functions
==========================

    Like Login Providers, TWIG supports session providers to all the admin
    of the server to decide how they would like to store the session/context
    array's between page loads.  To accomplish this the following functions
    are defined:

    TWIGGetContext() 

	This function retrieves $context from storage.

	This function should return an array that contains all the elements
	from $context.

    TWIGGetSession() 

	This function retrieves $session from storage.

	This function should return an array that contains all the elements
	from $session.

    TWIGSession( $type = "get", $other = "" ) 

	This function modifies a copy of $session based upon entries in 
	$other and then	stores it.

	$type is defined as either "get" or "put" depending on the type of
	output required.

	$other is a multi-dimensional array as follows:

		$other[$i]["item"]	= session value to replace
		$other[$i]["value"]	= value to replace it with

    TWIGContext( $type = "get", $feature = "", $action = "", $other = "" )

	This function modifies a copy of $context based upon entries in 
	$other, $feature and $action and then stores it.

	$type is defined as either "get" or "put" depending on the type of
	output required.

	$feature is the feature that should be stored in $context.
	
	$action is the action that should be stored in $context.

	$other is a multi-dimensional array as follows:

		$other[$i]["item"]	= context value to replace/add
		$other[$i]["value"]	= value to replace/add


    TWIGCleanSession()

	This function cleans up any left over $session data that may be left
	in storage once the page has been completed.

    TWIGCleanContext()

	This function cleans up any left over $context data that may be left
	in storage once the page has been completed.
		
New List Functions
==================

    TWIG 2.1.0 introduced a major change in how the 'list' code functionality 
    worked.  Many of the various features of TWIG uses the list code (contacts,
    bookmarks, etc.) and the changes were designed to make the code more
    flexible.

    At this time all new features created should use the new list functions
    instead of the old list includes which will be phased out over the next
    several versions of TWIG.  Once all existing features have been migrated
    over the old list code will be removed.

    The new list functions are as follows:

    TWIGListHeader( $menu )

	This function builds the standard header found in all list based 
	functions, $menu is passed in to TWIGGenerateMenu() so that custom
	menu items can be created.

    TWIGListGenerateTable( $tableheaders, $tablecontents, $start = 1, $titems, $pagesize )

	This function is similar to TWIGGenerateTable() (see it's docs for the 
	description of the first two parameters).  

	$start defines what item to start the display with.

	$titems defines the total number of items in the list.

	$pagesize defines how many items to display on this page.

    TWIGListGetItem( $ItemID, $db="", $fields = "*", $GroupQuery="" )

	This function retrieves the columns $fields from table $db where the
	item's ID is $ItemID.

	$ItemID is the item to retrieve.

	$db is the table.  If none is passed $db defaults to
	$dbconfig["<feature>_table"].

	$fields is a comma separated string defining the columns to grap for
	the item.  This defaults to "*" or all columns.

	$GroupQuery is a SQL statement fragment defining a set of groups from
	which to pull the item.  This is generally not needed since the item's
	ID should be unique, but it has been preserved as an optional
	parameter to ensure compatibility with previous implementations.

    TWIGListItemHeader( $data, $viewtype="view", $menu="" )

	This function displays the standard header for viewing or editting an
	item.

	$data is an array of the gathered information for the item.

	$viewtype may be either "view" or "edit".  It defines whether the item
	is being viewed or editted.  If omitted, this defaults to "view".

	$menu is an array to be passed to TWIGGenerateMenu().  If omitted,
	the function will generate its own generic menu.

    TWIGListItemFooter( $data, $viewtype="view", $buttons="")

	This function displays the standard footer for viewing or editting an
	item.

	$data is an array of the gathered information for the item.

	$viewtype may be either "view" or "edit".  It defines whether the item
	is being viewed or editted.  If omitted, this defaults to "view".

	$buttons is a string defining the buttons to be placed at the bottom
	of the form when $viewtype="edit".  If omitted a default set of
	buttons is inserted (usually "Update" and "Delete" depending on
	permissions).

    TWIGListItemEditFormHeader( $edittype = "new", $menu, $ListDB, $ItemID, $GroupQuery )

	This legacy function displays the standard header when editing an item.
	However, it has now simply a wrapper for the TWIGListGetItem() and
	TWIGListItemHeader() functions.  It has been preserved for compatibility
	with previous applications, but will likely be removed in the future.

	$edittype is included for consistency with the footer call but is 
	not actually used.

	$menu is an array that is passed to TWIGGenerateMenu().

	$ListDB is the table name to use in queries.

	$ItemID is the item to edit.

	$GroupQuery is the current $groupquery string.

    TWIGListItemEditFormFooter( $edittype = "new", $menu, $ListDB, $ItemID, $GroupQuery )

	This legacy function displays the standard footer when editing an item.
	However, it has now simply a wrapper for the TWIGListGetItem() and
	TWIGListItemFooter() functions.  It has been preserved for compatibility
	with previous applications, but will likely be removed in the future.

	$edittype is used to determine if an add button or update/delete buttons
	are displayed.

	$menu is included for consistency with the header call but is 
	not actually used.

	$ListDB is the table name to use in queries.

	$ItemID is the item to edit.

	$GroupQuery is the current $groupquery string.
	

    TWIGListItemEditProcess( $action, $ListDB, $GroupQuery, $data, $destination = "" )

	This function processes any changes that are required after the
	edit form has been submitted, it should be included at the top 
	of the page that will process the edit form.

	$action can be any of the following:
		
		$TWIGphrase["Update"]
		$TWIGphrase["Delete"]
		$TWIGphrase["Add"]
		$TWIGphrase["Delete Selected"]
		$TWIGphrase["Move"]
		$TWIGphrase["Copy"]

	$ListDB is the table name to use in queries.

	$GroupQuery is the current $groupquery string.

	$data is an array, either submitted by the edit form or retrieved
	from a dbQuery() call.

	$destination is the group to move the items to if performing a move.

Mail Functions
==============

    The mail relay function are a little more low level to the system, but some
    programmers may find them useful.

    TWIG's mail functions changed between 2.2.3 and 2.3, 
    TWIGExecuteServerCommands() has been moved to the common.inc.php3, and
    TWIGMailRelay() has been replaced with a mail sending system provider 
    structure that loads an include that defines TWIGMailSendMessage()

    Additionally, all of the php defined mail functions (the imap_?() functions)
    have been wrapped with php functions to allow for the mail system to be 
    abstracted.

    Currently there are two providers available, the traditional imap provider
    and a pop3 provider.

    TWIGMailSendMessage( $server = "localhost", $port = "25", $to, $from, $domain, $header, $body ) 

	This function sends a message through the mail system.

	$server - defines what mail server to use during sending.
	$port   - defines the port to connect to.
	$to 	- is a list of users to send the message to.
	$from 	- is the e-mail address of the sender.
	$domain - is the default domain to append to $to addresses that are 
                  missing one.
	$header - the message headers.
	$body   - the message body.
	
	Currently only two providers are supported, the built in php mail() 
	function and the mail relay style code from previous version of TWIG.

    TWIGOpenMB( $mailbox, $oldmbox = FALSE) 

	This function opens a connection the the mail server, this function
	returns a handle to be used in the other mail functions.

	$mailbox - the mailbox to open.
	$oldmbox - a pointer to an open mailbox if one exists.

    TWIGCloseMB( $mbox )

	This function closes an open connection as opened by TWIGOpenMB().

    TWIGCheckNewMail( $mbox )

	This function checks to see if there is any new mail in the opened
	mailbox.

    TWIGGetMessageCount( $mbox )

	This function returns the number of messages in an open mailbox.

    MailboxEncode( $mb )

	This function encodes a text representation of a mailbox so that it
	is safe to pass it through a url.

    MailboxDecode( $mb, $strip = "" )

	This function decodes a string encoded by MailboxEncode().

    CheckMBType( $str )

	This function returns the type of mailbox represented by a string.

    TWIGMailFetchStructure()

	See imap_fetchstructure() in the php manual for details.

    TWIGMailFetchBody( $mailbox, $message, $section )

	See imap_fetchbody() in the php manual for details.
	
    TWIGMailBoxCheck( $mailbox )

	See imap_check() in the php manual for details.

    TWIGMailCopy( $mailbox, $message, $destination )

	See imap_mail_copy() in the php manual for details.

    TWIGMailMove( $mailbox, $message, $destination )

	See imap_mail_move() in the php manual for details.
		
    TWIGMailDelete( $mailbox, $item )

	See imap_delete() in the php manual for details.

    TWIGMailSubscribedFolders( $mailbox, $path, $filter )

	See imap_listsubscribed() in the php manual for details.

    TWIGMailEmptyTrash( $mailbox )

	See imap_expunge() in the php manual for details.

    TWIGMailGetSortedList( $mailbox, $sortedby, $sorteddirection )

	See imap_sort() in the php manual for details.

    TWIGMailCreateFolder( $mailbox, $folder )

   	See imap_createmailbox() in the php manual for details.

    TWIGMailSubscribeFolder( $mailbox, $folder )

	  See imap_subscribe() in the php manual for details.
	
    TWIGMailUnSubscribeFolder( $mailbox, $folder )

    	See imap_unsubscribe() in the php manual for details.

    TWIGMailDeleteFolder( $mailbox, $folder )

    	See imap_deletemailbox() in the php manual for details.

    TWIGMailRenameFolder( $mailbox, $folder, $newname )

	See imap_renamemailbox() in the php manual for details.

    TWIGMailFolderList( $mailbox, $startingfolder, $filter )

	See imap_listmailbox() in the php manual for details.

    TWIGMailFolderInfo( $mailbox )

	See imap_mailboxmsginfo() in the php manual for details.

    TWIGMailHeader( $mailbox, $message, $fromlength, $subjectlength, $defaultdomain )

	See imap_header() in the php manual for details.

    TWIGMailSetMessageFlag( $mailbox, $message, $flag )

	See imap_setflag_full() in the php manual for details.

    TWIGMailUnSetMessageFlag( $mailbox, $message, $flag )

	See imap_clearflag_full() in the php manual for details.

    TWIGMailAppendMessage( $mailbox, $folder, $message, $flags )

	See imap_append() in the php manual for details.

    TWIGMailUndelete( $mailbox, $message )

	See imap_undelete() in the php manual for details.

    TWIGMailFetchHeader( $mailbox, $message )

	See imap_fetchheader() in the php manual for details.

    TWIGMailParseAddresssList( $list, $defaultdomain )

	See imap_rfc822_parse_adrlist() in the php manual for details.

    TWIGMailDecodeBase64( $text )

	See imap_base64() in the php manual for details.

    TWIGMailGetFolderString( $server, $port, $type, $folder, $user = "", $pass = "" )

	Creates a folder string that represents a folder to be opened.

	$server - the server to connect to
	$port	- the port to connect to on the $server
	$type	- the folder type
	$folder - the folder name
	$user	- the user to open the folder as
	$pass	- the password to open the folder with

    TWIGMailParseFolderString( $FolderString )

	Parses a folder string created by TWIGMailGetFolderString() and returns
	an array of:

	array( $server, $port, $type, $folder, $user, $pass )

    TWIGMailGetDisplayName( $Folder )
	
	Parses a folder string and returns a text string to display to the user
	for use in lists etc.
