<?php
if (!defined('IN_SAS'))
{
	die("Hacking attempt");
}

/*
** DGS Search
** utils.php written by James Sella and William Sella
** Copyright (c) 2000-2001 Digital Genesis Software, LLC. All Rights Reserved.
** Released under the GPL Version 2 License.
** http://www.digitalgenesis.com
** adapted to work with the language file from S@S, instead of the DGS SEARCH one's.
** fc.stuurman (fc.stuurman@hccnet.nl)
#$Id: utils.php,v 1.1 2006/10/03 08:54:49 fstuurman Exp $
*/

function getHtmlTitle($file)
{
	global $config;

	$warn = false;

	if ($warn)
	{
		$buffer = file($file); //Without @ will show SAFE MODE warnings.
	}
	else
	{
		$buffer = @ file($file); //Hide warnings.
	}

	if (!is_array($buffer))
		return;

	$buffer = implode(' ', $buffer);
	$lowBuffer = strtolower($buffer);

	/* Locate where <TITLE> is located in html file. */
	$lBound = strpos($lowBuffer, '<title>') + 7; //7 is the lengh of <TITLE>.

	if ($lBound < 1)
		return;

	/* Locate where </TITLE> is located in html file. */
	$uBound = strpos($lowBuffer, '</title>', $lBound);

	if ($uBound < $lBound)
		return;

	/* Clean HTML and PHP tags out of $title with the madness below. */
	$title = ereg_replace("[\t\n\r]", '', substr($buffer, $lBound, $uBound - $lBound));
	$title = trim(strip_tags($title));

	if (strlen($title) < 1) //A blank title is worthless.
		return;

	return $title;
}

function getMetaDesc(& $content)
{
	global $config;

	$lowBuffer = strtolower($content);

	/* Locate where <META is located in html file. */
	$lBound = strpos($lowBuffer, '<meta');

	if ($lBound < 1)
		return false;

	/* Locate where </HEAD is located in html file. */
	$uBound = strpos($lowBuffer, '</head', $lBound);

	if ($uBound < $lBound)
		return false;

	/* Clean HTML and PHP tags out of $desc with the madness below. */
	$desc = ereg_replace("[\t\r\n]", '', substr($content, $lBound, $uBound - $lBound));
	$desc = eregi_replace('^.*<META[[:space:]]+NAME[[:space:]]*=[[:space:]]*\"?description\"?[[:space:]]+CONTENT[[:space:]]*=[[:space:]]*\"?([^\">]*).*$', '\\1', $desc);
	$desc = trim(strip_tags($desc));

	if (strlen($desc) < 1) //A blank desc is worthless.
		return false;

	return $desc;
}

function strimatch($string1, $string2)
{
	for ($i = 0; $i < strlen($string1) && $i < strlen($string2); $i++)
	{
		if (strtolower($string1[$i]) != strtolower($string2[$i]))
		{
			break;
		}
	}

	return substr($string1, 0, $i);
}

function strmatch($string1, $string2)
{
	for ($i = 0; $i < strlen($string1) && $i < strlen($string2); $i++)
	{
		if ($string1[$i] != $string2[$i])
		{
			break;
		}
	}

	return substr($string1, 0, $i);
}

function getFormData()
{
	global $HTTP_GET_VARS;
	global $HTTP_POST_VARS;

	$requestType = getEnvVar('REQUEST_METHOD');

	switch (strtolower($requestType))
	{
		case 'get' :
			$data = $HTTP_GET_VARS;
			break;
		case 'post' :
			$data = $HTTP_POST_VARS;
			break;
		default :
			settype($data, 'array');
	}

	if (!$data && function_exists('getSpecificFormData'))
		$data = getSpecificFormData();

	return $data;
}

function getSpecificFormData()
{
	/* The content of this function is specific to DGS Search. */
	global $r, $o, $s, $q, $debug, $option;

	$data['r'] = $r;
	$data['o'] = $o;
	$data['s'] = $s;
	$data['q'] = $q;
	$data['debug'] = $debug;
	$data['option'] = $option;

	return $data;
}

function getEnvVar($envVar)
{
	global $config;
	global $HTTP_ENV_VARS;
	global $HTTP_SERVER_VARS;

	if ($config['debug'] > 1)
	{
		printf("<br />->Debug: getEnvVar() - getenv(\"%s\"): %s<br />\n", $envVar, getenv($envVar));
		printf("->Debug: getEnvVar() - \$GLOBALS[\"%s\"]: %s<br />\n", $envVar, $GLOBALS[$envVar]);
		printf("->Debug: getEnvVar() - \$HTTP_ENV_VAR[\"%s\"]: %s<br />\n", $envVar, $HTTP_ENV_VARS[$envVar]);
		printf("->Debug: getEnvVar() - \$HTTP_SERVER_VAR[\"%s\"]: %s<br />\n", $envVar, $HTTP_SERVER_VARS[$envVar]);
	}

	$retVal = $GLOBALS[$envVar];
	if (strlen($retVal) < 1)
	{
		$retVal = getenv($envVar);
		if (strlen($retVal) < 1)
		{
			$retVal = $HTTP_ENV_VARS[$envVar];
			if (strlen($retVal) < 1)
			{
				$retVal = $HTTP_SERVER_VARS[$envVar];
			}
		}
	}

	return $retVal;
}

