<?php

	class AKB_CATEGORIES
	{
		var $_catId = 0;
		var $_page = 1;
		var $_pages = 0;
		var $_start = 0;
		var $_end = 0;
		var $_linkCats = null;
		var $numQuestions = 0;

		/**
		* Constructior
		* Initialise some values for this object
		*
		* @return void
		*/
		function AKB_CATEGORIES()
		{
			// Get the category (if any)
			$this->_SetCat();
			$this->_SetPage();
			$this->_SetBounds();
			$this->_SetPages();

			$GLOBALS['start'] = $this->_start;
			$GLOBALS['end'] = $this->_end;
		}

		/**
		* _GetCat
		* Returns the category id for this object
		*
		* @return int the category id
		*/
		function _GetCat()
		{
			return $this->_catId;
		}

		/**
		* _SetPage
		* Set the page number currently being displayed from paged results to
		* $this->_page
		*
		* @return void
		*/
		function _SetPage()
		{
			$arrVals = array();
			$vals = $_SERVER['REQUEST_URI'];
			$pos = strpos($vals, '?');
			$vals = substr($vals, $pos+1, strlen($vals));
			parse_str($vals, $arrVals);

			if ((isset($arrVals['page'])) && ((int)$arrVals['page'] > 0)) {
				$this->_page = (int)$arrVals['page'];
			}
		}


		/**
		* _SetPages
		* Set $this->_pages to the number of pages of results there are
		*
		* @return bool true if this->_catId is invalid
		*/
		function _SetPages()
		{
			if ($this->_catId <= 0) {
				$this->numQuestions = 0;
				$this->_pages = 0;
				return true;
			}
			$categoryRestrictSQL = "";
			if (isset($GLOBALS['categoryRestrictOption']) && $GLOBALS['categoryRestrictOption'] == "1") {
				$accessible_cats = $GLOBALS['AKB_CLASS_HELPER']->GetPermittedCats();
				if (isset($this->security) && $this->security == 'public') {
					$accessible_cats[] = $this->_catId;
				}
				$accessible_cats = array_unique($accessible_cats);
				$categoryRestrictSQL = "AND a.categoryid IN (".implode(", ", $accessible_cats).")";
			}
			
			// Workout how many pages of results there are
			$workflowQry = '';
			if (validUrl()) {
				$workflowQry = 'AND (workflowstatus = \''.WF_STATUS_APPROVED.'\' OR workflowstatus = \''.WF_STATUS_AUTO_APPROVED.'\' OR workflowstatus = \''.WF_STATUS_REPENDING.'\') ';
			}
			$query = '
				SELECT q.questionid
				FROM '.$GLOBALS['tablePrefix'].'categories c,'.$GLOBALS['tablePrefix'].'categoryassociations a,
				('.$GLOBALS['tablePrefix'].'question_auth qa RIGHT JOIN '.$GLOBALS['tablePrefix'].'questions q ON qa.questionid = q.questionid)
				WHERE 
					c.categoryid = a.categoryid
					AND q.questionid = a.questionid
					AND q.visible = 1
					'.$workflowQry.'
					AND c.categoryid = '.((int) $this->_catId).'
					AND 
						(
						((q.startdate < \''.$GLOBALS['currDatetime'].'\') AND ((q.enableexpiry = 1) AND q.expirydate > \''.$GLOBALS['currDatetime'].'\'))
						OR
						((q.startdate < \''.$GLOBALS['currDatetime'].'\') AND (q.enableexpiry = 0))
						)
					'.$categoryRestrictSQL.'
					AND ((qa.groupid IS NULL) '.AKB_AUTH::deriveGroupSQL(false).')
				GROUP BY q.questionid
			';
			
			$result = $GLOBALS['AKB_DB']->Query($query);
			$this->numQuestions = $GLOBALS['AKB_DB']->CountResult($query);
			$this->_pages = ceil($this->numQuestions / RESULTS_PER_PAGE);
			
		}

		/**
		* _GetPage
		* Get the current page number
		*
		* @return int $this->_page
		*/
		function _GetPage()
		{
			return $this->_page;
		}

		/**
		* _GetPages
		* Get the number of pages in search results
		*
		* @return int $this->_pages
		*/
		function _GetPages()
		{
			return $this->_pages;
		}

		/**
		* _SetBounds
		* Set the start and end of results
		*
		* @return void
		*/
		function _SetBounds()
		{
			if ($this->_GetPage() == 1) {
				$this->_start = 0;
				$this->_end = RESULTS_PER_PAGE;
			} else {
				$this->_start = ($this->_GetPage()-1) * RESULTS_PER_PAGE;
				$this->_end = RESULTS_PER_PAGE;
			}
		}

		/**
		* _SetCat
		* Sets $this->_catId to the category id. Has to take into consideration
		* if clean urls are on or not
		*
		* @return bool true if clean urls are off and $_GET['categoryid'] is set
		*/
		function _SetCat()
		{
			// If we aren't using clean urls then our job is pretty easy
			if (!$GLOBALS['cleanUrls'] && isset($_GET['categoryid'])) {
				$this->_catId = (int) $_GET['categoryid'];
				$category = new API_CATEGORY();
				$category->load($this->_catId);
				
				//Set the security for this object
				$this->security = $category->security;

				// If we couldn't load the category then either it doesn't exist
				// or there was a problem accessing the database so redirect to
				// the home page
				if (!$category->loaded) {
					ob_end_clean();
					header('Location: '.$GLOBALS['pathToKB']);
					die();
				}
				$GLOBALS['CategoryId'] = $category->categoryid;
				$GLOBALS['CategoryName'] =  $GLOBALS['AKB_CLASS_TEMPLATE']->DisablePlaceholders($category->name);
				return true;
			}

			// Get the category from the request_uri and work out its ID
			$path = $_SERVER['REQUEST_URI'];
			$iPos = 0;
			if (strstr($path, '/categories/')) {
				$iPos = strpos($path, '/categories/') + strlen('/categories/');
			}
			$cats = substr($path, $iPos, strlen($path));
			$cats = eregi_replace('/$', '', $cats);

			// Get rid of the paging variable
			$cats = eregi_replace('/\?page=[0-9]{1,}$', '', $cats);
			
			// Now that we have the categories we need to organize them
			// into an array and work out the category ID
			$arrCats = explode('/', $cats);
			
			$this->_linkCats = $arrCats;

			// Replace all bad variables back in
			for ($i = 0; $i < sizeof($arrCats); $i++) {
				$arrCats[$i] = strip_tags($GLOBALS['AKB_CLASS_HELPER']->_MakeURLNormal($arrCats[$i]));
			}
			
			$GLOBALS['CategoryName'] = "";
			$GLOBALS['CatTrails'] = array();
			$GLOBALS['CategoryName'] = $GLOBALS['AKB_CLASS_TEMPLATE']->DisablePlaceholders($arrCats[sizeof($arrCats)-1]);
			
			// If we don't have any data get it from the db
			$GLOBALS['AKB_CLASS_HELPER']->getCatsInfo();
			
			$parentid = 0;
			if (!empty($arrCats[0])) {
				foreach ($arrCats as $cat) {
					if (isset($GLOBALS['AKB_CLASS_HELPER']->tree->nodesByPid[$parentid]) && is_array($GLOBALS['AKB_CLASS_HELPER']->tree->nodesByPid[$parentid])) {
						foreach ($GLOBALS['AKB_CLASS_HELPER']->tree->nodesByPid[$parentid] as $catid) {
							$pcat = $GLOBALS['AKB_CLASS_HELPER']->catsById[$catid];
	
							if (strtolower($pcat['name']) == strtolower($cat)) {
								$GLOBALS['CategoryName'] = strip_tags($pcat['name']);
								$GLOBALS['CatTrails'][] = array ($pcat['categoryid'], $cat);
								$this->_catId = $pcat['categoryid'];
								$parentid = $pcat['categoryid'];
								break;
							}
						}
					}
				}
			}
			 
			if (is_numeric($GLOBALS['CategoryName']) && sizeof($arrCats) == 1) {
				// Get the name of the category and redirect to its full path. We do this
				// to save CPU cycles when outputting the category list
				$catId = $GLOBALS['CategoryName'];
				$query = sprintf("select name from %scategories where categoryid='%d'", $GLOBALS['tablePrefix'], $catId);
				$catName = $GLOBALS['AKB_DB']->FetchOne($query);

				if ($catName) {
					$link = sprintf('%s/categories/%s', $GLOBALS['pathToKB'], $GLOBALS['AKB_CLASS_HELPER']->GetCompleteCategoryPath($catId, $catName));
					ob_end_clean();
					header('Location: '.$link);
					die();
				} else {
					ob_end_clean();
					header('Location: '.$GLOBALS['pathToKB']);
					die();
				}
			} else {
				// Give the category ID a global scope so that it can be accessed from the templates
				if ($this->_catId) {
					$category = new API_CATEGORY();
					$category->load($this->_catId);
					
					if (!$category->loaded) {
						header("location: index.php");
						die();
					}

					//Set the security for this object
					$this->security = $category->security;

					$GLOBALS['CategoryId'] = $this->_GetCat();
				}
			}
		}

		/**
		* HandlePage
		* The default page handler
		*
		* @return void
		*/
		function HandlePage()
		{
			// Determine which function to load
			$ToDo = '';
			
			switch ($ToDo) {
				default:
					$this->ShowCategoryPage();
			}
		}

		/**
		* IncrementViewCount
		* Increment the number of views for a page
		*
		* @return void
		*/
		function IncrementViewCount()
		{
			$query = sprintf("update %scategories set visits=visits+1 where categoryid='%d'", $GLOBALS['tablePrefix'], $this->_GetCat());
			$GLOBALS['AKB_DB']->Query($query);
		}

		/**
		* GetAuth
		* Get the authorisation information for either this->_catId if $catid is
		* null (default) or the catid passed in
		*
		* @param mixed $catid The id of the cat to get auth info about
		*
		* @return array array(pass, catid) of the cat in the tree whos auth
		* applies to the given $catid
		*/
		function GetAuth($catid=null)
		{
			$h =& $GLOBALS['AKB_CLASS_HELPER'];
			if (!isset($h->catsById) || empty($h->catsById)) {
				$h->getCatsInfo();
			}

			if ($catid === null && $this->_catId > 0) {
				$cat = $h->catsById[$this->_catId];
			} elseif ($catid !== null && isset($h->catsById[$catid])) {
				$cat = $h->catsById[$catid];
			} else {
				return array('', 0);
			}

			// If this is a non-root category and this category doesn't have
			// a password, check the parent for a password
			if ($cat['parentid'] > 0 && empty($cat['pass']) ) {
				return $this->GetAuth($cat['parentid']);
			} else {
				return array($cat['pass'], $cat['categoryid']);
			}
		}

		/**
		* CheckPass
		* Check to see if a user is authorised to view this page
		*
		* @return bool True if they can view the page false otherwise
		*/
		function CheckPass($id=null)
		{
			if ($id === null) {
				list ($pass, $categoryid) = $this->GetAuth();
			} else {
				list ($pass, $categoryid) = $this->GetAuth($id);
			}

			// If the password isn't set for this or any parent category, then
			// allow the user to access the category
			if (trim($pass) == '') {
				return true;
			}

			// If the password is set in the cookie and is right then allow
			// access to the category
			$cookie_name = 'akb_cat_pass_'.$categoryid;
			if (isset($_COOKIE[$cookie_name])
				&& $_COOKIE[$cookie_name] == $pass) {
					return true;
			}
			
			// Is the user attempting to get access to the category?
			if (isset($_POST['catAuthPass'])
				&& $_POST['catAuthPass'] == $pass) {
				// Save the authorization to a cookie and grant access
				setcookie($cookie_name, $pass, time()+3600*24*365, '/');
				return true;
			}

			return false;
		}

		/**
		* ShowCategoryPage
		* Show the page with the category details on it
		*
		* @return void
		*/
		function ShowCategoryPage()
		{
			$permitted = $GLOBALS['AKB_CLASS_HELPER']->GetPermittedCats();
			
			$categoryId = $this->_GetCat();
			
			if ($GLOBALS['cleanUrls'] === true) {
				$arrURI = explode('/', $_SERVER['REQUEST_URI']);
				$todo = $arrURI[sizeof($arrURI)-1];
			} else if (isset($_GET['todo'])) {
				$todo = $_GET['todo'];
			} else {
				$todo = '';
			}
			if ($todo == '__addarticle' && !AKB_AUTH::IsLoggedIn() && !AKB_AUTH::HasAdminAccess()) {
				$GLOBALS['Message'] = '<div class="BoxMessage"><img align="left" src="'.$GLOBALS['pathToKB'].'/admin/images/warning.gif"/>'.sprintf(GetLang("addArticleNotPermitted"),$GLOBALS['pathToKB']."/login.php","mailto:".$GLOBALS['contactEmail']).'</div>';
			} else if ($todo == '__addarticle' && AKB_AUTH::IsLoggedIn() && AKB_AUTH::HasAdminAccess() && !in_array($categoryId, $permitted)) {
				$GLOBALS['Message'] = '<div class="BoxMessage"><img align="left" src="'.$GLOBALS['pathToKB'].'/admin/images/warning.gif"/>'.sprintf(GetLang("addArticleNotPermittedLoggedInUser"),"mailto:".$GLOBALS['contactEmail']).'</div>';
				
			} else {
				$todoSplit = split('_', $todo);
				switch ($todoSplit[0]) {
					case 'QuestionSavedNew' :
						$viewArticleLink='<a href="'.GetUrl('question', $todoSplit[1]).'">here</a>';
						$GLOBALS['Message'] = '<div class="BoxMessage"><img align="left" src="'.$GLOBALS['pathToKB'].'/admin/images/success.gif"/>'.sprintf(GetLang($todoSplit[0]),$viewArticleLink).'</div>';
					break;
					case 'QuestionSavedNewRequiresApproval' :
						$GLOBALS['Message'] = '<div class="BoxMessage"><img align="left" src="'.$GLOBALS['pathToKB'].'/admin/images/success.gif"/>'.GetLang($todoSplit[0]).'</div>';
					break;
				}
			}
			
			// Setup the navigation
			$link = GetUrl('category', $categoryId);
			$seperator = $GLOBALS['cleanUrls'] ? '?' : '&amp;';
			
			$GLOBALS['Nav'] = BuildNav($link, $this->_GetPages(), $this->_GetPage(), $seperator);
			$GLOBALS['AddArticleLink'] = GetUrl('category', $categoryId, 'todo=__addarticle');
			//Check permissions
			if (
				((int)$categoryId == 0) 
				|| ((!in_array($categoryId,$permitted)) && ($this->security == "private")) 
				|| ((!AKB_AUTH::IsLoggedIn()) && ($this->security == "private"))) {
				
				//Load the not authorised panel.
				$GLOBALS['HidePanels'] = array(
					'CategoriesPanel',
					'CategoryQuestionsPanel'
				);
				
				$GLOBALS['NotPermittedLink'] = 'javascript: history.go(-1);';
				
				$highestCat = $this->_linkCats[count($this->_linkCats)-1];
				
				$GLOBALS['catNotPermitted'] = sprintf(GetLang("catNotPermitted"),strip_tags($GLOBALS['AKB_CLASS_HELPER']->_MakeURLNormal($highestCat)),$GLOBALS['pathToKB']."/login.php","mailto:".$GLOBALS['contactEmail']);
				
				$GLOBALS['AKB_CLASS_TEMPLATE']->SetPageTitle($GLOBALS['knowledgebaseName']);
				$GLOBALS['AKB_CLASS_TEMPLATE']->SetTemplate('Categories');
				$GLOBALS['AKB_CLASS_TEMPLATE']->ParseTemplate();
			} else {
				list ($pass, $null) = $this->GetAuth();
				$pass = trim($pass);
				if (empty($pass) && (empty($GLOBALS['frontendUser']) || empty($GLOBALS['frontendPass']))) {
					// Should we show the RSS button?
					$GLOBALS['Link'] = GetUrl('rss', $this->_GetCat());
					$GLOBALS['RssButton'] = $GLOBALS['AKB_CLASS_TEMPLATE']->GetSnippet('RssLink');
				}
				
				// Increment the number of views for this category
				$this->IncrementViewCount();

				if ($todo == '__addarticle' && AKB_AUTH::IsLoggedIn() && AKB_AUTH::HasAdminAccess() && in_array($categoryId, $permitted)) {
					$GLOBALS['BodyOnload'] = 'onload="addArticle('.$categoryId.');"';
					$GLOBALS['BodyOnloadFunction'] = 'addArticle('.$categoryId.');';
				}
				
				// Load the categories page
				$GLOBALS['HidePanels'] = array('CategoryAuthPanel');

				$GLOBALS['AKB_CLASS_TEMPLATE']->SetPageTitle($GLOBALS['CategoryName']);
				$GLOBALS['AKB_CLASS_TEMPLATE']->SetTemplate('Categories');
				$GLOBALS['AKB_CLASS_TEMPLATE']->ParseTemplate();
			}
		}
		
		/**
		* GetCategoriesForQuestion
		* Returns an array of category id's that this question is associated with
		*
		* @return void
		*/		
		function GetCategoriesForQuestion($questionId) {
			$query = sprintf("select categoryid from %scategoryassociations where questionid='%d'", $GLOBALS["tablePrefix"], $questionId);
			$result = $GLOBALS['AKB_DB']->Query($query);

			$cat = array();
			while ($row = $GLOBALS['AKB_DB']->Fetch($result)) {
				$cat[] = $row['categoryid'];
			}
			
			return $cat;
		}
	}

?>