" . OtherTools(our_db, $strPHP); } $out.="
" . time() . " " . $intDate . " " . $out . "
";
return $out;
}
function mustDisplayField($strTable, $strFieldConfig, $strFieldName)
{
//returns yes if $strFieldName is in $strFieldConfig for table, returns no if $strFieldName is not in the found info for table
//returns nothing if there is no info on this table
$arrFieldsToRequire=genericdata($strTable,0, 1, $strFieldConfig, "*", "|", true);
$strFieldRequired="nothing";
if (is_array($arrFieldsToRequire))
{
if (array_search($strFieldName, $arrFieldsToRequire)>0)
{
$strFieldRequired="yes";
}
else
{
$strFieldRequired="no";
}
}
return $strFieldRequired;
}
function GreaterFieldDisplayLogic($strTable, $strFieldConfig, $strFieldName, $intFieldCount, $intFieldLimitLo, $intFieldLimitHi, $display_field_list="")
{
$strFieldRequired=mustDisplayField($strTable, $strFieldConfig, $strFieldName);
$out=false;
//echo $intFieldLimitLo . "
";
if($display_field_list!="")
{
$display_field_list=trim(deMultiple($display_field_list, " "));
if(inList($display_field_list, $strFieldName))
{
$out=true;
}
}
else
{
if ((($strFieldRequired=="yes" || $intFieldCount<=$intFieldLimitLo) && $intFieldCount<=$intFieldLimitHi) || ($strFieldRequired=="nothing" && $intFieldCount<=$intFieldLimitHi))
{
if(!contains(strtolower($strFieldName), "password")) //no sense in showing a blanked-out password in a list of records
{
$out=true;
}
}
}
return $out;
}
function qbuild($strPHP, $strDatabase, $strTable, $mode, $idfieldname, $id)
//Builds a url from the given info, specific to tableform-style implementation
{
$out=$strPHP ."?" . qpre . "db=" . $strDatabase ;
if ($strTable!="")
{
$out.="&" . qpre . "table=". $strTable;
}
if ($mode!="")
{
$out.="&" . qpre . "mode=" . $mode;
}
if ($idfieldname!="")
{
$out.="&" . qpre . "idfield=" . $idfieldname;
if ($id!="" && !contains($idfieldname, "+") && !contains($idfieldname, " ") && !contains($idfieldname, "%20"))
{
$out.="&" . $idfieldname . "=" . $id;
}
}
return $out;
}
function adminbreadcrumb($disablelink)
//Breadcrumb nav for the admin tools
{
$intArgs =func_num_args();
$out="";
$strDelimiter=" : ";
for($i=1; $i<$intArgs; $i=$i+2)
{
$out.="";
$label=func_get_arg($i);
$link="";
if($i+1<$intArgs)
{
$link=func_get_arg($i+1);
}
//echo $label . " " . $link. "
";
if ($link=="" || $disablelink)
{
$out.= $label;
}
else
{
$out.="" . $label . "";
}
$out.="";
if ($i<$intArgs-2)
{
$out.=$strDelimiter;
}
//echo $out . "
";
}
return $out;
}
function SimpleTableDescriptionHeader($strDatabase, $strTable, &$fieldsincluded, $strClass="bgclassline", $intRowsToInclude=5, $fieldsToExclude="", $typesToExclude="", $arrExtraColumns="", $strTableID="idsorttable")
//Judas Gutenberg 2-21-2008
//creates a header for a non-paginated dump of a table's full contents
//$fieldsincluded is returned as a space-delimited list by reference so you know what to show in the table to which this is a header
{
$records = DBExplain($strDatabase, $strTable);
$intFindCount=1;
$goodFieldList="";
$intCount=1;
$arrOut[0]=$strClass;
foreach ($records as $k => $info )
{
if(!inList($fieldsToExclude, $info["Field"]) && $intCount< 1+$intRowsToInclude && !inList($typesToExclude, $info["Type"]))
{
$arrOut[$intCount]="" . $info["Field"] . "";
$fieldsincluded.=" " . $info["Field"];
$intCount++;
}
}
if(is_array($arrExtraColumns))
{
foreach($arrExtraColumns as $extra)
{
$arrOut[$intCount]=$extra;
$intCount++;
}
}
for($i=0; $i< $intEmptyCols; $i++)
{
$arrOut[$intCount]=" ";
$intCount++;
}
$fieldsincluded= RemoveEndCharactersIfMatch($fieldsincluded, " ");
$out=call_user_func_array("htmlrow", $arrOut);
return $out;
}
function TableList($strDatabase, $likeclause="")
{
$sql=conDB();
$strSQL="SHOW TABLES FROM " . $strDatabase . " " . $likeclause;
$records = $sql->query($strSQL);
return $records;
}
function sql_error()
{
//a wrapper function in case some day we're not using mysql
return mysql_error();
}
function CommmaDelimitedDump($strDatabase, $strTable, $strFields="", $strFieldDelimiter=",", $strRowDelimiter="\n", $quotecontent=true, $UserID="", $strSQL="")
//An export feature from table to file
//If $strFields is not empty, then the fields are filtered based on their mention in $strFields
{
$sql=conDB();
$strAdminIDRangeAddendum=UserIDToSelectAddendum($strDatabase, $strTable, $strIDFieldName, $UserID);
if ($strSQL=="")
{
$strSQL="SELECT * FROM " . $strDatabase . "." . $strTable;
$strSQL=ProperlyAppendSQLWherePhrase($strSQL, $strAdminIDRangeAddendum);
}
$out="";
$records = $sql->query($strSQL);
foreach ($records as $key=>$value )
{
$intFieldCount=0;
$row="";
foreach ($value as $key1 => $value1 )
{
$strpreparedcontent=doublequoteescape($value1);
if ($quotecontent)
{
$strpreparedcontent='"' . $strpreparedcontent . '"';
}
if ($strFields!="")
{
if (inList($strFields, $key1))
{
$row.= $strpreparedcontent . $strFieldDelimiter;
}
}
else
{
$row.= $strpreparedcontent . $strFieldDelimiter;
}
}
$out.= RemoveEndCharactersIfMatch($row, $strFieldDelimiter);
$out.= $strRowDelimiter;
}
return $out;
}
////////////////////////////////////////
//UTILITIES////////////////////////////
//////////////////////////////////////
function LinkIfFile($strFile, $strQueryString, $strAnchorText, $strUnlinkedPre="", $strUnlinkedPost="", $bwlActuallyLink=true, $bwlUnlinkParam="", $strExtraPairs="")
//Creates a link if the linked-to file exists
{
$out="";
$strURL=$strFile;
if (file_exists($strFile))
{
if ($strQueryString!="")
{
$strURL.="?" . $strQueryString;
}
if($bwlActuallyLink)
{
$out="" . $strAnchorText . "";
}
else
{
$out= "" . $strAnchorText . "";
}
}
if ($out!="")
{
$out=$strUnlinkedPre . $out . $strUnlinkedPost;
}
return $out;
}
function simplelinenav($strconfig)
//provides unified site navigation based on double-delimited strConfig having the form filename1|label1-filename2|label2...
{
$strPHP=$_SERVER['PHP_SELF'] . IfAThenB($_SERVER['QUERY_STRING'], "?") . $_SERVER['QUERY_STRING'];
$arrconfig=split("-",$strconfig);
$count=count($arrconfig);
$out="";
for ($i=0; $i<$count; $i++)
{
$arrthis=split("\|", $arrconfig[$i]);
$strthisfile="/" . $arrthis[0];
//echo $strthisfile . " " . $strPHP . "
";
if ($strthisfile!= $strPHP)
{
$out.= "" . $arrthis[1] . "" . chr(13);
}
else
{
$out.= $arrthis[1] . chr(13);
}
if ($i<$count-1)
{
$out.=" | ";
}
}
return($out);
}
function endswith($strIn, $what)
//Does $strIn end with $what?
{
if (substr($strIn, strlen($strIn)- strlen($what) , strlen($what))==$what)
{
return true;
}
return false;
}
function beginswith($strIn, $what)
//Does $strIn begin with $what?
{
if (substr($strIn,0, strlen($what))==$what)
{
return true;
}
return false;
}
function contains($strIn, $what)
//Does $strIn contain $what?
{
if ($strIn!="" && $what !="")
{
if (strpos($strIn, $what)===false)
{
return false;
}
}
else
{
return false;
}
return true;
}
function gracefuldecay()
//Go through the parameters and return the first that isn't empty. Incredibly useful!
{
$intArgs =func_num_args();
for($i=0; $i<$intArgs; $i++)
{
$option=func_get_arg($i);
if ($option!="")
{
return $option;
}
}
}
function CalculateProbableTextAreaDimensions($v, &$width, &$height, $widthguide=10, $probablescreentextwidth=80)
{
$len=strlen($v);
$arrRows=explode("\n", $v);
$thisrows=count($arrRows);
$lcasev=strtolower($v);
if($widthguide>$probablescreentextwidth)
{
$widthguide=$probablescreentextwidth;
}
if(contains($lcasev, "
1)
{
$out="";
}
else
{
if ($size!="")
{
$strSize=" size='" . $size . "'";
}
$out="\n";
}
return $out;
}
function HiddenInputs($arrIn, $pre=qpre, $strListToAvoid="", $additionalprefix="")
//Takes an associative array and makes it into a series of hidden input tags
{
$out="";
foreach($arrIn as $k=>$v)
{
if (!inList($strListToAvoid, $k))
{
$quote='"';
if(contains($v, "\""))
{
$quote="'";
}
$out.="\n";
}
}
return $out;
}
function addBwls()
//Adds all the bwls and returns the number that were true
{
$count = func_num_args();
$out=0;
for ($i=0; $i<$count; $i++)
{
$thisarg[$i]=func_get_arg($i);
if ($thisarg[$i])
{
$out++;
}
}
return $out;
}
function IntToSQLBoul($int)
//Turn a number into the words "true" or "false".
{
if (intval($int)==1)
{
$out="true";
}
else
{
$out="false";
}
return $out;
}
function ProperlyAppendSQLWherePhrase($strSQL, $strPhrase)
//Smart enough to know whether the phrase needs a WHERE
{
$strProspect=BlankOutQuotedAreas($strSQL, "*", "'");
if (contains(strtolower($strProspect), " where "))
{
$strSQL.= IfAThenB($strPhrase, " AND ") . $strPhrase;
}
else
{
$strSQL.= IfAThenB($strPhrase, " WHERE ") . $strPhrase;
}
return $strSQL;
}
function ReverseDirectionSQL($strDirection)
//This function allows me to reverse the sort order by clicking on the heading a second time.
{
$strDirection=Alternate("ASC", "DESC", $strDirection);
return $strDirection;
}
function Alternate($strOptionOne, $strOptionTwo, $strOptionNow)
//Swap between two strings. Great for both front end and back end.
{
if ($strOptionOne== $strOptionNow)
{
return $strOptionTwo;
}
return $strOptionOne;
}
function deMultiple($strIn, $chrIn)
//Remove multiple side-by-side instances of $chrIn - works best for things like spaces and chr(13).
{
$strOut=$strIn;
while(strpos($strOut, $chrIn . $chrIn))
{
$strOut = str_replace( $chrIn . $chrIn, $chrIn, $strOut);
}
return($strOut);
}
function RemoveLastCharacterIfMatch($strIn, $chrIn)
//Trim off the last character of $strIn if they happen to be $chrIn.
//Only works with one-character $chrIn.
{
$out=$strIn;
if (substr($strIn, strlen($strIn)-1, 1) ==$chrIn)
{
$out= substr($strIn, 0, strlen($strIn)-1);
}
return $out;
}
function RemoveFirstCharacterIfMatch($strIn, $chrIn)
//Trim off the first character of $strIn if they happen to be $chrIn.
//Only works with one-character $chrIn.
{
$out=$strIn;
//echo substr($strIn, 0, 1) . "
";
if (substr($strIn, 0, 1) ==$chrIn)
{
$out= substr($strIn, 1);
}
return $out;
}
function RemoveEndCharactersIfMatch($strIn, $chrIn)
//Trim off the end characters of $strIn if they happen to be $chrIn.
//Only works with one-character $chrIn.
{
$out= RemoveFirstCharacterIfMatch($strIn, $chrIn);
$out= RemoveLastCharacterIfMatch($out, $chrIn);
return $out;
}
function GenericForm($arrFieldNames, $arrLabels, $arrDefaults, $arrSizes, $arrHiddenMask, $strPHP)
//Simplest-possible conversion of field names, labels, and defaults into an actual form.
{
$strLineClass="bgclassline";
$strClassFirst="bgclassfirst";
$strClassSecond="bgclasssecond";
$strOtherBgClass="bgclassother";
$strOtherLineClass="bgclassline";
$intDefaultSize=20;
$out= "
$
";
$bwlPossibleMCD=false;
//we've not been adding to the content of this delimited item
//because it began with the first several characters of a
//multichar delimiter (MCD). so we have to take those first
//few chrs and add them to $thisvar.
$thisvar.=$strTempPossibleDelimeter;
$strTempPossibleDelimeter="";
$intDelimiterChrCount=0;
}
}
if($bwlPossibleMCD )//MCD means multi-chr delimiter
{
if($intDelimiterChrCount==strlen($delimiter))
{
//echo $thisvar . "\n";
if($chrEndQuoteToStripFromData!="")
{
$thisvar=RemoveEndCharactersIfMatch($thisvar, $chrKnownQuote);
}
$arrOut[$intArrCursor]=$thisvar;
$intArrCursor++;
$thisvar="";
$intDelimiterChrCount=0;
$strTempPossibleDelimeter="";
$bwlPossibleMCD =false;
}
}
else if (!$bwlQuoteOn && ($chrKnownQuote=="" && inList($quotechar, $chr) || $chrKnownQuote==$chr))
{
$bwlQuoteOn=true;
$chrKnownQuote=$chr;
if($bwlLeaveQuotesInPlace)
{
$thisvar.=$chr;
}
}
else if ($bwlQuoteOn)
{
//$chrPrev catches the situation in which the backslash is itself escaped
if($chr=="\\" && $strEscapeStyle=="php" && $chrPrev!="\\")
{
if($chrNext==$chrKnownQuote)
{
$chrQuoteToBeEscaping=$chrNext;
}
}
else if($chrKnownQuote=="" && inList($quotechar, $chr) || $chrKnownQuote==$chr) //only for csv escapes
{
//handle internally-escaped quotes, that is, a known quote escaping one immediately following in data
if($chrQuoteToBeEscaping==$chr)
{
$chrQuoteToBeEscaping="";
$thisvar.=$chr;
}
else if($chrNext==$chrKnownQuote && $strEscapeStyle=="csv")
{
//was: $chrQuoteToBeEscaping=$chr;
$chrQuoteToBeEscaping=$chrNext;
if($bwlLeaveQuotesInPlace)
{
$thisvar.=$chr;
}
}
else
{
$bwlQuoteOn=false;
$chrKnownQuote="";
if($bwlLeaveQuotesInPlace)
{
$thisvar.=$chr;
}
}
}
else //we're not a quote but we are a chr in a quoted section of text
{
if($chrQuoteOverwrite!="")
{
$thisvar.=$chrQuoteOverwrite;
}
else
{
$thisvar.=$chr;
}
}
}
else if($bwlLeaveQuotesInPlace)
{
if($chrNonQuoteOverwrite=="")
{
$thisvar.=$chr;
}
else
{
$thisvar.=$chrNonQuoteOverwrite;
}
}
}
}
if($chrEndQuoteToStripFromData!="")
{
$thisvar=RemoveEndCharactersIfMatch($thisvar, $chrEndQuoteToStripFromData);
}
$arrOut[$intArrCursor]=$thisvar;
return $arrOut;
}
function BlankOutQuotedAreas($data, $chrBlank, $quotechar="' \"", $chrPHPCommentBlank="")
//Whoever passes in $quotechar will want to have done
//$quotechar=HandleNumericCasesInSpaceDelimitedChrString($quotechar);
//to it. i don't do that here since this function is done inside loops and
//$quotechar=HandleNumericCasesInSpaceDelimitedChrString($quotechar) is somewhat expensive
//I take advantage of BetterExplode's parser to blank out the quoted areas
{
$arrThis=BetterExplode(" ", $data, $quotechar="\" '", true, "csv", true, "", $chrBlank, $chrPHPCommentBlank);
$out=implode(" ", $arrThis);
return $out;
}
function PosInList($strList, $strProspect, $strDelimiter=" ", $bwlIgnoreCase=true, $quotechar="' \"")
//Search for each item of $strList in $strProspect and returns first found strpos or -1 if nothing
{
$arrList=explode(" ", $strList);
if($quotechar!="")
{
$bwlIgnoreQuotedAreas=true;
}
else
{
$bwlIgnoreQuotedAreas=false;
$quotechar=HandleNumericCasesInSpaceDelimitedChrString($quotechar);
}
if($bwlIgnoreCase)
{
$strList=strtolower($strList);
$strProspect=strtolower($strProspect);
}
foreach($arrList as $strToTest)
{
if(! $bwlIgnoreQuotedAreas)//fast algorithm for cases where quoted areas don't need to be ignored
{
if(contains($strProspect, $strToTest))
{
//i added 1 here to get something to work right but i'm not sure it's the right thing to do
return(strpos($strProspect, $strToTest) + 1);
}
}
else//got to do the slow-ass algorithm
{
//echo " ";
$strAlterSQL="";
$strUpdateSQL="";
$strAlterSetSQL="";
$bwlMustShortenByFour=false;
if(is_array($arrDescribedValuePairs))
{
foreach($arrDescribedValuePairs as $k=>$v)
{
$bwlMustShortenByFour=true;
$valtostore=$v;
if($bwlEscape)
{
$valtostore= singlequoteescape($v);
}
if(is_array($arrAlteredValuePairs))
{
if(!array_key_exists($k, $arrAlteredValuePairs))
{
$strSQL.= " " . $k . "='" . $valtostore . "' AND";
$strUpdateSQL.= $k . "='" . $valtostore . "',";
$strAlterWhereSQL.=" " . $k . "='" . $valtostore . "' AND";
}
}
else
{
$strSQL.= " " . $k . "='" . $valtostore . "' AND";
$strUpdateSQL.= $k . "='" . $valtostore . "',";
$strAlterWhereSQL.=" " . $k . "='" . $valtostore . "' AND";
}
}
}
if(is_array($arrAlteredValuePairs))
{
foreach($arrAlteredValuePairs as $k=>$v)
{
//echo $k . " " . $v . "== ";
if($bwlMustShortenByFour)//gets rid of the " AND"
{
$strSQL= substr($strSQL, "0", strlen($strSQL)-4);
}
$strAlterWhereSQL= substr($strAlterWhereSQL, "0", strlen($strAlterWhereSQL)-4);
$strUpdateSQL= RemoveLastCharacterIfMatch($strUpdateSQL, ",");
$strAlterSetSQL= RemoveLastCharacterIfMatch($strAlterSetSQL, ",");
$idInsert="";
$bwlCanGetInsertID=false;
$records=$sql->query($strSQL);
//echo "count records: " . count($records) . " ";
if (count($records)>0 && count($arrDescribedValuePairs)>0 && is_array($arrDescribedValuePairs) && $strAlterWhereSQL!="" && $strAlterSetSQL!="")
{
//need an update
$strSQL="UPDATE " . $strDatabase . "." . $strTable . " SET ". $strAlterSetSQL . " WHERE " . $strAlterWhereSQL;
}
else if (count($records)<1 || !is_array($arrDescribedValuePairs))
{
//need an insert
$strSQL="INSERT INTO " . $strDatabase . "." . $strTable . " SET ". $strAlterSetSQL . IfAThenB($strAlterSetSQL, ", ") . $strUpdateSQL ;
$bwlCanGetInsertID=true;
}
if($strSQL!="")
{
$strSQL= RemoveLastCharacterIfMatch($strSQL, " ");
$strSQL= RemoveLastCharacterIfMatch($strSQL, ",");
//echo $strSQL . " ";
if ($bwlDebug=="die")
{
die();
}
}
}
//echo $idInsert . "= ";
}
return "Database state saved.";
}
function hasautocount($strDatabase, $strTable)
//Does the table have an autocount column?
{
$records=DBExplain($strDatabase, $strTable);
$count=0;
foreach ($records as $k => $v )
{
if ($v["Extra"]=="auto_increment")
{
return true;
}
}
return false;
}
function TypeParse($strIn, $intPart)
//Parse mysql types into the basic type ($intPart=0) and whatever descriptive numerics follow ($intPart=1).
{
$strIn=str_replace(" ","", $strIn);
$strIn=str_replace("(","|", $strIn);
$strIn=str_replace(")","|", $strIn);
$arrIn=explode("|", $strIn);
return $arrIn[$intPart];
}
function ReturnNonIDPartOfName($strIn)
//This function only works in a DB with strict adherence to the _id naming convention.
{
if (contains($strIn, "_"))
{
$arrIn=explode("_", $strIn);
for($i=0; $i
preblankedout: " . $strProspect . "
";
$strProspect=BlankOutQuotedAreas($strProspect, "*", $quotechar);
//echo "
blankedout: " . $strProspect . "
";
//echo $strToTest . "==totest
";
//echo $strProspect . "------------" . $strToTest . "==prospect/totest
";
if(contains($strProspect, $strToTest))
{
//i added 1 here to get something to work right but i'm not sure it's the right thing to do
return(strpos($strProspect, $strToTest) + 1);
}
}
}
return -1;
}
function inList($strList, $item, $MatchOnlyType="")
//look to see if item is in the space-delimited strList (similar to my ASP version)
{
$arrThis=explode(' ', $strList);
for ($t=0; $t
\n";
//echo hexdump($strProspectiveTag) . "
\n";
if(inList($taglist, $strProspectiveTag) || inList($taglist, RemoveFirstCharacterIfMatch($strProspectiveTag, "/")))
{
$inUnapprovedTag = true;
}
else
{
$inApprovedTag=true;
}
}
if(!$inUnapprovedTag)
{
$newString.= substr($oldString,$i,1);
}
if( substr($oldString,$i,strlen($end)) == $end && $inUnapprovedTag ==true && !($end=="" && $inUnapprovedTag ==true))
{
$inUnapprovedTag = false;
//$i++;
}
if( substr($oldString,$i,strlen($end)) == $end && $inApprovedTag ==true && !($end=="" && $inApprovedTag ==true))
{
$inApprovedTag = false;
//$i++;
}
//i want to bail at $maxLength, but not if we're still in a good tag
if (strlen($newString)>$maxLength && !$inApprovedTag)
{
break 1;
}
}
return $newString;
}
function truncate($strIn, $intNumber)
//Truncates $strIn to $intNumber (more or less) at the nearest space less than $intNumber and adds ...
//I've added some code to make sure an image tag early in $strIn is shown in full, but shrunk to a thumbnail
{
$taglist="div span DIV SPAN p br P BR strong b STRONG B i I h3 h2 h1 H1 H2 H3";
$strIn= killBetweenTags($strIn, $taglist, $intNumber + 10);
//echo "+" . $strIn . "\n";
$strLen=strlen($strIn);
$bwlSkipElipsis=false;
if ($strLen<$intNumber+2)
{
return $strIn;
}
//parsehyperlink($strIn, 55);
$intStart=$intNumber;
for ($i=$intStart; $i>1; $i--)
{
if (substr($strIn, $i, 1)==" ")
{
$out= substr($strIn, 0, $i);
$lespos=strrpos($out,"<");
$grepos=strrpos($out,">");
if (($grepos<$lespos || $grepos === false ) && $lespos<$intNumber && !($lespos === false) )
{
$grepos=strpos($strIn,">", $lespos)+1;
$out = substr($strIn, 0, $grepos);
$out=str_replace("");
if (($grepos<$lespos || $grepos=="") && $lespos<$intNumber && !($lespos === false))
{
$grepos=strpos($strIn,">", $lespos)+1;
$out = substr($strIn, 0, $grepos);
$out=str_replace("0)
{
return truncate($strIn, $intNumber);
}
else
{
return parsehyperlink($strIn, $intNumber);
}
}
function htmlrow($strClass)
//Produces a row for the display of data, configured now to do so in an HTML table.
//If one precedes a class name with a * then the row gets a MAtrselectfromline onclick event, which is very useful for all sorts of things
{
$out="\n";
}
elseif ($strClass!="")
{
$out.=" class=\"" . $strClass . "\"";
}
$out.=">\n";
$out.=$strPreFed;
for($i=1; $i<$intArgs; $i++)
{
$strWidth="";
$content=func_get_arg($i);
if (contains($content, "insert.gif"))
{
$strWidth="width=\"33\"";
}
elseif(!contains($content, "<"))
{
$strWidth="width=\"22%\"";
}
$bwlNoTD=false;
if (contains($content, "type=\"hidden\"") && !contains($content, "\n";
}
else
{
$out.=" \n";
return $out;
}
function replaceMultipleQueryVariables()
{
//probably won't use this as much as linkme, since it just generates the link, not the HTML
$strPHP=$_SERVER['PHP_SELF'];
$intArgs =func_num_args();
$out="";
$arrOut=$_REQUEST;
for($i=0; $i<$intArgs; $i=$i+2)
{
$var=func_get_arg($i);
$val=func_get_arg($i+1);
$strOut=replaceSpecificQueryVariable($var, $val, $arrOut);
$arrOut=QuerystringToAssociativeArray($strOut);
}
$out=$strPHP . "?" . $strOut;
return $out;
}
function QuerystringToAssociativeArray($strIn)
//convert a querystring directly into an associative array without ever having it be an actual querystring
{
$arrOut=array();
$arr=explode("&", $strIn);
foreach($arr as $a)
{
$arrSub=explode("=", $a);
$arrOut[$arrSub[0]]=urldecode($arrSub[1]);
}
return $arrOut;
}
function linkme($strIn, $target)
//creates a hyperlink labeled with $strIn, replacing any query variables passed in additionally
{
$strPHP=$_SERVER['PHP_SELF'];
$intArgs =func_num_args();
$out="";
$arr=array();
for($i=2; $i<$intArgs; $i=$i+2)
{
$var=func_get_arg($i);
$val=func_get_arg($i+1);
$str= replaceSpecificQueryVariable($var, $val, $arr);
$arr =QuerystringToAssociativeArray($str);
}
$out=$strPHP . "?" . $str;
$targethtml="";
if ($target!="")
{
$targethtml=" target=\"" . $target . "\"";
}
$out="" . $strIn . "";
return $out;
}
function replaceSpecificQueryVariable($strVariable, $strValue, $arr="")
//replaces specific associative element in an array, usually the Query String, though it can be a passed-in array of the Post array.
{
$out="";
$intOut=0;
$strCharacterGlue="";
$bwlFoundOurVariable=false;
if (is_array($arr) && count($arr)>0)
{
$arrToScan=$arr;
}
else
{
if (count($_GET)==0 && count($_POST)>0)
{
$arrToScan=$_POST;
}
else
{
$arrToScan=$_GET;
}
}
foreach ($arrToScan as $k=>$v)
{
if (strlen($v)<100)//keep the query string to a reasonable size in some cases
{
if ($intOut!=0)
{
$strCharacterGlue="&";
}
if ($k==$strVariable)
{
$out.= $strCharacterGlue . $k. "=" . urlencode($strValue);
$bwlFoundOurVariable=true;
}
else
{
if(is_string($v))
{
$out.=$strCharacterGlue . $k. "=" . urlencode($v);
}
}
}
$intOut++;
}
if ($out=="")
{
$out=$strVariable. "=" . urlencode($strValue);
}
elseif (!$bwlFoundOurVariable)
{
$out.="&" . $strVariable. "=" . urlencode($strValue);
}
//echo "--" . $out;
return $out;
}
function EliminateEmptyArrayPairs($arrIn)
{
$arrOut=Array();
foreach($arrIn as $k=>$v)
{
if($v!="")
{
$arrOut[$k]=$v;
}
}
return $arrOut;
}
function ZeroIfEmpty($in)
{
if ($in=="")
{
return 0;
}
return $in;
}
function IfAThenB($a,$b)
{
if ($a!="")
{
return $b;
}
}
function tablechecksum($strDatabase, $tablename)
//Judas Gutenberg, September 2 2008
//returns a table's checksum from mysql
{
$sql=conDB();
//for some reason i have to do this. it's a bug in mysql
$strSQL="ALTER TABLE " . $strDatabase . "." . $tablename . " CHECKSUM=1";
$rs = $sql->query($strSQL);
//echo sql_error(). "\n";
}
}
else
{
$out.=" \n";
}
$out.="
";
$strSQL="CHECKSUM TABLE " . $strDatabase . "." . $tablename;
$rs = $sql->query($strSQL);
$r=$rs[0];
$out=$r["Checksum"];
//echo $tablename . " " . $out . "
";
return $out;
}
function CountSQLRecords($strSQLQuery)
{
if (strpos(strtolower($strSQLQuery), "count(")<1)
{
$strSQLQuery=str_replace("*", "count(*) as 'countage'", $strSQLQuery);
}
$sql=conDB();
$countrecords = $sql->query($strSQLQuery);
$countrecord=$countrecords[0];
$intCount=$countrecord["countage"];
return $intCount;
}
function RequestCompoundDate($pre)
{
$day=$_REQUEST[$pre . "|day" ];
$month=$_REQUEST[$pre . "|month" ];
$year=$_REQUEST[$pre. "|year" ];
$strTime=ReasonableStringDate($month, $day, $year);
$v=$strTime; //just turning the value into a PHP timestamp
$k=$strPossibleDateName; //just turning the key back to a conventional key for the next section
return $v;
}
function GVFF($spacedelimitednamelist, $arrAdditional="", $type="post" )
//returns an array of requests with values
{
$arrIn=explode(" ", $spacedelimitednamelist);
$arrOut=Array();
foreach($arrIn as $k)
{
if ($type=="request")
{
$v=$_REQUEST[$k];
}
else if ($type=="post")
{
$v=$_POST[$k];
}
else if ($type=="get")
{
$v=$_GET[$k];
}
$arrOut[$k]=$v;
}
if (is_array($arrAdditional))
{
foreach($arrAdditional as $k=>$v)
{
$arrOut[$k]=$v;
}
}
return $arrOut;
}
function UpdateOrInsert($strDatabase, $strTable, $arrDescribedValuePairs, $arrAlteredValuePairs, $bwlEscape=true, $bwlDebug=false)
//Does an insert or an update depending on whether or not the described record exists.
//Make sure to not include items in $arrAlteredValuePairs that are in $arrDescribedValuePairs.
//If there are no $arrDescribedValuePairs, they become $arrAlteredValuePairs in an INSERT.
{
$sql=conDB();
$strSQL="SELECT * FROM " . $strDatabase . "." . $strTable . " WHERE ";
//echo $strSQL . "
";
if ($k!="")
{
$valtostore=$v;
if($bwlEscape)
{
$valtostore= singlequoteescape($v);
}
$strAlterSetSQL.= $k . "='" . $valtostore . "',";
}
}
}
//echo "strAlterSetSQL " . $strAlterSetSQL . "
";
//echo "count descr val pairs: " . count($arrDescribedValuePairs) . "
";
//echo "isarray descr val pairs: " . is_array($arrDescribedValuePairs) . "
";
//echo "strAlterWhereSQL " . $strAlterWhereSQL . "
";
//echo "strAlterSetSQL " . $strAlterSetSQL . "
";
if(CanChange())
{
$records = $sql->query($strSQL);
}
else
{
return "Database is read-only.
";
}
if($bwlCanGetInsertID)
{
$idInsert=mysql_insert_id();
}
if($bwlDebug)
{
echo "" . $strSQL . "
";
echo sql_error() . "
";
$out= gracefuldecay(sql_error(),$idInsert) ;
return $out;
}
function paginatelinks($intRecCount, $intRecordsPerPage, $intStartRecord, $strPHP, $strThisQVar)
//Paginates a record set
//$intRecCount is the total number of records in unpaginated record set
{
$out="";
if ($intStartRecord=="")
{
$intStartRecord=0;
}
$intPages=intval(($intRecCount-1)/$intRecordsPerPage);
if ($intPages>0)
{
for ($i=0; $i<=$intPages; $i++)
{
$url=$strPHP . "?" . replaceSpecificQueryVariable($strThisQVar, $i * $intRecordsPerPage);
if (intval($intStartRecord)!= intval($i * $intRecordsPerPage) )
{
$out.="" .intval($i +1) . "";
}
else
{
$out.= "" . intval($i +1) . "";
}
if (($i+1)* $intRecordsPerPage<$intRecCount)
{
$out.= " | ";
}
}
return "Go to Page: " . $out;
}
}
function NumToMon($intNum)
//Take a number from 1 to 12 and return a month name.
{
$strMons="|January|February|March|April|May|June|July|August|September|October|November|December";
$arrMons=explode("|", $strMons);
return $arrMons[$intNum];
}
function getMax($intOne, $intTwo)
//Returns the larger of two numbers.
{
if ($intOne>$intTwo)
{
$intBigger=$intOne;
}
else
{
$intBigger=$intTwo;
}
return $intBigger;
}
function getMin($intOne, $intTwo)
//Returns the smaller of two numbers.
{
if ($intOne<$intTwo)
{
$intSmaller=$intOne;
}
else
{
$intSmaller=$intTwo;
}
return $intSmaller;
}
////specifically DB-related functions
function deMoronizeDB($strDB)
//Fixes idiotic dbs that contain dashes in their names. Thanks a lot, certain DB host providers!
{
if (contains($strDB, "-") && !contains($strDB, "`"))
{
$strDB="`" . $strDB . "`";
}
return $strDB;
}
function DuplicatesInThisField($arrIn, $strFieldName, $strValue)
{
//scans through a mysql recordset looking to see id there are duplicates of $strValue in a field named $strFieldName
$found=0;
foreach($arrIn as $row)
{
if ($row[$strFieldName]==$strValue)
{
$found++;
if ($found>1)
{
return true;
}
}
}
return false;
}
function numericpulldown($intstart,$intend,$intdefault,$strName, $bwlDontShowNone=false)
//Gives me a select with numbers running from $intstart to $intend, with $intdefault selected, and names it $strName
{
$strOut=""."\n";
$function_ret=$strOut;
return $function_ret;
}
function datepulldowns($strNamePre,$dtmDefault, $bwlDontShowNone=false)
//provides a set of pulldowns to select a date
{
if (!is_numeric($dtmDefault) && $dtmDefault!="")
{
$dtmDefault=strtotime($dtmDefault);
}
$strSuperPre=qpre;
$strOut="";
if (is_numeric($dtmDefault))
{
$intMonth=strftime("%m",$dtmDefault);
$intYear=strftime("%Y",$dtmDefault);
$intDay=strftime("%d",$dtmDefault);
}
else
{
$intDay="";
$intMonth="";
$intYear="";
}
$yearlow=gracefuldecaynumeric(numrange_low,0);
$yearhi=gracefuldecaynumeric(numrange_hi,99);
if (strlen($yearlow)==4)
{
$intYear=intval($intYear);
}
else
{
$intYear=intval(substr($intYear,strlen($intYear)-(2)));
}
if (substr($intYear,0,1)=="0")
{
$intYear=intval(substr($intYear,strlen($intYear)-(1)));
}
$strOut.= "\n".numericpulldown(1,12,$intMonth,$strSuperPre . $strNamePre."|month", $bwlDontShowNone)."\n"." / ";
$strOut.="\n".numericpulldown(1,31,$intDay,$strSuperPre . $strNamePre."|day", $bwlDontShowNone)."\n" . " / ";
$strOut.="\n".numericpulldown($yearlow,$yearhi,$intYear,$strSuperPre . $strNamePre."|year", $bwlDontShowNone)."\n";
return $strOut;
}
function gracefuldecaynumeric()
{
//go through the parameters and return the first that isn't empty
$intArgs =func_num_args();
for($i=0; $i<$intArgs; $i++)
{
$option=func_get_arg($i);
if (is_numeric($option))
{
return $option;
}
}
}
function gracefuldecaynotzero()
{
//go through the parameters and return the first that isn't empty
$intArgs =func_num_args();
for($i=0; $i<$intArgs; $i++)
{
$option=func_get_arg($i);
if ($option!=0)
{
return $option;
}
}
}
function boolcheck($strName,$strDefault, $bwlFriendly=false, $bwlNoForm=false,$strStyle="")
//shows a set of radio buttons for setting a boolean db value
{
$strTrue="true";
$strFalse="false";
if ($bwlFriendly)
{
$strTrue="yes";
$strFalse="no";
}
if ($bwlNoForm)
{
if (intval($strDefault)==1)
{
return $strTrue;
}
return $strFalse;
}
else
{
if (intval($strDefault)==1)
{
$out= " " . $strTrue ;
$out.= " " . $strFalse ;
}
else if (!($strDefault==="") && !is_null($strDefault))
{
$out= " " . $strTrue ;
$out.= " " . $strFalse ;
}
else
{
$out= " " . $strTrue ;
$out.= " " . $strFalse ;
}
}
if ($strStyle!="")
{
$out= "" . $out . "";
}
return $out;
}
function LabelForID($strDatabase, $strTable, $strIDField, $intID)
{
$strNameField=firstnonidcolumname($strDatabase, $strTable);
if ( $intID!="")
{
$sql=conDB();
$strSQL="SELECT " . $strNameField . " FROM " . $strDatabase . "." . $strTable . " WHERE " . $strIDField . " = " . $intID;
$records = $sql->query($strSQL);
if ($records)
{
//echo"@";
$record=$records[0];
return $record[$strNameField];
}
}
}
function foreigntablepulldown($strDatabase, $strTable, $strIDField, $intDefault, $strLabelField="", &$namereturn, $bwlHiddenReturn=false, $strPreferredNameField="", $styleclass="")
//Gives me a select named $strIDField of ids with rows from $strTable, defaulted to $intDefault
//$namereturn, passed by reference, allows me to hand back the selected string label of the pulldown, which is won at considerable
//computative effort
//bwlHiddenReturn allows me to pass the actual string value of the dropdown in a specially-labeled hidden field.
{
$sql=conDB();
$strHiddenExtra="";
$strNameField2="";
$strNameField="";
$moreflag=false;
if ($strLabelField=="")
{
$strLabelField= $strIDField;
}
$strOut="\n";
$strOut.= $strHiddenExtra;
return $strOut;
}
function FindOtherTableMapped($strDatabase, $strGivenTable, $strMappingTable)
//Given a mapping table and a table at one end of the map, return the other.
{
$sql=conDB();
$strSQL="SELECT * FROM " . $strDatabase . "." . tfpre . "relation WHERE table_name='" . $strMappingTable . "' AND relation_type_id=0";
$records = $sql->query($strSQL);
foreach($records as $record)
{
if( $record["f_table_name"]!=$strGivenTable)
{
return $record["f_table_name"];
}
}
}
function FindMappingTable($strDatabase, $strTable, $strMappedTable, $strMappedPKName="", $strAvoidTableList="")
//Return the name of table that maps one table to another
{
$sql=conDB();
$strTableList="";
$strMTableList="";
if($strMappedTable!="")
{
$strSQL="SELECT * FROM " . $strDatabase . "." . tfpre . "relation WHERE (f_table_name='" . $strTable . "' OR f_table_name='" . $strMappedTable . "') AND relation_type_id=0 " ;
}
else
{
$strSQL="SELECT * FROM " . $strDatabase . "." . tfpre . "relation WHERE (f_table_name='" . $strTable . "' OR f_column_name='" . $strMappedPKName . "') AND relation_type_id=0 " ;
}
//echo $strSQL;
$records = $sql->query($strSQL);
foreach($records as $record)
{
if( $record["f_table_name"]==$strTable)
{
$strTableList.=$record["table_name"]. " ";
if (inList($strMTableList, $record["table_name"]) && !inList($strAvoidTableList, $record["table_name"]))
{
return $record["table_name"];
}
}
if( $record["f_table_name"]==$strMappedTable )
{
$strMTableList.=$record["table_name"] . " ";
if (inList($strTableList, $record["table_name"]) && !inList($strAvoidTableList, $record["table_name"]))
{
return $record["table_name"];
}
}
if( $record["f_column_name"]==$strMappedPKName )
{
$strMTableList.=$record["table_name"] . " ";
if (inList($strTableList, $record["table_name"])&& !inList($strAvoidTableList, $record["table_name"]))
{
return $record["table_name"];
}
}
}
return false;
}
function FieldCount($strDatabase, $strTable)
//Returns the number of columns in a table.
{
$records = DBExplain($strDatabase, $strTable);
return count($records);
}
function MaxColNameLength($strDatabase, $strTable)
//Returns the length in characters of a table's column names. Will return table's name if it's longest
{
$records = DBExplain($strDatabase, $strTable);
$maxlen=strlen($strTable);
foreach ($records as $k => $info )
{
$len=strlen($info["Field"]);
if($len>$maxlen)
{
$maxlen=$len;
}
}
return $maxlen;
}
function countrecords($strDatabase , $strTable )
//Returns the number of records in a table.
{
$sql=conDB();
$countrecs = $sql->query("SELECT COUNT(*) FROM " . $strDatabase . "." . $strTable );
$countrec=$countrecs[0];
$count=$countrec["COUNT(*)"];
return $count;
}
function PercentageOfNotNullsInTable($strDatabase, $strTable)
{
//September 14, 2008
//this function is, of necessity, super expensive!
//returns an associative array of percentages of not nulls for each field
//so you can tell the relative utility of the fields in actual practice
$sql=conDB();
$records = DBExplain($strDatabase, $strTable);
$arrOut=Array();
$total=countrecords($strDatabase, $strTable);
foreach ($records as $k => $info)
{
$strField= $info["Field"];
$strSQL="SELECT count(" . $strField .") AS result FROM " . $strDatabase . "." . $strTable . " WHERE " . $strField . "!=\"\"";
//echo $strSQL . "
";
$records = $sql->query($strSQL);
$record=$records[0];
$val=$record["result"];
//$total=$record["total"];
if($total>0)//don't divide by zero
{
$percent=intval($val/$total * 100);
}
else
{
$percent=0;
}
if (!is_numeric($percent) || $percent=="")
{
$percent="0";
}
$arrOut[$strField]=$percent;
}
return $arrOut;
}
function FleshedOutFKSelect($strDatabase, $strTable, $additionalClauses, &$arrDesc, $strUnnecessaryJoinTables="", $bwlKeepPKs=false, $bwlIncludeAllRelatedFields=false)
//Delivers the SQL to do a select from a table with the necessary joins so that instead of foreign key ids we get
//fields populated with readable strings
//ALSO: returns an array by reference containing types, because this is essential info for a lot of what this SQL is used to do
//Judas Gutenberg 2007-2-1
{
$sql=conDB();
//first get all the text fields for all the foreign keys
$strPK=PKLookup($strDatabase, $strTable);
$strSQL="SELECT * FROM " . $strDatabase . "." . tfpre . "relation WHERE relation_type_id=0 AND table_name='" . $strTable . "'";
//echo $strSQL;
$records = $sql->query($strSQL);
$strJoinSQL="";
$strPreJoinSQL="";
$strSkipFieldList="";
$arrDesc=Array();
$bwlDie=false;
$count=0;
foreach($records as $record)
{
//echo $record["f_table_name"] . " " . $strTable . "
";
if ($record["f_table_name"]== $strTable)
{
$bwlDie=true;
}
if (!inList($strUnnecessaryJoinTables, $record["f_table_name"]))
{
$strJoinSQL.=" LEFT JOIN " . $strDatabase . "." . $record["f_table_name"] . " x" . $count. " ON t." . $record["column_name"] . "=x" . $count. "." . $record["f_column_name"] . " " ;
$nameColumn=firstnonidcolumname($strDatabase, $record["f_table_name"]);
$strNameAdditional="";
//in some cases the foreign table's field name isn't specific enough in the join to be a proper label
//so in those cases i append the table name to the front of the fieldname to make it into a proper label
if($nameColumn=="name")
{
$strNameAdditional=" as `" . $record["f_table_name"] . "_" . $nameColumn . "`";
}
$arrDesc[$nameColumn]= GetFieldType($strDatabase, $record["f_table_name"], $nameColumn);
if($bwlIncludeAllRelatedFields)
{
$leafrecords = DBExplain($strDatabase,$record["f_table_name"]);
foreach($leafrecords as $kl=>$vl)
{
$strPreJoinSQL.=" x".$count . "." . $vl["Field"] . "," ;
}
}
else
{
$strPreJoinSQL.=" x".$count . "." . $nameColumn .$strNameAdditional. "," ;
}
if(!$bwlKeepPKs)
{
$strSkipFieldList.=" " . $record["column_name"];
}
$count++;
}
}
//now throw away the FK fields themselves, since they just gum up the works
$records=DBExplain($strDatabase, $strTable);
$intFindCount=1;
$goodFieldList="";
foreach ($records as $k => $info )
{
if(!inList($strSkipFieldList, $info["Field"]))
{
$goodFieldList.="t." . $info["Field"] . ",";
$arrDesc[$info["Field"]]= GetFieldType($strDatabase, $strTable, $info["Field"]);
}
}
$goodFieldList=RemoveEndCharactersIfMatch($goodFieldList, ",");
$strPreJoinSQL=RemoveEndCharactersIfMatch($strPreJoinSQL, ",");
$out="SELECT DISTINCT " . $goodFieldList . IFAthenB(($strPreJoinSQL && $goodFieldList),", ") . $strPreJoinSQL ." FROM " . $strTable . " t " . $strJoinSQL . " " . " " . $additionalClauses . " GROUP BY " . $strPK ;
if (count($arrDesc)<1)
{
$arrDesc=GetFieldTypeArray($strDatabase, $strTable);
}
if($bwlDie)
{
$out="";
}
//echo $out;
return $out;
}
function firstnonidcolumname($strDatabase, $strTable)
//In which i make a reasonable guess of how to best provide a user-friendly label for a row of data
//I basically look through the fields until I find the first one that isn't type int or named password
{
return NthNonIDColumName($strDatabase, $strTable, 1);
}
function NthIDColumName($strDatabase, $strTable, $n)
//I basically look through the fields until I find the $nth one that is type int
{
$records=DBExplain($strDatabase, $strTable);
$intFindCount=1;
foreach ($records as $k => $info )
{
$olderror=error_reporting(0);
//echo TypeParse($info["Type"],0) . "==
";
//if (!contains(TypeParse($info["Type"],0),"int") && (!contains($info["Field"], "password") & !contains($info["Field"], "image") & !contains($info["Field"], "filename") & !contains($info["Field"], "date") & !contains($info["Field"], "price")))
if (contains(TypeParse($info["Type"],0),"int"))
{
//echo $info["Field"]. "=
";
if ($intFindCount==$n)
{
//echo $info["Field"] . "**
";
return $info["Field"];
}
$intFindCount++;
}
error_reporting($olderror);
}
}
function NthNonIDColumName($strDatabase, $strTable, $n)
//In which i make a reasonable guess of how to best provide a user-friendly label for a row of data
//I basically look through the fields until i find the $nth one that isn't type int or named password
{
$records=DBExplain($strDatabase, $strTable);
$intFindCount=1;
foreach ($records as $k => $info )
{
$olderror=error_reporting(0);
//echo TypeParse($info["Type"],0) . "==
";
//if (!contains(TypeParse($info["Type"],0),"int") && (!contains($info["Field"], "password") & !contains($info["Field"], "image") & !contains($info["Field"], "filename") & !contains($info["Field"], "date") & !contains($info["Field"], "price")))
if (!contains(TypeParse($info["Type"],0),"int") && (!contains($info["Field"], "password") ))
{
if ($intFindCount==$n)
{
return $info["Field"];
}
$intFindCount++;
}
error_reporting($olderror);
}
}
function SortColumn($strDatabase, $strTable)
//Looks for a possible sort column
//February 25 2007
{
$records=DBExplain($strDatabase, $strTable);
foreach ($records as $k => $info )
{
$olderror=error_reporting(0);
//echo TypeParse($info["Type"],0) . "==
";
//if (!contains(TypeParse($info["Type"],0),"int") && (!contains($info["Field"], "password") & !contains($info["Field"], "image") & !contains($info["Field"], "filename") & !contains($info["Field"], "date") & !contains($info["Field"], "price")))
//echo $info["Field"] . "**
";
if (contains(TypeParse($info["Type"],0),"int"))
{
//echo $k . "
";
$name=$info["Field"];
if(contains($name, "sort"))
{
return $name;
}
}
error_reporting($olderror);
}
}
function foreignKeyLookup($strDatabase, $strTable, $strColumn)
//Looks up the foreign key table and column given a column.
{
$sql=conDB();
$records = $sql->query("SELECT column_name, f_table_name, f_column_name FROM " . $strDatabase . "." . tfpre . "relation WHERE table_name='" . $strTable . "' AND column_name='" . $strColumn . "' AND relation_type_id=0");
$count=0;
foreach ($records as $record)
{
return array( $record["f_table_name"], $record["f_column_name"]) ;
$count++;
}
}
function PKLookup($strDatabase, $strTable)
//Looks up the PK for a table.
{
$records=DBExplain($strDatabase, $strTable);
foreach ($records as $k => $v )
{
if ($v["Key"]=="PRI")
{
$out.= " ". $v["Field"];
}
}
return trim($out);
}
function RelationLookup($strDatabase, $strTable, $strColumn, $intType=0)
//Looks up the multi-table info given a column
{
$sql=conDB();
$records = $sql->query("SELECT column_name, f_table_name, f_column_name FROM " . $strDatabase . "." . tfpre . "relation WHERE table_name='" . $strTable . "' AND column_name='" . $strColumn . "' AND relation_type_id=" . $intType);
$count=0;
foreach ($records as $record)
{
return array( $record["f_table_name"], $record["f_column_name"]) ;
$count++;
}
}
function firstforeignkeycolumn($strDatabase, $strTable, $strMappedTableToAvoid)
//In which i make a reasonable guess of where a mapping table maps to
//returns a three-member array, with [0]the field name and [1] the mapped table and [2] the mapped column
//I pass in $strMappedTableToAvoid to avoid mapping off to the table I'm starting from
//modified for MySQL 2-7-06
{
return Nthforeignkeycolumn($strDatabase, $strTable, $strMappedTableToAvoid, 1);
}
function Nthforeignkeycolumn($strDatabase, $strTable, $strMappedTableToAvoid, $n)
//In which i make a reasonable guess of where a mapping table maps to
//returns a three-member array, with [0]the field name and [1] the mapped table and [2] the mapped column
//I pass in $strMappedTableToAvoid to avoid mapping off to the table I'm starting from
//modified for MySQL 2-7-06
{
$sql=conDB();
$records = $sql->query("SELECT * FROM " . $strDatabase . "." . tfpre . "relation WHERE table_name='" . $strTable . "' AND relation_type_id=0");
$count=0;
$right=0;
foreach ($records as $record)
{
if ( $record["f_table"] != $strMappedTableToAvoid )
{
//echo $k . "->" . $v . "
";
$right++;
if ($n==$right)
{
return array( $record["column_name"], $record["f_table_name"], $record["f_column_name"], $record["display_column_name"]) ;
}
}
$count++;
}
}
function highestprimarykey($strDatabase, $strTable)
//I want the max PK id for a table.
//I didn't know that PHP has built-in support for this functionality when I wrote this.
//actually, though, this function does something somewhat different from PHP's mysql_insert_id functionality
//because it allows me to go in and find the largest PK value in a table to which nothing was added
//modified sept 2 2008 to deal with compound pks, returning null in that case
{
$sql=conDB();
$out="";
$records=DBExplain($strDatabase, $strTable);
foreach ($records as $k => $v )
{
if ($v["Key"]=="PRI")
{
if($out!="")
{
return; //return null if we have two PKs
}
$strSQL="SELECT MAX(" . $v["Field"]. ") FROM " . $strDatabase . "." . $strTable;
$orecords=$sql->query($strSQL);
$orecord =$orecords[0];
$out= $orecord["MAX(" . $v["Field"]. ")"];
}
}
return $out;
}
function FieldExists($strDatabase, $strTable, $strFieldName)
//Does this field exist in this table?
{
$records=DBExplain($strDatabase, $strTable);
foreach ($records as $k => $v )
{
if ($v["Field"]==$strFieldName)
{
return true;
}
}
return false;
}
function RowExists($strDatabase, $strTable, $strFieldName, $ID)
//Does this ID exist in this table in this field?
{
$sql=conDB();
$strSQL="SELECT " . $strFieldName . " FROM " . $strDatabase . "." . $strTable . " WHERE " . $strFieldName . "='" . $ID . "'";
$records = $sql->query($strSQL);
if (count($records)>0)
{
return true;
}
return false;
}
function GetFieldType($strDatabase, $strTable, $strFieldName)
//Give me the type of a column
{
$records=DBExplain($strDatabase, $strTable);
foreach ($records as $k => $v )
{
if ( $v["Field"]==$strFieldName)
{
return $v["Type"];
}
}
}
function DBExplain($strDatabase, $strTable, $bwlFollowRelations=false)
//explains the columns across several tables linked by relations in the relation table or do a simple explain
{
$sql=conDB();
$arrOut=Array();
if($bwlFollowRelations)
{
$strSQL="SELECT * FROM " . $strDatabase . "." . tfpre . "relation WHERE relation_type_id=0 AND table_name='" . $strTable . "'";
$records = $sql->query($strSQL);
foreach($records as $record)
{
$strThisTable=$record["f_table_name"];
$trecords = $sql->query("EXPLAIN " . $strDatabase . "." . $strThisTable);
$arrOut=array_merge($arrOut, $trecords);
}
}
$records = $sql->query("EXPLAIN " . $strDatabase . "." . $strTable);
$arrOut=array_merge($arrOut, $records);
return $arrOut;
}
function GetFieldTypeArray($strDatabase, $strTable)
//Give me the types of a columns for a table as an array.
{
$arrOut=Array();
$records=DBExplain($strDatabase, $strTable);
foreach ($records as $k => $v )
{
$arrOut[$v["Field"]]= $v["Type"];
}
return $arrOut;
}
function generateFieldTypeArray($strDatabase, $strTable)
//Returns an associative array keyed to the names of columns containing types.
//nov 2006
{
$arrFieldType=array();
$descr=DBExplain($strDatabase, $strTable);
foreach ($descr as $nom=>$info)
{
$strName=$info["Field"];
$strType=TypeParse($info["Type"], 0);
$arrFieldType[$strName]=$strType;
}
return $arrFieldType;
}
function countforeignkeycolumns($strDatabase, $strTable, $strMappedTableToAvoid)
//For counting all the foreign keys except to the one to avoid
//Useful for seeing whether it's best to not treat a mapping table as such
{
$sql=conDB();
$strSQL="SELECT COUNT(*) as 'table_count' FROM " . $strDatabase . "." . tfpre . "relation WHERE table_name = '" . $strTable . "' AND relation_type_id=0";
$records = $sql->query($strSQL);
$record=$records[0];
return $record["table_count"];
}
function nonuseridnonPKIDcolumn($strDatabase, $strTable)
//Return the first int column that isn't userid or PK.
{
$records=DBExplain($strDatabase, $strTable);
foreach ($records as $k => $v )
{
if ($v["Key"]!="PRI" && !contains($v["Field"],"user_id") && (beginswith($v["Type"], "int")))
{
return $v["Field"];
}
}
return false;
}
function SetChanged($strDatabase)
{
$sql=conDB();
$tables=TableList($strDatabase);
$strFieldName="Tables_in_" . str_replace("`", "", $strDatabase);
$strSQL="INSERT INTO " . $strDatabase . "." . tfpre . "dbdiff(diff_performed) VALUES('" . DateTimeForMySQL(date("F j Y g:i a")) . "')";
$rs = $sql->query($strSQL);
$id=mysql_insert_id();
foreach ($tables as $k=>$v )
{
$tablename=$v[$strFieldName];
$count = countrecords($strDatabase , $tablename );
$checksum=tablechecksum($strDatabase , $tablename );
$highestpk=highestprimarykey($strDatabase, $tablename);
$strSQL="INSERT INTO " . $strDatabase . "." . tfpre . "dbdiff_table(dbdiff_id, table_name, table_rowcount, table_checksum, max_id) VALUES('" . $id . "','" . $tablename . "','" . $count . "','" . $checksum . "','" . $highestpk . "')";
$rs = $sql->query($strSQL);
//echo $strSQL . " " . sql_error() . "