function getTime()
{
	if (function_exists('microtime'))
	{
		$tm = microtime();
		$tm = explode(' ', $tm);
		return (float) sprintf('%f', $tm[1] + $tm[0]);
	}

	return time();
}

function processConfig()
{
	global $config;

	if ($config['debug'])
		printf(">Debug: processConfig()<br />\n");

	/* Put the config into a known state. */
	normalizeConfig();

	/* Verify config */
	if (!$errors)
		$errors = verifyConfig();

	/* Handle Errors */
	if ($errors)
	{
		printf("<b>Error: Configuration error(s) in config.php. Details below:<br />\n<br />\n");
		reset($errors);
		while (list (, $error) = each($errors))
		{
			printf("&nbsp;&nbsp;%s<br />\n", $error);
		}
		printf('</b><br />\n');
		return false;
	}

	return true;
}

function normalizeConfig()
{
	global $config;

	if ($config["debug"])
		printf("->Debug: normalizeConfig()<br />\n");
	return true;
}

function verifyConfig()
{
	global $config;
	global $serverpath;

	$installBase = "$serverpath/modules/dgs_search";
	$siteBase = $serverpath;
	$verify = false;

	if ($config['debug'])
		printf("->Debug: verifyConfig()<br />\n");

	/* These checks are optional. */
	if ($verify)
	{
		$error = verifyPHPVersion(3, 0, 7);
		if (is_string($error))
			$errors[] = $error;
		if (!is_string($siteBase))
			$errors[] = '\$config[\'siteBase\'] is not set to a string type.';
		else
			if (!is_dir($siteBase) || (is_link($siteBase) && !is_dir(readlink($siteBase))))
				$errors[] = '\$config[\'siteBase\'] is not a set to a valid directory.';
		if (!is_string($fsBase))
			$errors[] = '\$config[\'fsBase\'] is not set to a string type.';
		if (strlen($siteBase) > 0)
		{
			$index = strpos($fsBase, $siteBase);
			if (!is_long($index) || $index != 0)
				$errors[] = '\$config[\'fsBase\'] must be a directory within \$config[\'siteBase\'] directory.';
			$index = strpos($installBase, $siteBase);
			if (!is_long($index) || $index != 0)
				$errors[] = '\$config[\'installBase\'] must be a directory within \$config[\'siteBase\'] directory.';
		}
	}

	/* Load modules is always required. */
	$modules['search'] = array (
		'db'
	);
	$modules['display'] = array (
		'query',
		'stats',
		'hr',
		'nav',
		'results',
		'nav'
	);

	/* Load and Verify modules is required. */
	$error = verifyModules($modules);
	if (is_string($error))
		$errors[] = $error;

	if (!isset ($errors))
		return false;
	return $errors;
}

function verifyModules($modules)
{
	global $config;
	global $serverpath;

	$installBase = $serverpath . "/modules/dgs_search";
	$debug = $config['debug'];

	if ($config['debug'])
		printf("-->Debug: verifyModules()<br />\n");

	reset($modules);
	while (list ($modType, $x) = each($modules))
	{
		reset($modules[$modType]);
		while (list ($x, $module) = each($modules[$modType]))
		{
			/*$modInclude = 'libs' . $config['fileSeparator'] . $modType . $config['fileSeparator'] . $module . '.php';*/
			$modInclude = $installBase . '/' . 'libs' . '/' . $modType . '/' . $module . '.php';

			/* Verify function isn't already available. */
			if (!function_exists($module))
			{
				if ($debug)
					printf('-->Debug: verifyModules() - Checking module \'%s\' stored in \'%s\'. ', $module, $modInclude);
				/* Verify we can read the module. */
				if (is_readable($modInclude))
				{
					if ($debug)
						printf(" <b>[Readable]</b><br />\n");
					include ($modInclude);
				}
				else
				{
					if ($debug)
						printf(" <b>[Not Readable]</b><br />\n");
					return sprintf("Unable to access %s module '%s' (%s).<br />\n", $modType, $module, $modInclude);
				}
				/* Verify that the module contains a function of the same name. */
				if (!function_exists($module))
				{
					return sprintf("Error: Module '%s' (%s) is not usable.<br />\nThis module must contain the function '%s(\$retVal, \$value, $param)'.<br />\n", $module, $modInclude, $module);
				}
				else
				{
					$loadedModules[$module] = true;
				}
			}
			else
				if ($loadedModules[$module] != true)
				{
					return sprintf("Error: The function '%s' was available before loading module '%s'.<br />\n'%s' may be a built in PHP function or another module may have the same name. If this is the case, you will need to rename the module.<br />\n", $module, $modInclude, $module);
				}
		}
	}

	return true;
}

