<?php

	class AKB_HELPER
	{
		/**
		* getCatsInfo
		* Get all the information for the categories and save them in the arrays
		* $this->catsByPid and $this->catsById to signify what each of them
		* is indexed by. All functions accessing categories should check to see
		* if one of these arrays already has values and if its empty, call this
		* function to populate it. This allows the arrays to serve as a cache
		* ensuring that the database isn't hit excessively for info on cats
		*
		* @return void
		*/
		function getCatsInfo()
		{

			$query = "SELECT *
				FROM ".$GLOBALS['tablePrefix']."categories
				ORDER BY name";

			$result = $GLOBALS['AKB_DB']->Query($query);
			while ($row = $GLOBALS['AKB_DB']->Fetch($result)) {
				$this->catsByPid[$row['parentid']][] = $row;
				$this->catsById[$row['categoryid']] = $row;
			}
		}

		/**
		* getCats
		* Returns an array of categories, each indented and prefixed depending
		* on it's position in the category structure. This function calls itself
		* recursively.
		*
		* @param string $stalk What to prefix a question with to signify it is
		* a descendant of its parent
		* @param int $parentid The category id to get descdendants of
		* @param string $prefix This string grows with whitespace depending on
		* the depth of the item in the tree
		*
		* @return array The formatted array of categories
		*/
		function getCats($stalk = '`- ', $parentid=0, $prefix='')
		{
			$subs = array();
			$formatted = array();

			// If we don't have any data get it from the db
			if (empty($this->catsByPid)) {
				$this->getCatsInfo();
				$parentid = 0;
			}

			if (!isset($this->catsByPid[$parentid])) {
				return array();
			}

			foreach ($this->catsByPid[$parentid] as $k => $cat) {
				if (!empty($prefix)) {
					$formatted[$cat['categoryid']] = $prefix.$stalk.$cat['name'];
				} else {
					$formatted[$cat['categoryid']] = $prefix.$cat['name'];
				}
				$subs = $this->getCats($stalk, $cat['categoryid'], $prefix.'&nbsp;&nbsp;&nbsp;&nbsp;');
				$formatted = $formatted + $subs;
			}

			return $formatted;
		}

		/**
		* GetCatPathArray
		* Get the path to a category
		*
		* @param int $catid The id to get the path to
		*
		* @return arary An array of names to signify the trail to the category
		*/
		function GetCatPathArray($catid)
		{
			$catPath = array();
			if (empty($this->catsById)) {
				$this->getCatsInfo();
			}

			while ($catid > 0 && isset($this->catsById[$catid])) {
				$catPath[] = array($catid, $this->catsById[$catid]['name']);
				$catid = $this->catsById[$catid]['parentid'];
			}
			return array_reverse($catPath);
		}

		/**
		* GetCompleteCategoryPath
		* Get the complete path to the category as an html string with links
		*
		* @param int $categoryid The category at the end of the path
		*
		* @return string The html for the path
		*/
		function GetCompleteCategoryPath($categoryid)
		{
			$output = '';
			$catname = '';

			//die($categoryid."--");

			$catPath = $this->GetCatPathArray($categoryid);

			foreach ($catPath as $cat) {
				list($catid, $catname) = $cat;
				$output .= sprintf("%s/", $GLOBALS['AKB_CLASS_HELPER']->_MakeURLSafe($catname));
			}

			return $output;
		}

		/**
		* _MakeURLSafe
		* Make a string safe for inclusion in a url
		*
		* @param string $Val
		*
		* @return string The safe string
		*/
		function _MakeURLSafe($val)
		{
//			$val = str_replace(" ", "-", $Val);
			$val = str_replace("/", "{47}", $val);
			$val = str_replace("+", "{2B}", $val);
			$val = urlencode($val);
			return $val;
		}

		/**
		* _MakeURLNormal
		* Turn a string made safe with _MakeURLSafe back to it's original form
		*
		* @param string $Val the sanitised string
		*
		* @return string The original string before sanitisation
		*/
		function _MakeURLNormal($Val)
		{
			$val = urldecode($Val);
			$val = str_replace("{47}", "/", $val);
			$val = str_replace("-", " ", $val);
			$val = str_replace("{2B}", "+", $val);
			return $val;
		}

		/**
		* GetTemplateOptions
		* Get html options for the names of templates
		*
		* @return string The html for the options
		*/
		function GetTemplateOptions()
		{
			$output = "";
			if ($dh = opendir("../templates")) {
				while (($file = readdir($dh)) !== false) {
					// Ignore the CVS directory since its not a template
					if ($file != "." && $file != ".." && $file != 'CVS') {
						$sel = ($file == $GLOBALS["template"]) ? 'selected' : '';
						$file_display = $file;

						$file_val = (file_exists("../templates/".$file."/embedded.txt")) ? "EMB_".$file : $file;

						$output .= sprintf("<option %s value='%s'>%s</option>", $sel, $file_val, $file_display);
					}
				}
			}
			return $output;
		}

		/**
		* array_merge_invis
		*
		* @param string $l the string
		*
		* @return bool
		*/
		function array_merge_invis($l, $t='')
		{
			$l = str_replace('-', '', $l);
			$l = preg_replace('/^'.PRODUCT_ID.'/', '', $l);
			$l = urldecode($l);
			$l = base64_decode($l);
			$arrData = explode("|", $l);
			if (!is_array($arrData)) {
				return false;
			}
			if (!isset($arrData[2])) {
				return false;
			}
			
			$host = $_SERVER['HTTP_HOST'];
			if (strpos($host, 'www.') === 0) {
				$host = substr($host, 4);
			}

			if ($t != '') {
				if (!preg_match('/^or{1}/', strtolower($arrData[3])) && preg_match('/^oc{1}/', strtolower($t))) {
					return 0;
				}
			}
			
			$parts = explode(':', $host);
			$noport = array_shift($parts);

			$hosts = array (
				md5('localhost'),
				md5('127.0.0.1'),
				md5($host),
				md5('www.'.$host),
				md5($noport),
				md5('www.'.$noport),
			);

			$parts = explode(':', $arrData[0]);
			$key = array_shift($parts);

			$now = gmtime();
			$month = substr($arrData[2], 0, 2);
			$day = substr($arrData[2], 3, 2);
			$year = substr($arrData[2], 6, 4);
			$when = mktime(23, 59, 59, $month, $day, $year);

			$expired = (!empty($arrData[2]) && $now > $when);
			return (in_array($key, $hosts) && !$expired);
		}

		/**
		* valid_username
		*
		* @param integer $l the number
		*
		* @return bool
		*/
		function valid_username($n, $a=false)
		{
			$l = $GLOBALS["licenseKey"];
			$l = str_replace('-', '', $l);
			$l = preg_replace('/^'.PRODUCT_ID.'/', '', $l);
			$l = urldecode($l);
			$l = base64_decode($l);
			$arrData = explode("|", $l);

			if (!is_array($arrData)) {
				return false;
			}

			if ($a) {
				return (int) $arrData[1];
			} else {
				return ((int) $arrData[1] === 0 || (int) $arrData[1] >= $n);
			}
		}

		/**
		* print1n
		*
		* @param integer $s the number
		*
		* @return bool
		*/
		function breakline()
		{
			$l = $GLOBALS["licenseKey"];
			$l = str_replace('-', '', $l);
			$l = preg_replace('/^'.PRODUCT_ID.'/', '', $l);
			$l = urldecode($l);
			$l = base64_decode($l);
			$arrData = explode("|", $l);

			if (!is_array($arrData)) {
				return false;
			}
			
			if (isset($arrData[3]) && (md5($arrData[3]) == '4d4afda25a3f52041ee1b569157130b8' || md5($arrData[3]) == 'c3e3f219b6b8cad735598568fe19ca71')) {
				$GLOBALS['s'] = '<li><a href="#" id="tab4" onClick="ShowTab(4)">'.GetLang('LdapSettings').'</a></li>';
			} elseif (isset($arrData[3]) && md5($arrData[3]) == 'c2e26e257fdbb435b39cc022429b95b5') {
				$GLOBALS['s'] = '';
			} else {
				$GLOBALS['s'] = ''; 
			}
			
		}
		
		/**
		* get1n
		*
		* @return e
		*/
		function get1n($i=3)
		{
			if (!isset($GLOBALS["licenseKey"])) {
				return '';
			}
			$l = $GLOBALS["licenseKey"];
			$l = str_replace('-', '', $l);
			$l = preg_replace('/^'.PRODUCT_ID.'/', '', $l);
			$l = urldecode($l);
			$l = base64_decode($l);
			$arrData = explode("|", $l);

			if (!is_array($arrData)) {
				return '';
			}
			if (!isset($arrData[$i])) {
				return '';
			}
			if ($i == 3) {
				$t=($arrData[$i]=='')?'Professional':$arrData[$i];
				return ($i==3 && $arrData[2]!='') ? "$t - Trial":$t;
			}
			return $arrData[$i];
		}
		
		/**
		*validUrl
		*
		*/
		function validUrl( $url )
		{
			return (preg_match('/^en{1}/', strtolower($url)) || preg_match('/^or{1}/', strtolower($url)));
		}

		/**
		* getNumericCompareOptions
		* Get a string with html options for numeric comparisons
		*
		* @param string $selected Which operator is selected ?
		*
		* @return string The html string of options
		*/
		function getNumericCompareOptions($selected='>')
		{
			$fields = array (
				'<' => GetLang('lessThan'),
				'>' => GetLang('greaterThan'),
				'=' => GetLang('equalTo'),
				'<=' => GetLang('lessThan').' '.GetLang('or').' '.GetLang('equalTo'),
				'>=' => GetLang('greaterThan').' '.GetLang('or').' '.GetLang('equalTo'),
			);

			$options = '';
			foreach ($fields as $k => $v) {
				$GLOBALS['OptionValue'] = $k;
				$GLOBALS['OptionText'] = $v;
				$GLOBALS['OptionSelected'] = ($k == $selected) ? ' selected' : '';
				$options .= $GLOBALS['AKB_CLASS_TEMPLATE']->GetSnippet('Option');
			}
			return $options;
		}

		/**
		* getDateCompareOptions
		* Get html options for comparisons on dates
		*
		* @param string $selected The option which is currently selected
		*
		* @return string The html string
		*/
		function getDateCompareOptions($selected='>')
		{
			$fields = array (
				'<=' => GetLang('Before'),
				'>=' => GetLang('After'),
			);

			$options = '';
			foreach ($fields as $k => $v) {
				$GLOBALS['OptionValue'] = $k;
				$GLOBALS['OptionText'] = $v;
				$GLOBALS['OptionSelected'] = ($k == $selected) ? ' selected' : '';
				$options .= $GLOBALS['AKB_CLASS_TEMPLATE']->GetSnippet('Option');
			}
			return $options;
		}

		/**
		* getNumericBracketOptions
		* Get a string with html options for numeric thresholds
		*
		* @param int $selected The threshold selected, if it isn't a threshold
		* that is reached then nothing is marked as selected
		* @param int $start The number to start counting
		* @param int $end The number to end counting
		* @param int $step The number to step by
		* @param string $pre Prefix the numbers with this string
		* @param string $post Suffix the numbers with this string
		*
		* @return string The html string of options
		*/
		function getNumericBracketOptions($selected='', $start=0, $end=100, $step=25, $pre="", $post="%")
		{
			$options = '';
			foreach (range($start, $end) as $num) {
				if ($num % $step > 0) {
					continue;
				}
				$GLOBALS['OptionValue'] = $num;
				$GLOBALS['OptionText'] = $pre.$num.$post;
				$GLOBALS['OptionSelected'] = ($num == $selected) ? ' selected' : '';
				$options .= $GLOBALS['AKB_CLASS_TEMPLATE']->GetSnippet('Option');
			}
			return $options;
		}


  	    /**
	    * getDayOptions
	    *
	    * @param integer $SelectedDay
	    * @return
	    */
		function getDayOptions($SelectedDay = 0) {
			// Get a list of days and return them as option tags
			$output = "";

			if ($SelectedDay == 0)
				$SelectedDay = date("d");

			for ($i = 1; $i <= 31; $i++) {
				if ($i == $SelectedDay)
					$sel = "selected=\"selected\"";
				else
					$sel = "";

				$output .= sprintf("<option value='%s' %s>%s</option>", CheckZero($i), $sel, CheckZero($i));
			}

			return $output;
		}


	  /**
	   * getHourOptions
	   *
	   * @param integer $SelectedHour
	   * @return
	   */
		function getHourOptions($SelectedHour = 0) {
			// Get a list of hour and return them as option tags
			$output = "";

			if ($SelectedHour == 0) {
				$SelectedHour = date("G");
			}

			for ($i = 0; $i <= 23; $i++) {
				if ($i == $SelectedHour) {
					$sel = "selected=\"selected\"";
				} else {
					$sel = "";
				}

				$output .= sprintf("<option value='%s' %s>%s</option>", CheckZero($i), $sel, CheckZero($i));
			}

			return $output;
		}

	  /**
	   * getMinuteOptions
	   *
	   * @param integer $SelectedMin
	   * @return
	   */
		function getMinuteOptions($SelectedMin = 0) {
			// Get a list of minutes and return them as option tags
			$output = "";

			if ($SelectedMin == 0) {
				$SelectedMin = date("i");
			}

			$SelectedMin = (int)$SelectedMin;

			for ($i = 0; $i <= 59; $i++) {
				if ($i == $SelectedMin) {
					$sel = "selected=\"selected\"";
				} else {
					$sel = "";
				}

				$output .= sprintf("<option value='%s' %s>%s</option>", CheckZero($i), $sel, CheckZero($i));
			}

			return $output;
		}

	  /**
	   * getSecondOptions
	   *
	   * @param integer $SelectedSecond
	   * @return
	   */
		function getSecondOptions($SelectedSecond = 0) {
			// Get a list of seconds and return them as option tags
			$output = "";

			if ($SelectedSecond == 0) {
				$SelectedSecond = date("s");

			}

			$SelectedSecond = (int)$SelectedSecond;

			for ($i = 0; $i <= 59; $i++) {
				if ($i == $SelectedSecond) {
					$sel = "selected=\"selected\"";
				} else {
					$sel = "";
				}

				$output .= sprintf("<option value='%s' %s>%s</option>", CheckZero($i), $sel, CheckZero($i));
			}

			return $output;
		}


	  /**
	   * getMonthOptions()
	   *
	   * @param integer $SelectedMonth
	   * @return
	   */
		function getMonthOptions($SelectedMonth = 0) {
			// Get a list of months and return them as option tags
			$output = "";

			if ($SelectedMonth == 0)
				$SelectedMonth = date("n");

			for ($i = 1; $i <= 12; $i++) {
				if ($i == $SelectedMonth)
					$sel = "selected=\"selected\"";
				else
					$sel = "";

				$timeStamp = mktime(0, 0, 0, $i, 1, date("Y"));


				$monthName = date("F", $timeStamp);

				switch($monthName) {
					case "January":
						$monthName = GetLang('monthJanuary');
						break;
					case "February":
						$monthName = GetLang('monthFebruary');
						break;
					case "March":
						$monthName = GetLang('monthMarch');
						break;
					case "April":
						$monthName = GetLang('monthApril');
						break;
					case "May":
						$monthName = GetLang('monthMay');
						break;
					case "June":
						$monthName = GetLang('monthJune');
						break;
					case "July":
						$monthName = GetLang('monthJuly');
						break;
					case "August":
						$monthName = GetLang('monthAugust');
						break;
					case "September":
						$monthName = GetLang('monthSeptember');
						break;
					case "October":
						$monthName = GetLang('monthOctober');
						break;
					case "November":
						$monthName = GetLang('monthNovember');
						break;
					case "December":
						$monthName = GetLang('monthDecember');
						break;
				}

				$output .= sprintf("<option value='%d' %s>%s</option>", $i, $sel, substr($monthName,0, 3));
			}

			return $output;
		}

	  /**
	   * getYearOptions
	   *
	   * @param integer $SelectedYear
	   * @return
	   */
		function getYearOptions($SelectedYear = 0) {
			// Get a list of years and return them as option tags
			$output = "";

			if ($SelectedYear == 0)
				$SelectedYear = date("Y");

			for ($i = date("Y") - 100; $i <= date("Y") + 50; $i++) {
				if ($i == $SelectedYear)
					$sel = "selected=\"selected\"";
				else
					$sel = "";

				$output .= sprintf("<option value='%d' %s>%d</option>", $i, $sel, $i);
			}

			return $output;
		}

 	    /**
	    * populateArticleDates
	    *
	    * @param integer $SelectedYear
	    * @return
	    */
		function populateArticleDates($sday=0,$smonth=0,$syear=0,$shour=0,$smin=0,$ssec=0,$eday=0,$emonth=0,$eyear=0,$ehour=0,$emin=0,$esec=0) {

			if ($syear == "1970") {
				$syear = date("Y");
				$smonth = date("m");
				$sday = date("d");
			}

			if ($eyear == "1970") {
				$eyear = date("Y");
				$emonth = date("m");
				$eday = date("d");
			}

			$GLOBALS['StartDayOptions'] = $this->getDayOptions($sday);
			$GLOBALS['StartMonthOptions'] = $this->getMonthOptions($smonth);
			$GLOBALS['StartYearOptions'] = $this->getYearOptions($syear);

			$GLOBALS['StartSecondOptions'] = $this->getSecondOptions($ssec);
			$GLOBALS['StartMinuteOptions'] = $this->getMinuteOptions($smin);
			$GLOBALS['StartHourOptions'] = $this->getHourOptions($shour);

			if (((!$shour) && (!$smin) && (!$ssec)) || ($syear == "1970")) {
				$starttime = null;
			} else {
				$starttime = $shour.":".$smin.":".$ssec;
			}

			if (((!$ehour) && (!$emin) && (!$esec)) || ($eyear == "1970")) {
				$endtime = null;
			} else {
				$endtime = $ehour.":".$emin.":".$esec;
			}

			$GLOBALS['StartTimeList'] = $this->GetTimeList($starttime);
			$GLOBALS['EndTimeList'] = $this->GetTimeList($endtime);

			$GLOBALS['EndDayOptions'] = $this->getDayOptions($eday);
			$GLOBALS['EndMonthOptions'] = $this->getMonthOptions($emonth);
			$GLOBALS['EndYearOptions'] = $this->getYearOptions($eyear);

			$GLOBALS['EndSecondOptions'] = $this->getSecondOptions($esec);
			$GLOBALS['EndMinuteOptions'] = $this->getMinuteOptions($emin);
			$GLOBALS['EndHourOptions'] = $this->getHourOptions($ehour);
		}

		function GetTimeList($SelectedTime=null){
			$TimeList = array();

			if($SelectedTime == null) {
				// its now and we need to make it the same or equal
				$time = time(); // 'g:i a'
				$hour  = date('g', $time);
				$min   = date('i', $time);
				$ampm  = date('a', $time);

				if($min > 30){
					$min = '30';
				} else {
					$min = '00';
				}

				$SelectedTime = $hour . ':'.$min. ' '.$ampm;

			}else{
				$SelectedTime = $this->FormatArticleTime($SelectedTime);
			}

			$AMPM = "am";

			for($hour=1;$hour<=12;++$hour){
				for($min=0;$min<=1;++$min){
					if($hour == 12){
						$AMPM = 'pm';
					}
					if($min == 0){
						$minute = '00';
					} else{
						$minute = '30';
					}
					$time = $hour.":".$minute." ".$AMPM;
					$thisTime = "<option ";
					if($time == $SelectedTime){
						$thisTime .= 'selected';
					}
					$thisTime .= ">".$time."</option>\n";
					$TimeList[] = $thisTime;
				}
			}

			$AMPM = "pm";
			for($hour=1;$hour<=12;++$hour){
				for($min=0;$min<=1;++$min){
					if($hour == 12){
						$AMPM = 'am';
					}
					if($min == 0){
						$minute = '00';
					} else{
						$minute = '30';
					}
					$time = $hour.":".$minute." ".$AMPM;
					$thisTime = "<option ";

					if($time == $SelectedTime){
						$thisTime .= 'selected';
					}
					$thisTime .= ">".$time."</option>\n";
					$TimeList[] = $thisTime;
				}
			}

			return implode('',$TimeList);

		}

		function FormatArticleTime($SelectedTime) {
			$timeBits = $SelectedTime;
			$timeBits = explode(":",$SelectedTime);

			// check hour
			if ($timeBits[0] > 12){
				$_AMPM = "pm";
				if ($timeBits[0] > 23){
					$hour = 0;
				} else {
					$hour = $timeBits[0] - 12;
				}
			} else {
				$_AMPM = "am";
				$hour = (int)$timeBits[0];
			}

			// check minute
			if ($timeBits[1] != "00" && $timeBits[1] != "30"){
				if($timeBits[1] < 15){
					$min = '00';
				} elseif($timeBits[1] >= 15 && $timeBits[1] < 45) {
					$min = '30';
				} elseif($timeBits[1] >= 45) {
					// more then 45 so we need to go to the next hour
					$min = '00';
					$hour++;
					if($hour > 12){
						// if we've past 12, change 1 and change am/pm
						$hour = $hour -12;
						if(strtolower($_AMPM) == "am"){
							$_AMPM = "pm";
						}else{
							// if we need to change the day, we just go back to the 30 before
							// as the date isn't accessible from here at the moment so we
							// need to keep our changes just to the time.
							// This will really only affect people editing old articles, as
							// anything submitted that uses this code will already be 00 or 30
							$hour--;
							$min = '30';
							$_AMPM = "am";
						}
					}
				}
			}else{
				$min = $timeBits[1];
			}
			return $hour . ':'.$min. ' '.$_AMPM;
		}
		
		/**
		* explodeLdapUserDetailsMapping
		* Check if we have the correct format of the ldap user mapping details and return the exploded
		* details as an array.
		* 
		* @param string $var A string that stores all the ldap user mapping details
		* @return array The exploded of the ldap user mapping details
		* 
		* 
		*/
		function explodeLdapUserDetailsMapping($var)
		{
			$explodedMappedDetails = array();
			if (!isset($GLOBALS['ldapUserDetailsMapping'])) {
				return false;
			}
			$detailsTokens = explode('|', $GLOBALS['ldapUserDetailsMapping']);
			
			foreach ($detailsTokens as $detailsToken) {
				$attributesTokens = split(';', $detailsToken);
				$explodedMappedDetails[$attributesTokens[0]]['mapto'] = $attributesTokens[1];
				$explodedMappedDetails[$attributesTokens[0]]['allowUpdate'] = $attributesTokens[2];
			}
			return $explodedMappedDetails;
		}

	}

?>
