<?php
/**
 * This object handles all database connections, and queries of the coppermine database
 * @package cpmfetch
 * @version $Revision: 1.9 $
 *
 * Release Version: 2.0.0 
 *
 * This program is free software; you can redistribute it and/or modify      
 * it under the terms of the GNU General Public License as published by      
 * the Free Software Foundation; either version 2 of the License, or         
 * (at your option) any later version.                                       
 *  
 */
  
 /**
  * This object handles all database transactions with the backend
  *
  *
  * @package cpmfetch
  */
class cpm_dao {

	/** @access private */
	var $VERSION = "2.0.0";

	/** @access private */
	var $dbconnection = "";

	/** @access private */
	var $cfCfg;

	/** @access private */
	var $cfDefaultComments;

	/** @access private */
	var $lastSQLRowsReturned = "";

	/** @access private */
	var $lastSQLErrorMessage = "";

	/** @access private */
	var $privacyfilter = "";

	/** @access private */
	var $filetypefilter = "";

	/** @access private */
	var $sqlSelect = "";

	/** @access private */
	var $sqlTableSelect = "";

	/** @access private */
	var $sqlUserDataLink = "";

	/** @access private */
	var $sqlPostSelect = "";

	//var $sqlPostSelect = " SQL_NO_CACHE ";

// Initializes the object

/**
*
* @access private
*/
function cpm_dao($config_file = "") {

	if ($config_file == "") {
		if (file_exists("cpmfetch_config.php")) {
			require("cpmfetch_config.php");
		}
		else
		{
			print "Error:  config file not specified and default not found - did you run the install program? ";
			exit;
		}
	}	elseif (file_exists($config_file)) {

		require($config_file);

		//Todo: Add in elsif to look for default config file in directory passed

	} else {
			print "Error:  config file $config_file specified but was not found.";
			exit;
	}

	if ($CONFIG_WRITTEN_VERSION == "INSTALL") {
		print "Error: You need to run the install.php file";
		exit;
	}

	// Load config settings
	$this->cfg = array_merge(
		$config_cpgSettings,
		$config_cpmfetchSettings,
		$config_overrides,
		$config_userDefined
	);

	$this->cfg['cfFilesystemPathToAlbums'] = $this->cfg['filesystem_path_to_cpg'] . "/" . $this->cfg['fullpath'];

	if ($this->cfg['cfDebugMode'] == 'true') $this->debugPrint("cpm_dao.  Setting cfFilesystemPathToAlbums  to " . $this->cfg['cfFilesystemPathToAlbums']);	


	if ($this->cfg['cfBridgedTo'] == 'false') {

		$this->sqlTableSelect = " "
				. $this->cfg['table_prefix'] . "pictures AS p "
				. "LEFT JOIN " . $this->cfg['cfSQLUserTableName'] . " AS u ON p.owner_id = u.user_id "
				. "LEFT JOIN " . $this->cfg['table_prefix'] . "albums AS a ON p.aid = a.aid "
				. "LEFT JOIN " . $this->cfg['table_prefix'] . "categories AS c ON a.category = c.cid ";

		$this->sqlSelect = $this->cfg['cfSQLPictureSelect'] . ', '
				. $this->cfg['cfSQLUserSelect'] . ', '
				. $this->cfg['cfSQLAlbumSelect'];

		$this->sqlUserDataLink = $this->cfg['cfSQLUserDataLink'];

	// Individual bridges will be configured in here, with the following being the default
	} else {

		// The Generic bridge solution, eliminate all user table information
		$this->sqlTableSelect = " "
				. $this->cfg['table_prefix'] . "pictures AS p " 
				. "LEFT JOIN " . $this->cfg['table_prefix'] . "albums AS a ON p.aid = a.aid " 
				. "LEFT JOIN ". $this->cfg['table_prefix'] . "categories AS c ON a.category = c.cid ";

				$this->sqlSelect = $this->cfg['cfSQLPictureSelect'] . ', '
				. $this->cfg['cfSQLAlbumSelect'];


		$this->sqlUserDataLink = "";

	} //End 	if ($this->cfg['cfBridgedTo'] == 'false') {

	$this->privacyfilter = $this->cfg['cfShowPrivateOffSqlDefault'];

}
	 // Cleans up the object when we are done

/**
*
* @access private
*/
function destroy ( ) {
	$this->dbDisconnect();	 
}

/**
* Limits what types of media can be selected by this program
*
* Allows you to specify a list of extensions that are allowable for displaying.  Types not
* explicity identified are omitted from results.  The format for submitting file types is an array
* of extensions.  such as array(".jpg",".avi").  There is a limit as matches will be made against 
* the lower case and upper case versions of the types.  If you have only one type, you may specifiy
* it as a string instead of an array.
*
* @param mixed $filter - either a string of one extension or an array of several extensions
* @access public
*/
function cpm_setFilter($filter="") {
	if ($filter == "") {
		$this->cfg['cfFileTypeFilter'] = "";
		if ($this->cfg['cfDebugMode'] == 'true') $this->debugPrint("cpm_setFilter cleared filter setting");
	}		
	else 
	{
		if (! is_array($filter)) {
			$filter = array($filter);
		}

		$filtertemp = " AND (";
		foreach ($filter as $type) {
			$filtertemp .= " p.filename like '%" . strtolower($type) . "'";
			$filtertemp .= " OR p.filename like '%" . strtoupper($type) . "'";
			$filtertemp .= " OR ";
		}

		$filtertemp = substr($filtertemp,0, strlen($this->$filtertemp) - 4);
		$filtertemp .= ') ';

		$this->cfg['cfFileTypeFilter'] = $filtertemp;
		if ($this->cfg['cfDebugMode'] == 'true') $this->debugPrint("cpm_setFilter changed to " . $filtertemp);
	}

}


/** 
* Toggles cpmFetch into a debug mode (default: returns setting)
*
* Actives some extra output for troubleshooting.  Debug data is output as HTML comments or blockquotes
*
* @param $bool true or false or blank.  Do not enclose in quotes.	
* @access public
* @since 1.1.1
*/
function cpm_debugMode ($bool = "") {
			
		if (is_bool($bool) && $bool) {
				$this->cfg['cfDebugMode'] = 'true';
		}
		elseif (is_bool($bool) && ! $bool) {
				$this->cfg['cfDebugMode'] = 'false';
		}
		elseif (! is_bool($bool) && strtolower($bool) == "true") {
				$this->cfg['cfDebugMode'] = 'true';
		}
		elseif (! is_bool($bool) && strtolower($bool) == "false") {
				$this->cfg['cfDebugMode'] = 'false';
		}
		
		if ($this->cfg['cfDebugMode'] == 'true' && $bool != "")$this->debugPrint("cpm_setDebugMode called.  cfDegbugMode set to  " . $bool);
		
		return ($this->cfg['cfDebugMode']);
				
}

/**
*
* @access private
*/
function debugPrint( ) {

}


/**
* Toggles access to non-public photos (default: false)
*
* Allows images not publically available to be selected and displayed until it is
* turned off, or the object is recreated.  This program makes no distinction beyond if
* a media item is public or not.
*
* @param $bool true or fale.  True unlocks access to private media
* @access public
* @since Version 0.7
*/
function cpm_unlock_private ($bool="") {

	if ($bool != "" && $bool == true) {
		$this->cfg['cfShowPrivate'] = $bool;
		$this->privacyfilter = $this->cfg['cfShowPrivateOnSqlDefault'];
		if ($this->cfg['cfDebugMode'] === true) $this->debugPrint("cpm_unlock_private:  Setting cfShowPrivate to  " . $bool);
	}
	elseif ($bool != "" && $bool == false) {
		$this->cfg['cfShowPrivate'] = $bool;
		$this->privacyfilter = $this->cfg['cfShowPrivateOffSqlDefault'];
		if ($this->cfg['cfDebugMode'] === true)$this->debugPrint("cpm_unlock_private:  Setting cfShowPrivate to  " . $bool);
	}

	return ($this->cfg['cfShowPrivate']);
}

/**
* Allows you to change the default media prefixes  settings for large are now ignored since cpg does not support it
* @param $string thumbnail size prefix
* @param $string Normal / Intermediate size prefix
* @param $string Large sized (original) photo prefix (optional but ignored)
* @access private
*/
function cpm_setMediaPrefixes( $_thumb, $_intermediate, $_large = "") {
	$this->cfg['thumb_pfx'] = $_thumb;
	$this->cfg['normal_pfx'] = $_intermediate;
}


/**
* Sets the format as seen in the php DATE function to be used in rendering dates
*
* Sets the format as seen in the php DATE function to be used in rendering dates.  
* For more information on the kinds of date strings you can use check
* {@link http://www.php.net/manual/en/function.date.php}
*
* @param string $_format - set to a valid date format string
* @access public
*/
function cpm_setDateFormat ($_format = "") {
		if ($_format == "") {
		$this->cfg['cfDateFormatString'] = $this->cfg['cfDefaultDateFormatString'];
	} else {
		$this->cfg['cfDateFormatString'] = $_format;
	}
}


/**
* Returns a named config variable.  
* This will return anything in the cpg settings table with the exception of
* those deemed a security risk (dbname, dbpass, bridge info, etc...)
*
* @param string $_keyName - name of variable to return
* @access private
*/
function cpm_getConfigEntry($_keyName) {
	$retval = false;

	switch (strtolower($_keyName)) {
		case('dbuser'):
		case('dbpass'):
		case('dbname'):
		case('dbserver'):
		case('login_threshold');
		case('login_expiry');
		case('admin_activation');
		case('bridge_db_database_name');
		case('bridge_db_hostname');
		case('bridge_db_username');
		case('bridge_db_password');
			print "Access for {$_keyName} not allowed";
			exit;
		default:
			if (array_key_exists($_keyName,$this->cfg)) {
				$retval = $this->cfg[$_keyName];
			}
		}

	return ($retval);
}


/**
*
* @access private
*/
function getMediaCount ( ) {

	$sqlcode = "SELECT {$this->sqlPostSelect} COUNT(*) as media_total FROM " . $this->cfg['table_prefix'] . "pictures AS p "
			. " LEFT JOIN " . $this->cfg['table_prefix'] . "albums AS a ON p.aid = a.aid " 
			. " WHERE 1 "
			. $this->filetypefilter
			. " AND p.approved='YES' " .  $this->privacyfilter;

	$resultset = $this->dbExecuteSql($sqlcode);
	
	return ($resultset[0]['media_total']);
}


/**
*
* @access private
*/
function getMediaCountFrom ($source) {
	$retval = "";

	$sourceSql = $this->makeSourceSql($source);
	if ($sourceSql != "") $sourceSql = " AND " . $sourceSql;

	$sqlcode = "SELECT {$this->sqlPostSelect} COUNT(*) as media_total FROM  "
		. $this->cfg['table_prefix'] . "pictures AS p "
		. "LEFT JOIN " . $this->cfg['table_prefix'] . "albums AS a ON p.aid = a.aid "
		. "WHERE 1 "
		. $this->filetypefilter
		. " AND p.approved='YES' "
		. $sourceSql . " {$this->privacyfilter} ";

	$resultset = $this->dbExecuteSql($sqlcode);
	return ($resultset[0]['media_total']);
	
}

/**
*
* @deprecated since version 2.0, to be removed in version 4.0
* @access private
*/
function getMediaCountForAlbum( $albumid ) {
	$retval = "";
	if (is_numeric($albumid)) {

		$sqlcode = "SELECT {$this->sqlPostSelect} COUNT(*) as media_total FROM "
			. $this->cfg['table_prefix'] . "pictures AS p "
			. "LEFT JOIN " . $this->cfg['table_prefix'] . "albums AS a ON  p.aid = a.aid "
			. "WHERE  p.aid={$albumid} "
			. $this->filetypefilter
			. " AND p.approved='YES' "
			. $this->privacyfilter;

		$resultset = $this->dbExecuteSql($sqlcode);
		$retval = $resultset[0]['media_total'];
	}

	return ($retval);
}

/**
*
* @access private
*/
function getMediaCountAddedSince ($timestamp) {
	$retval = "";
	if (is_numeric($timestamp)) {

		$sqlcode = "SELECT {$this->sqlPostSelect} COUNT(*) as media_total FROM "
			. $this->cfg['table_prefix'] . "pictures AS p "
			. "LEFT JOIN " . $this->cfg['table_prefix'] . "albums AS a ON p.aid = a.aid " 
			. "WHERE 1 "
			. $this->filetypefilter
			. " AND ctime > " . $timestamp
			. " AND p.approved='YES' "
			.  $this->privacyfilter;

		$resultset = $this->dbExecuteSql($sqlcode);
		$retval = $resultset[0]['media_total'];
	}
	return ($retval);
}

/**
* Returns the number of albums in the database.
* @access public
*/
function getAlbumCount( ) {
	$sqlcode = "SELECT {$this->sqlPostSelect} COUNT(*) as media_total FROM "
		. $this->cfg['table_prefix']
		. "albums AS a";

	if ($this->privacyfilter != "") {
		$sqlcode .= " WHERE a.visibility = 0" ;
	}

	$resultset = $this->dbExecuteSql($sqlcode);
	return ($resultset[0]['media_total']);
}


/**
* Returns the number of comments in the CPG database
* @access public
*/
function getCommentCount( ) {
	$sqlcode = "SELECT {$this->sqlPostSelect} count(*) as media_total FROM "
		. $this->cfg['table_prefix']
		. "comments AS c";

	$resultset = $this->dbExecuteSql($sqlcode);
	return ($resultset[0]['media_total']);
}

/**
* Returns the total views across the entire CPG database
* @access public
*/
function getViewcount( ) {

	$sqlcode = "SELECT {$this->sqlPostSelect} sum(p.hits) as media_total FROM "
		. $this->cfg['table_prefix'] . "pictures AS p "
		. "LEFT JOIN " . $this->cfg['table_prefix'] . "albums AS a ON  p.aid = a.aid "
		. "WHERE 1 "
		. $this->filetypefilter
		. " AND p.approved='YES' "
		. $this->privacyfilter;

	$resultset = $this->dbExecuteSql($sqlcode);
	return ($resultset[0]['media_total']);
}


/**
* Returns the number of categories in the CPG database
* @access public
*/
function getCategoryCount( ) {
	$sqlcode = "SELECT {$this->sqlPostSelect} count(*) as media_total FROM "
		. $this->cfg['table_prefix']
		. "categories AS c";

	$resultset = $this->dbExecuteSql($sqlcode);
	return ($resultset[0]['media_total']);
	
}


// END OF STATISTICAL SECTION

/**
*
* @access private
*/
function getMediaByPid ($pid) {
	$resultset = array();
	if (is_numeric($pid)) {
		$sqlcode = "SELECT {$this->sqlPostSelect} " . $this->sqlSelect . " FROM "
			. $this->cfg['table_prefix'] . "pictures AS p "
			. "LEFT JOIN " . $this->cfg['table_prefix'] . "albums AS a ON  p.aid = a.aid "
			. "LEFT JOIN " . $this->cfg['table_prefix'] . "categories AS c ON a.category = c.cid, "
			. $this->cfg['table_prefix'] . "users AS u "
			. "WHERE p.pid = {$pid} "
			. $this->sqlUserDataLink
			. $this->filetypefilter ." "
			. $this->privacyfilter . " AND p.approved='YES' ";

		$resultset = $this->dbExecuteSql($sqlcode);
		$this->addPathInfo($resultset);
	}

	return($resultset);

}

/**
*
* @access private
*/
function getAlbumListFrom ($source) {
	$resultset = array();
	$sourceSql = $this->makeSourceSql($source);

	if ($sourceSql != "") $sourceSql = " AND " . $sourceSql;
		
	$sqlcode = "SELECT {$this->sqlPostSelect} " . $this->sqlSelect . " FROM "
			. $this->sqlTableSelect
			. " WHERE 1 "
			. $this->sqlUserDataLink 
			. $this->filetypefilter ." AND p.approved='YES' "
			. $sourceSql . " {$this->privacyfilter} "
			. " GROUP BY a.aid ORDER BY a.aid DESC";

	$resultset = $this->dbExecuteSql($sqlcode);
	$this->addPathInfo($resultset);

	return($resultset);

}




/**
*
* @access private
* @todo Source does not work on this call?
*/
function getCategoryListFrom($source="") {
	$resultset = array();

	$sourceSql = $this->makeSourceSql($source);
	if ($sourceSql != "") $sourceSql = " AND " . $sourceSql;

	$sqlcode = "SELECT {$this->sqlPostSelect} " . $this->sqlSelect . " FROM "
	. "{$this->cfg['table_prefix']}categories as c "
	. "LEFT JOIN {$this->cfg['table_prefix']}albums as a ON c.cid = a.category "
	. "LEFT JOIN {$this->cfg['cfSQLUserTableName']} AS u ON c.owner_id = u.user_id "
	. "LEFT JOIN {$this->cfg['table_prefix']}pictures AS p ON a.thumb = p.pid "
	. "WHERE 1 "
	. $sourceSql . " {$this->privacyfilter} "
	. "order by c.parent, c.pos, a.pos";

	$resultset = $this->dbExecuteSql($sqlcode);
	$this->addPathInfo($resultset);
	return($resultset);

}


/**
*
* @access private
*/
function getTopRatedMediaFrom ($source, $count = 1) {
	$resultset = array();
	if (is_numeric($count)) {

		$sourceSql = $this->makeSourceSql($source);

		if ($sourceSql != "") $sourceSql = " AND " . $sourceSql;

		$sqlcode = "SELECT {$this->sqlPostSelect} " . $this->sqlSelect . " FROM "
			. $this->sqlTableSelect
			. " WHERE 1 "
			. $this->sqlUserDataLink 
			. $this->filetypefilter ." AND p.approved='YES' "
			. $sourceSql . " {$this->privacyfilter} "
			. " ORDER BY p.pic_rating DESC LIMIT 0,$count";

			$resultset = $this->dbExecuteSql($sqlcode);
			$this->addPathInfo($resultset);
	}
	elseif ($this->cfg['cfDebugMode'] == 'true'){
		debugPrint("Non numeric count submitted");
	}

	return ($resultset);
}

/**
*
* @access private
*/
function getMostVotedMediaFrom ($source, $count = 1) { 
	$resultset = array();
	if (is_numeric($count)) {

		$sourceSql = $this->makeSourceSql($source);

		if ($sourceSql != "") $sourceSql = " AND " . $sourceSql;

		$sqlcode = "SELECT {$this->sqlPostSelect} " . $this->sqlSelect . " FROM "
			. $this->sqlTableSelect
			. " WHERE 1 "
			. $this->sqlUserDataLink
			. $this->filetypefilter
			. " AND p.approved='YES' "
			. $sourceSql
			. " {$this->privacyfilter} "
			. " ORDER BY p.votes DESC LIMIT 0,$count";

			$resultset = $this->dbExecuteSql($sqlcode);
			$this->addPathInfo($resultset);
	}
	elseif ($this->cfg['cfDebugMode'] == 'true'){
		debugPrint("Non numeric count submitted");
	}

	return ($resultset);
	
}

/**
*
* @access private
*/
function getRandomTopRatedMediaFrom ($source, $count = 1) {
		
	$results = array();

	if (is_numeric($count)) {

		$countForSource = $this->getMediaCountFrom ($source);

		if ($countForSource == 0) {
			$rangeLimit = 0;
		} else {
			$rangeLimit =round(($countForSource * ($this->cfg['cfTopPercentForTopRated'] / 100)),0);
		}
	
		if ($rangeLimit < $count) $rangeLimit = $count;
		
		$sourceSql = $this->makeSourceSql($source);

		if ($sourceSql != "") $sourceSql = " AND " . $sourceSql;			
								
		$sqlcode = "SELECT {$this->sqlPostSelect} " . $this->sqlSelect . " FROM "
			. $this->sqlTableSelect
			. " WHERE 1 "
			. $this->sqlUserDataLink
			. $this->filetypefilter
			. " AND p.approved='YES' "
			. $sourceSql
			. " {$this->privacyfilter} "
			. " ORDER BY p.pic_rating DESC LIMIT 0,$rangeLimit";

		$resultset = $this->dbExecuteSql($sqlcode);

		if (count($resultset) > 0) {
			if (count($resultset) < $count) $count = count($resultset);
			srand((float)$this->getRandomSeed());
			shuffle($resultset);
			for ($cnt = 0; $cnt < $count; $cnt++) {
				array_push($results,$resultset[$cnt]);
			}

			$resultset = "";	// Free up a large result array
			$this->addPathInfo($results);

		}
	}
	elseif ($this->cfg['cfDebugMode'] == 'true'){
			debugPrint("Non numeric count submitted");
	}

	return ($results);
}


/**
*
* @access private
*/
function getRandomMostViewedMediaFrom ($source, $count = 1) { 
	$results = array();

	if (is_numeric($count)) {

		$countForSource = $this->getMediaCountFrom ($source);
		if ($countForSource == 0) {
			$rangeLimit = 0;
		} else {
			$rangeLimit =round(($countForSource * ($this->cfg['cfTopPercentForTopRated'] / 100)),0);
		}

	if ($rangeLimit < $count) $rangeLimit = $count;
		$sourceSql = $this->makeSourceSql($source);

		if ($sourceSql != "") $sourceSql = " AND " . $sourceSql;

		$sqlcode = "SELECT {$this->sqlPostSelect} " . $this->sqlSelect . " FROM "
			. $this->sqlTableSelect
			. " WHERE 1 "
			. $this->sqlUserDataLink
			. $this->filetypefilter
			. " AND p.approved='YES' "
			. $sourceSql
			. " {$this->privacyfilter} "
			. " ORDER BY p.hits DESC LIMIT 0,$count";

		$resultset = $this->dbExecuteSql($sqlcode);

		if (count($resultset) > 0) {
			if (count($resultset) < $count) $count = count($resultset);
			srand((float)$this->getRandomSeed());
			shuffle($resultset);
			for ($cnt = 0; $cnt < $count; $cnt++) {
				array_push($results,$resultset[$cnt]);
			}

			$resultset = ""; //empty a large result set			
			$this->addPathInfo($results);

		}
	}
	elseif ($this->cfg['cfDebugMode'] == 'true'){
		debugPrint("Non numeric count submitted");
	}
	return ($results);
}

/**
*
* @access private
*/
function getLastAddedMediaFrom ($source, $count = 1) {
	$resultset = array();
	if (is_numeric($count)) {

		$sourceSql = $this->makeSourceSql($source);

		if ($sourceSql != "") $sourceSql = " AND " . $sourceSql;

		$sqlcode = "SELECT {$this->sqlPostSelect} " . $this->sqlSelect . " FROM "
			. $this->sqlTableSelect
			. " WHERE 1 "
			. $this->sqlUserDataLink
			. $this->filetypefilter
			. " AND p.approved='YES' "
			. $sourceSql
			. " {$this->privacyfilter} "
			. " ORDER BY p.ctime DESC LIMIT 0,$count";

		$resultset = $this->dbExecuteSql($sqlcode);
		$this->addPathInfo($resultset);

	}
	elseif ($this->cfg['cfDebugMode'] == 'true'){
		debugPrint("Non numeric count submitted");
	}

	return ($resultset);
}

/**
*
* @access private
*/
function getLastUpdatedAlbumsFrom ($source, $count = 1) {
	$resultset = array();
	if (is_numeric($count)) {

		$sourceSql = $this->makeSourceSql($source);

		if ($sourceSql != "") $sourceSql = " AND " . $sourceSql;

 		$sqlcode = "SELECT {$this->sqlPostSelect} " . $this->sqlSelect . " FROM "
 			. $this->sqlTableSelect ." LEFT JOIN "
			. $this->cfg['table_prefix'] . "pictures AS p2 ON p.aid = p2.aid and p.ctime < p2.ctime "
 			. " WHERE p2.pid is NULL "
 			. $this->sqlUserDataLink
 			. $this->filetypefilter
 			. " AND p.approved='YES' "
 			. $sourceSql
 			. " {$this->privacyfilter} "
			. " GROUP BY p.aid " 
			. " ORDER BY p.ctime DESC LIMIT 0,$count";

		$resultset = $this->dbExecuteSql($sqlcode);
		$this->addPathInfo($resultset);

	}
	elseif ($this->cfg['cfDebugMode'] == 'true'){
		debugPrint("Non numeric count submitted");
	}

	return ($resultset);
}



	
/**
* Returns a random image from a category in cpm
*
* @access private
*/
function getRandomImageFrom ($source, $count) {
	$resultset = array();

	if (is_numeric($count)) {

	$sourceSql = $this->makeSourceSql($source);
	
	if ($sourceSql != "") $sourceSql = " AND " . $sourceSql;

		$sqlcode = "SELECT {$this->sqlPostSelect} " . $this->sqlSelect . " FROM "
			. $this->sqlTableSelect
			. " WHERE 1 "
			. $this->sqlUserDataLink
			. " AND p.approved='YES' "
			. $this->filetypefilter . " "
			. $this->privacyfilter . $sourceSql
			. " ORDER BY rand(" .  $this->getRandomSeed()   . ") LIMIT $count";

		$resultset = $this->dbExecuteSql($sqlcode);
		$this->addPathInfo($resultset);

	} //end if
	elseif ($this->cfg['cfDebugMode'] == 'true'){
		debugPrint("Non numeric count submitted");
	}

	return($resultset);

} //end function

/**
*
* @access private
*/
function getLastImagesWithComments($limit) {
	$resultset = array();
	if (is_numeric($limit)) {
		$sqlcode = "SELECT {$this->sqlPostSelect} " . $this->sqlSelect
			. ", m.msg_body AS mMsg_body, m.msg_author AS mMsg_author "
			. " FROM "
			. $this->sqlTableSelect. ", "
			. $this->cfg['table_prefix'] . "comments AS m "
			. " WHERE m.pid = p.pid "
			. $this->sqlUserDataLink
			. $this->filetypefilter
			. " AND p.approved='YES' {$this->privacyfilter}"
			. " ORDER BY m.msg_date DESC LIMIT 0,$limit";

		$resultset = $this->dbExecuteSql($sqlcode);
		$this->addPathInfo($resultset);
	}

	return ($resultset);

}


/**
* Returns a report of media added since a timestamp
*
* @access private
*/
function getMediaAddedToCategoriesSince ($timestamp) {
	$resultset = array();

	if (is_numeric($timestamp)) {
		$sqlcode = "SELECT {$this->sqlPostSelect} " . $this->sqlSelect
			. ', c.name AS cName, c.cid AS cCid, count( p.pid ) AS count '
			. ' FROM '
			 . $this->sqlTableSelect
			. " WHERE 1 "
			. $this->sqlUserDataLink
			. " AND p.approved='YES' {$this->privacyfilter} AND p.ctime > " . $timestamp
			. ' GROUP BY a.category'
			. ' ORDER BY c.name, p.mtime';

		$resultset = $this->dbExecuteSql($sqlcode);
		$this->addPathInfo($resultset);
	}

	return($resultset);
}
				

/**
* Returns a report of media added since a timestamp
*
* @access private
*/
function getMediaAddedSince ($timestamp) {
	$resultset = array();

	if (is_numeric($timestamp)) {
		$sqlcode = "SELECT {$this->sqlPostSelect} " . $this->sqlSelect
			. ', c.name AS cName, count( p.pid ) AS count '
			. ' FROM '
			. $this->sqlTableSelect
			. " WHERE a.category = c.cid "
			. $this->sqlUserDataLink
			. " AND p.approved='YES' {$this->privacyfilter} AND p.ctime > " . $timestamp
			. ' GROUP BY a.category, a.aid'
			. ' ORDER BY c.name, p.mtime';

		$resultset = $this->dbExecuteSql($sqlcode);
		$this->addPathInfo($resultset);
	}

	return($resultset);
}
	
	
/**
* Provides shortcuts into different function that return data
*
* The format is specified by placeholders indicated by percent signs '%'.
* If you actually want a percent sign
* you will need to put two percent signs in a row '%%'.  
* The most up to date list for supported placeholders
* can be found in the coppermine_dao formatStats function.  But the main ones are:
* <ul><li>%f - file count</li>
* <li>%a - album count</li>
* <li>%c - category count</li>
* <li>%v - view count</li>
* <li>%n - comment count (note count)</li></ul>
*
* @access public
*/
function formatStats ($format) {
	$output = "";
	$curpos = 0;
	$nextfind = 0;
	$lastpos = strlen($format);

	while ($curpos <= $lastpos) {
		$nextfind = strpos($format,'%',$curpos);

		if (false === $nextfind) {
			$output .= substr($format,$curpos);
			break;
		}

		$output .= substr($format,$curpos, ($nextfind - $curpos));
		$curpos = $nextfind + 1;

		switch ($format[$curpos]) {
			case ('f'):
				$output .= $this->getMediaCount();
				break;
			case ('a'):
				$output .= $this->getAlbumCount();
				break;
			case ('c'):
				$output .= $this->getCategoryCount();
				break;
			case ('v'):
				$output .= $this->getViewCount();
				break;
			case ('n'):
				$output .= $this->getCommentCount();
				break;
			case ('%'):
				$output .= '%';
				break;
			default:
				$output .= $format[$curpos];
		}
		$curpos++;
	}
	return ($output);
}


// ********************************************************************************
// DATABASE RELATED FUNCTIONS
// ********************************************************************************

/**
*
* @access private
*/
function makeSourceSql ($source) {

	if ($source == "") return ("");

	$sourceSql = " (";

	$source=strtolower($source);

	$albumlist = array();
	$categorylist = array();
	$ownerlist = array();
	$keywordlist = array();
	$textlist = array();

	$parts = explode(':',$source);

	foreach ($parts as $thispart) {
		$sections = explode('=',$thispart);

		if ("album" == $sections[0]) {
			$albumlist = explode(',',$sections[1]);
		}
		elseif ("cat" == $sections[0]) {
			$categorylist = explode(',',$sections[1]);
		}
		elseif("owner" == $sections[0]) {
			$ownerlist = explode(',',$sections[1]);
		}
		elseif("text" == $sections[0]) {
			$textlist = explode(',',$sections[1]);
		}	
		elseif("keyword" == $sections[0]) {
			$keywordlist = explode(',',$sections[1]);
		}

	} // end foreach

	if (sizeof($albumlist)) {
		foreach ($albumlist as $aid) {
			if (is_numeric($aid)) {
				$sourceSql .= " p.aid=$aid OR ";
			}
		}
	}

	if (sizeof($categorylist)) {
		foreach($categorylist as $cid) {

			if (is_numeric($cid)) {
				if ("1" == $cid) {
					$sourceSql .= " a.category > 10000 OR ";
				}else {
					$sourceSql .= " a.category=$cid OR ";
				}
			}
		}
	}


	if (' OR ' == substr($sourceSql,-4)) {
			$sourceSql = substr($sourceSql,0,-3);
			$sourceSql .= ") ";
	}


	if (sizeof($ownerlist)) {
		if ($sourceSql != " (") {
			$sourceSql .= ' AND ( ';
		}

		foreach ($ownerlist as $ownername) {
				$sourceSql .= " p.owner_name='" . mysql_escape_string($ownername) . "' OR ";
		}

		$sourceSql = substr($sourceSql,0,-3);
		$sourceSql .= ") ";

	}


    if (sizeof($textlist) || sizeof($keywordlist)) {

		if ($sourceSql != " (") {
			$sourceSql .= ' AND ( ';
		}

		if (sizeof($textlist)) {
			foreach ($textlist as $keyword) {
					$sourceSql .= " p.keywords LIKE '%" . mysql_escape_string($keyword) . "%' OR ";
					$sourceSql .= " p.title LIKE '%" . mysql_escape_string($keyword) . "%' OR ";
					$sourceSql .= " p.caption LIKE '%" . mysql_escape_string($keyword) . "%' OR ";
			}
		}

		if (sizeof($keywordlist)) {
			foreach ($keywordlist as $keyword) {
				if (! in_array($keyword,$textlist)) {
					$sourceSql .= " p.keywords LIKE '%" . mysql_escape_string($keyword) . "%' OR ";
				}
			}
		}

		if (' OR ' == substr($sourceSql,-4)) {
				$sourceSql = substr($sourceSql,0,-3);
		}

		$sourceSql .= ' ) ';

	} else {

		if (' OR ' == substr($sourceSql,-4)) {
				$sourceSql = substr($sourceSql,0,-3);
		}

	}

	//$sourceSql .= ") ";

	if (" (" == $sourceSql) $sourceSql = "";

	return ($sourceSql);

}


/*  Press messing with keyword functions
function makeSourceSql ($source) {

	if ($source == "") return ("");

	$sourceSql = " (";

	$source=strtolower($source);

	$albumlist = array();
	$categorylist = array();
	$ownerlist = array();

	$parts = explode(':',$source);

	foreach ($parts as $thispart) {
		$sections = explode('=',$thispart);

		if ("album" == $sections[0]) {
			$albumlist = explode(',',$sections[1]);
		}
		elseif ("cat" == $sections[0]) {
			$categorylist = explode(',',$sections[1]);
		}
		elseif("owner" == $sections[0]) {
			$ownerlist = explode(',',$sections[1]);
		}
	} // end foreach

	if (sizeof($albumlist)) {
		foreach ($albumlist as $aid) {
			if (is_numeric($aid)) {
				$sourceSql .= " p.aid=$aid OR ";
			}
		}
	}

	if (sizeof($categorylist)) {
		foreach($categorylist as $cid) {

			if (is_numeric($cid)) {
				if ("1" == $cid) {
					$sourceSql .= " a.category > 10000 OR ";
				}else {
					$sourceSql .= " a.category=$cid OR ";
				}
			}
		}
	}

	if (sizeof($ownerlist)) {
		foreach ($ownerlist as $ownername) {
			//if (is_numeric($aid)) {
				$sourceSql .= " p.owner_name='" . mysql_escape_string($ownername) . "' OR ";
			//}
		}
	}

	if (' OR ' == substr($sourceSql,-4)) {
			$sourceSql = substr($sourceSql,0,-3);
	}

	$sourceSql .= ") ";

	if (" () " == $sourceSql) $sourceSql = "";

	return ($sourceSql);

}*/


/**
* Creates a connection to the gallery database
*
* If 
*
* @access private
*/
function dbConnect ( ) {
	if ($this->dbconnection == "") {

		if (version_compare(phpversion(), "4.2.0", ">=") &&
				strtolower($this->cfg['cfUseExistingDBConnection']) != "true") {
			$this->dbconnection = mysql_connect($this->cfg['dbserver'], $this->cfg['dbuser'], $this->cfg['dbpass'], true);
		} else {
			$this->dbconnection = mysql_connect($this->cfg['dbserver'], $this->cfg['dbuser'], $this->cfg['dbpass']);
		}


		// Add in check to make sure there is a connection
		// Add in check to see if this call succeeded
		mysql_select_db($this->cfg['dbname'], $this->dbconnection);

		//Why is this like this?
		//$this->debugPrint(mysql_error($this->dbconnection));
	}
}

/**
* Calls a mysql_close on the current db connection.
*
* This will close the db connection, unless you are running PHP >= 4.2.0 and have
* CpmFetch configured to use an existing db connection (cfUseExistingDBConnection), in
* which case it will not close it at all.  
*
* @access private
*/
function dbDisconnect ( ) {
	if (strtolower($this->cfg['cfUseExistingDBConnection']) != "true") {

		if ($this->dbconnection) {
			mysql_close($this->dbconnection);
			//$this->debugPrint("Closing DB connection");
		}
	}
}

/**
*
* @access private
*/
function dbExecuteSql ($sqlcode, $convert = true) {
	$this->dbConnect();
	$this->lastSQLRowsReturned = 0;
	$this->lastSQLErrorMessage = "";
	$results = array();

	$resultset = mysql_query($sqlcode, $this->dbconnection);

	if (!$resultset) {
		print  mysql_error($this->dbconnection);
		print "<p>{$sqlcode}</p>";
		$this->lastSQLErrorMessage = mysql_error($this->dbconnection);
		$this->lastSQLRowsReturned = 0;
	}
	else
	{
		$this->lastSQLRowsReturned = mysql_num_rows($resultset);
		$this->lastSQLErrorMessage = "";
	}

	if ($this->cfg['cfDebugMode'] == 'true'){
		$debuginfo =  "SQL : $sqlcode\n";
		$debuginfo .=  "ROWS: {$this->lastSQLRowsReturned}\n";
		$this->debugPrint($debuginfo);
	}

	while ($row = mysql_fetch_assoc($resultset)) {
		array_push ($results,$row);
	}
	
	mysql_free_result($resultset);

	return ($results);
}

/**
* Take an array of rows and add in tags for thumbnail, normal and large image paths
*
* @access private
*/
function addPathInfo(&$data) {

	if (is_array($data) && count($data) > 0 && array_key_exists('pFilename',$data[0])) {
		foreach ($data as $key => $row) {
			//print "$key ";
 			$data[$key]['fullPathToThumb']  = $this->getImageToUse($row['pFilepath'], $row['pFilename'] ,$this->cfg['thumb_pfx']);
 			$data[$key]['fullPathToNormal'] =  $this->getImageToUse($row['pFilepath'], $row['pFilename'] ,$this->cfg['normal_pfx']);
 			$data[$key]['fullPathToFull']   = $this->getImageToUse($row['pFilepath'], $row['pFilename'] ,"");
		}
	}

	return;
}



/** 
* The following methods are not data access per say, but do provide data back
* independing of formatting, and I did not want to include another file...
*
* @access private
*/	
function getImageToUse($filepath,$filename, $fileprefix) {

		$imagetoshow = '';
		$extension = strtolower(substr($filename,strrpos($filename,'.')));

		if ($extension == '.jpg' || $extension == '.jpeg' || $extension == '.gif' || $extension == '.png' || $extension == '.bmp' ) {
			//code added to upgrade or downgrade a size if int or large not present

			if (file_exists($this->cfg['cfFilesystemPathToAlbums'] . $filepath . $fileprefix . $filename)) {
				$imagetoshow = $this->cfg['fullpath'] .  $filepath . $fileprefix . $filename;
			}
			elseif ($fileprefix == $this->cfg['normal_pfx']) {
				$imagetoshow = $this->cfg['fullpath'] . $filepath .  $this->cfg['normal_pfx'] . $filename;
			}
			elseif ($fileprefix == "") {
				$imagetoshow = $this->cfg['fullpath'] . $filepath .  $filename;
			}
			else {
				print "CF-Error <!-- GITU: Could not find any image to display: Extension (strtolower): $extension  File:" .  $this->cfg['cfFilesystemPathToAlbums'] .  $filepath . $fileprefix . $filename . "--> \n";
			}
		}
		// We are not going after a normal image file here, something special that needs to be handled differently
		else {
			$filetolookfor = substr($filename,0,strlen($filename) - strlen($extension));

			if (file_exists($this->cfg['cfFilesystemPathToAlbums'] .  $filepath . $fileprefix . $filetolookfor . '.jpg')) {
				$imagetoshow = $this->cfg['fullpath'] . $filepath . $fileprefix . $filetolookfor . '.jpg';
			}
			elseif (file_exists($this->cfg['cfFilesystemPathToAlbums'] .  $filepath . $fileprefix . $filetolookfor . '.gif')) {
				$imagetoshow = $this->cfg['fullpath'] . $filepath . $fileprefix . $filetolookfor . '.gif';
			}
			elseif ($fileprefix != $this->cfg['thumb_pfx'] && (file_exists($this->cfg['cfFilesystemPathToAlbums'] .  $filepath . $this->cfg['thumb_pfx'] . $filetolookfor . '.jpg'))) {
				$imagetoshow = $this->cfg['fullpath'] . $filepath . $this->cfg['thumb_pfx'] . $filetolookfor . '.jpg';
			}
			elseif ($fileprefix != $this->cfg['thumb_pfx'] && (file_exists($this->cfg['cfFilesystemPathToAlbums']  . $filepath . $this->cfg['thumb_pfx'] . $filetolookfor . '.gif'))) {
				$imagetoshow = $this->cfg['fullpath'] . $filepath . $this->cfg['thumb_pfx'] . $filetolookfor . '.gif';
			}
			// This means we are gonna use the representative image that came with CPG
			else {
				$imagetoshow = "images/" . $this->getdefaultimagename($extension);
			}
		}

		return ($imagetoshow);
}

/**
*
* @access private
*/
function urlEncodeImagePath($_name) {
		$newname = "";

		if ($_name != "") {
			$newname = rawurlencode($_name);
			$newname = str_replace("%2F","/",$newname);
		}

		return ($newname);
}

/**
*
* @access private
*/
function getdefaultimagename ($ext) {

	$ext = strtolower($ext);

	switch ($ext) {

		case ('.mp3'):
			$defImage='thumb_mp3.jpg';
			break;
		case ('.mpeg'):
			$defImage='thumb_mpeg.jpg';
			break;
		case ('.mpg'):
			$defImage='thumb_mpg.jpg';
			break;
		case ('.avi'):
			$defImage='thumb_avi.jpg';
			break;
		case ('.doc'):
			$defImage='thumb_doc.jpg';
			break;
		case ('.wmv'):
			$defImage='thumb_wmv.jpg';
			break;
		case ('.audio'):
			$defImage='thumb_audio.jpg';
			break;
		case ('.document'):
			$defImage='thumb_document.jpg';
			break;
		case ('.gz'):
			$defImage='thumb_gz.jpg';
			break;
		case ('.htm'):
			$defImage='thumb_htm.jpg';
			break;
		case ('.html'):
			$defImage='thumb_html.jpg';
			break;
		case ('.mid'):
			$defImage='thumb_mid.jpg';
			break;
		case ('.midi'):
			$defImage='thumb_midi.jpg';
			break;
		case ('.mov'):
			$defImage='thumb_mov.jpg';
			break;
		case ('.movie'):
			$defImage='thumb_movie.jpg';
			break;
		case ('.ogg'):
			$defImage='thumb_ogg.jpg';
			break;
		case ('.qtv'):
			$defImage='thumb_qtv.jpg';
			break;
		case ('.ra'):
			$defImage='thumb_ra.jpg';
			break;
		case ('.ram'):
			$defImage='thumb_ram.jpg';
			break;
		case ('.rar'):
			$defImage='thumb_rar.jpg';
			break;
		case ('.rm'):
			$defImage='thumb_rm.jpg';
			break;
		case ('.rmj'):
			$defImage='thumb_rmj.jpg';
			break;
		case ('.swf'):
			$defImage='thumb_swf.jpg';
			break;
		case ('.txt'):
			$defImage='thumb_txt.jpg';
			break;
		case ('.wav'):
			$defImage='thumb_wav.jpg';
			break;
		case ('.wma'):
			$defImage='thumb_wma.jpg';
			break;
		case ('.xls'):
			$defImage='thumb_xls.jpg';
			break;
		case ('.zip'):
			$defImage='thumb_zip.jpg';
			break;

		default:
			$defImage="";
	}

	return ($defImage);

}




/**
* Creates the href and img tags to be displayed
*
* @access private
*/
function createlink($filepath, $filename, $aid, $pos, $imagelink="int") {

	$link= $this->cfg['cpg_url'];
	if ($link == "") $link = "/";

	if ($imagelink == 'album' || $imagelink == 'thumb') {
		$link .= 'thumbnails.php?album=' . $aid;
	} elseif ($imagelink == 'int') {
		$link .= 'displayimage.php?pos=-' .	$pos;
	} elseif ($imagelink == 'large') {
		$link .= 'albums/' . $filepath . $filename;
	} elseif ($imagelink == 'none') {
		$link = '';
	} else {
		$link .=  'displayimage.php?pos=-' .	$pos;
	}

	return ($link);

} //end function

/**
*
* @access private
*/
function createDescription($format, &$row, $failOnMissing=false) {
	$output = "";
	$didIfail = false;
	//print "Format: $format<br>";

	if ($format != "" && ! (strpos($format,'{{') === false)) {
		//print "NewParam";
		$curpos = 0;
		$nextfind = 0;
		$lastpos = strlen($format);

		while ($curpos <= $lastpos) {
			$nextstart = strpos($format,'{{',$curpos);

			if (false === $nextstart) {
				$output .= substr($format,$curpos);
				break;
			}

			$nextend = strpos($format,'}}',$nextstart);

			if (false === $nextend) {
				$output .= substr($format,$curpos);
				break;
			}

			$tag = substr($format,$nextstart+2,$nextend - $nextstart - 2);

			$output .= substr($format,$curpos, ($nextstart - $curpos));
			$curpos = $nextend + 2;

			switch ($tag) {
				case ('pCtimeAgo'):
					$timediff = time() - $row['pCtime'];
					$output .= round($timediff / 86400, 0);
					break;
				case ('pFilesizeKB'):
					// Formatted as KBytes
					$output .= round($row['pFilesize'] / 1024,1);
					break;
				// Number of stars (Vote results)
				case ('pPic_RatingStars'):
					$output .= round($row['pPic_Rating'] / 2000,1);
					break;
				case ('pCtimeFormatted'):
					// Date formatted CTime
					$output .= date($this->cfg['cfDateFormatString'],$row['pCtime']);
					break;
				default:
					if (array_key_exists($tag,$row)) {
						$output .= $row[$tag];
					} else {
						$didIfail = true;
						$output .= $tag;
					}
			} // end switch
		} // end while

		//print $output;

	} else {
		$output = $format;
	} // End of check to see if there is content and new style params



	if ($format != "" && !(strpos($format,'%') === false)) {
		//print "Legacy $format $output";
		$output = $this->createOldFormatDescription($output,$row,$failOnMissing);

		if ($output === false) {
			$didIfail = true;
		}
	}

	if ($didIfail && $failOnMissing) {
		return (false);
	} else {
		//print "returning output $output";
		return $output;
	}

}


/**
*
* @access private
* @deprecated since version 2.0, will be removed in 4.0
*/
function createOldFormatDescription($format,$row, $failOnMissing=false) {
	$output = "";

	$didIfail = false;

	if ($this->cfg['cfDebugMode'] == 'true'){
		$debuginfo =  "DEPRECIATED: Avoid using % style option array calls.  Pls use {{ }} style {$format}";
		$this->debugPrint($debuginfo);
	}

	if ($format != "") {

		$curpos = 0;
		$nextfind = 0;
		$lastpos = strlen($format);

		while ($curpos <= $lastpos) {
			$nextfind = strpos($format,'%',$curpos);

			if (false === $nextfind) {
				$output .= substr($format,$curpos);
				break;
			}

			$output .= substr($format,$curpos, ($nextfind - $curpos));
			$curpos = $nextfind + 1;

			switch ($format[$curpos]) {

// These were remapped below to match the CPG1.4.x format of user_profile#
//	case ('H'): $output .= $row['uUser_website']; break;
//	case ('I'): $output .= $row['uUser_interest']; break;
//	case ('L'): $output .= $row['uUser_location']; break;
//	case ('O'): $output .= $row['uUser_occupation']; break;

				case ('a'): $output .= $row['aTitle']; 	if ("" == $row['aTitle']) $didIfail = true;
						break;
				case ('A'): (array_key_exists('mMsg_author',$row)) ? $output .= $row['mMsg_author']: $didIfail = true;
						break;
				case ('c'): $output .= $row['pCaption']; if ("" == $row['pCaption']) $didIfail = true;
						break;
				case ('C'): (array_key_exists('mMsg_body',$row)) ? $output .= $row['mMsg_body']: $didIfail = true;
						break;
				case ('d'): $output .= $row['aDescription'];	if ("" == $row['aDescription']) $didIfail = true;
						break;
				case ('D'): $timediff = time() - $row['pCtime']; 	$output .= round($timediff / 86400, 0);
						break;
				case ('e'): (array_key_exists('uUser_email',$row)) ? $output .= $row['uUser_email']: $didIfail = true;
						break;
				case ('f'): $output .= $row['pFilename']; if ("" == $row['pFilename']) $didIfail = true;
						break;
				case ('h'): (array_key_exists('pHits',$row)) ? $output .= $row['pHits']: $didIfail = true;
						break;
				case ('H'): (array_key_exists('uUser_profile3',$row)) ? $output .= $row['uUser_profile3']: $didIfail = true;
						break;
				case ('i'): (array_key_exists('pPid',$row)) ? $output .= $row['pPid']: $didIfail = true;
						break;
				case ('I'): (array_key_exists('uUser_profile2',$row)) ? $output .= $row['uUser_profile2']: $didIfail = true;
						break;
				case ('l'): (array_key_exists('uUser_lastvisit',$row)) ? $output .= $row['uUser_lastvisit']: $didIfail = true;
						break;
				case ('L'): (array_key_exists('uUser_profile1',$row)) ? $output .= $row['uUser_profile1'] : $didIfail = true;
						break;
				case ('o'): $output .= $row['pOwner_name']; if ("" == $row['pOwner_name']) $didIfail = true;
						break;
				case ('O'): (array_key_exists('uUser_profile4',$row)) ? $output .= $row['uUser_profile4']: $didIfail = true;
						break;
				case ('p'): $output .= $row['pFilepath']; if ("" == $row['pFilepath']) $didIfail = true;
						break;
				case ('r'): (array_key_exists('uUser_regdate',$row)) ? $output .= $row['uUser_regdate']: $didIfail = true;
						break;
				case ('s'): $output .= $row['pFilesize']; if ("" == $row['pFilesize']) $didIfail = true;
						break;
				case ('S'): $output .= round($row['pFilesize'] / 1024,1);
						break;
				case ('t'): $output .= $row['pTitle']; if ("" == $row['pTitle']) $didIfail = true;
						break;
				case ('v'): (array_key_exists('pVotes',$row)) ? $output .= $row['pVotes'] : $didIfail = true;
						break;
				case ('V'): $output .= round($row['pPic_Rating'] / 2000,1);
						break;
				case ('w'): (array_key_exists('uUser_website',$row)) ? $output .= date($this->cfg['cfDateFormatString'],$row['pCtime']) : $didIfail = true;
						break;
				case ('W'): (array_key_exists('pCtime',$row)) ?$output .= $row['pCtime']: $didIfail = true;
						break;
				case ('x'): (array_key_exists('pWidth',$row)) ?$output .= $row['pWidth']: $didIfail = true;
						break;
				case ('y'): (array_key_exists('pHeight',$row)) ?$output .= $row['pHeight']: $didIfail = true;
						break;
 				case ('1'): (array_key_exists('pUser1',$row)) ?$output .= $row['pUser1']: $didIfail = true;
						break;
				case ('2'): (array_key_exists('pUser2',$row)) ?$output .= $row['pUser2']: $didIfail = true;
						break;
				case ('3'): (array_key_exists('pUser3',$row)) ?$output .= $row['pUser3']: $didIfail = true;
						break;
				case ('4'): (array_key_exists('pUser4',$row)) ?$output .= $row['pUser4']: $didIfail = true;
						break;
				case ('%'): $output .= '%'; break;
				default:
					$output .= $format[$curpos];
			}

			$curpos++;

		} // End while

	}// End of check to see if there is content

	if ($didIfail && $failOnMissing) {
		return (false);
	} else {
		return $output;
	}
}

/**
*
* @access private
*/
function getRandomSeed() {
	return microtime()*1000000;
}

}  //END OF CLASS

?>