function verifyPHPVersion($major, $minor, $sub)
{
	global $config;

	if ($config["debug"])
		printf("->Debug: verifyPHPVersion() - Running PHP '%s' (Required version is %d.%d.%d)<br />\n", phpversion(), $major, $minor, $sub);

	$phpVersion = explode(".", phpversion());
	/* Convert any non-integer values to -1, such as 4.0b3 */
	$phpVersion[0] = (strlen($phpVersion[0]) > 0) ? intval($phpVersion[0]) : -1;
	$phpVersion[1] = (strlen($phpVersion[1]) > 0) ? intval($phpVersion[1]) : -1;
	$phpVersion[2] = (strlen($phpVersion[2]) > 0) ? intval($phpVersion[2]) : -1;

	if ($phpVersion[0] < $major || ($phpVersion[0] == $major && $phpVersion[1] < $minor) || ($phpVersion[0] == $major && $phpVersion[1] == $minor && $phpVersion[2] < $sub))
	{
		return sprintf('%s %s requires at least PHP v%d.%d.%d. You are currently running PHP %s.', $config['program'], $config['version'], $major, $minor, $sub, phpversion());
	}

	return true;
}

function processWindow(& $content, $width, $height, $q, $matchCount)
{
	global $config;
	$keywords_array = explode(" ", $q);
	$q = $keywords_array[0]; //only use the first keyword to get description
	$lowQ = strtolower($q);
	$qSize = strlen($q);
	$window = $width / 2;
	$descEnd = '...';
	$stripTags = true;
	$desc = array ();

	$content = str_replace('<br', ' <br', $content);
	$content = str_replace('<Br', ' <Br', $content);
	$content = str_replace('<BR', ' <BR', $content);
	$content = str_replace('<p', ' <p', $content);
	$content = str_replace('<P', ' <P', $content);
	$content = str_replace('&nbsp;', ' ', $content); //'&nbsp' parts show up if they are broken, so convert to spaces.

	if ($stripTags)
		$content = strip_tags($content);

	$content = ereg_replace('[[:space:]]{2,}', ' ', $content); //Consume extra whitespace from content.
	$content = trim($content);

	$lowContent = strtolower($content);
	$contentSize = strlen($content);

	$queryIdx = 0;
	for ($i = 0; $i < $height; $i++)
	{
		$queryIdx = strpos($lowContent, $lowQ, $queryIdx);
		if (!is_int($queryIdx) || $queryIdx >= $contentSize) //If we don't find $q, then there are no more matches.
			break;

		/* Grab the section of text around the matching keyword. */
		$lBound = ($queryIdx - $window < 0) ? 0 : $queryIdx - $window;
		$uBound = ($lBound + $width > $contentSize) ? $contentSize : $lBound + $width;
		$lBound = ($uBound < $contentSize) ? $lBound : (($uBound - $width < 1) ? 0 : $uBound - $width);

		/* Slide our window to avoid cutting words. */
		$descAdj = $uBound - ($queryIdx + $qSize);
		for ($j = 0; $j < $descAdj; $j++)
		{
			if ($lBound - $j <= 0 || $content[$lBound - $j -1] == ' ')
			{
				$lBound -= $j;
				$uBound -= $j;
				break;
			}
		}

		/* Shrink the uBound to avoid cutting words. */
		$descAdj = $uBound - ($queryIdx + $qSize);
		if ($uBound < $contentSize && $content[$uBound] != ' ')
		{
			for ($j = 1; $j < $descAdj; $j++)
			{
				if ($content[$uBound - $j] == ' ' && $uBound - $j > $lBound)
				{
					$uBound -= $j;
					break;
				}
			}
		}

		/* Cut the desc out of content and add descEnd. */
		$descBuf = '';
		if ($lBound > 0)
			$descBuf = $descEnd;
		$descBuf .= trim(substr($content, $lBound, $uBound - $lBound));
		if ($uBound < $contentSize)
			$descBuf .= $descEnd;
		foreach ($keywords_array as $value)
		{
			$descBuf = eregi_replace("($value)", "<b>\\1</b>", $descBuf);
		}
		$desc[$i] = $descBuf;
		$queryIdx = $uBound; //Jump the queryIdx to the end of the desc.
	}
	return $desc;
}
?>
