Location: PHPKode > projects > Community Learning Network > cln/lib/CLN/Cln_KB_Search.php
<?php
/*
 * KB Search Class
 *
 * Copyright (c) 2003-4 St. Christopher House
 *
 * Developed by The Working Group Inc.
 *
 * 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 program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 * @version $Id: Cln_KB_Search.php,v 1.15 2005/01/25 21:14:47 derekbrooks Exp $
 *
 */
 

if(!defined('CLN_CORE_KBSEARCH_INTERFACE')) define('CLN_CORE_KBSEARCH_INTERFACE', 'lib/CLN/interfaces/kbSearch-core.php');


class Cln_KB_Search
{
	/*
	 *
	 * Class Attributes:  Cln_Process_Manager
	 *
	 * 		The attributes for this class are:
	 *
	 *		TBD
	 *
	 */

	// Search related
	var $customWheres; // An array of custom 'WHERE' statements
	var $fetchColumns; // The columns to fetch
	var $tables; // The tables to search
	var $sortColumn; // The column to sort by
	var $sortDirection; // The direction to sort by
	var $includedModules; // The modules that are included, an array of modIds
	var $excludedModules; // The modules that are excluded, an array of modIds
	var $perms;	// The permissions, an array of roleIds
	var $resultType; // single or multiple results

	// Results related
	var $results; // The MySQL Result Set
	var $numResults; // The total number of results
	var $numPages; // The total number of pages;
	var $pageSize; // The number of results to display per page
	var $currentPage; // The current page # that is displayed
	var $currentResult; // The current result #
	var $choice; // The choice of ko(s) that is ultimately made

	// Display related
	var $hasRun; // Has the search been run yet?
	var $interfacePath; // The path to the search result interface
	var $appendToURL; // An array of name/value pairs that should be appended to the URL

	// User related
	var $userResult; // The place where the user's chosen kos are stored

	/*
	 *
	 * Function:  Cln_KB_Search()
	 *
	 * 		Class Constructor
	 *
	 * @access public
	 * @return TBD
	 *
	 */
	function Cln_KB_Search()
	{
		$this->customWheres = Array();
		$this->fetchColumns = 'ko.koId, ko.title, ko.modId, UNIX_TIMESTAMP(ko.created) as created, UNIX_TIMESTAMP(ko.modified) as modified';
		$this->tables = sprintf('%s as ko, %s as perm', KO_TABLE, PERMISSION_TABLE);
		$this->sortColumn = 'ko.title';
		$this->sortDirection = 'ASC';
		$this->includedModules = Array();
		$this->excludedModules = Array();
		$this->perms = Array();
		
		// this is a hack to setup the defaults for permissions - dwc
		if(!isset($_REQUEST['searchRoles']) || empty($_REQUEST['searchRoles'])) {
			$_REQUEST['searchRoles'] = array('owner','publisher','collaborator','viewer');
		}
		
		$this->resultType = 'single';
		$this->results = NULL;
		$this->numResults = 0;
		$this->pageSize = 20;
		$this->currentPage = NULL;
		$this->currentResult = NULL;
		$this->choice = NULL;
		$this->hasRun = FALSE;
		$this->interfacePath = 'lib/CLN/interfaces/kbSearch.html';
		if (isset($_GET['editKoId'])) {
			// :NOTE: i think this is a better default - dwc
			$this->nameValuePairs['editKoId'] = $_GET['editKoId'];
			$this->nameValuePairs['editProcess'] = 'Content';
		}
		else {
			$this->appendToURL = array();
		}
		$this->userResult = FALSE;
	}


	/*
	 *
	 * Function:  run()
	 *
	 * 		Runs the search, sets all the proper values, etc
	 *
	 * @access public
	 * @return TBD
	 *
	 */
	function run()
	{
		$this->hasRun = TRUE;
		$this->getPassedData();
		if (!$this->isComplete()) {
			$this->search();
		}
		else {
			// Search is complete
			return $this->choice;
		}
	}

	/*
	 *
	 * Function:  getContent()
	 *
	 * 		Gets the search content
	 *
	 * @access public
	 * @return TBD
	 *
	 */
	function getContent($interface = '')
	{
		if (!$this->hasRun) {
			$this->run();
		}
		return $this->getInterface($interface);
	}


	/*
	 *
	 * Function:  getPassedData()
	 *
	 * 		Captures any passed fields that are related to the search
	 *
	 * @access public
	 * @return TBD
	 *
	 */
	function getPassedData()
	{
		// perform this check first, as it determines whether or not to check
		// session variable for searchTerms
		// Look for a submitted page #
		if (isset($_GET['kbSearchPage'])) {
			foreach($_SESSION['searchTerms'] as $name => $value) {
				$_REQUEST[$name] = $value;
			}
			$this->currentPage = $_GET['kbSearchPage'];
		}
		else {
			// clear search terms
			unset($_SESSION['searchTerms']);
			
			$this->currentPage = 1;
		}
		
		
		// handle title searches
		if(isset($_REQUEST['searchTitle']) && !empty($_REQUEST['searchTitle'])) {
			$this->customWheres[] = "ko.title LIKE '%".$_REQUEST['searchTitle']."%'";
			$_SESSION['searchTerms']['searchTitle'] = $_REQUEST['searchTitle'];
		}
		
		// handle createdBy and modifiedBy searches
		if(isset($_REQUEST['searchCreatedBy']) && !empty($_REQUEST['searchCreatedBy'])) {
			$createdById = $_SESSION['User']->getUserId($_REQUEST['searchCreatedBy']);
			// get createdBy id
			$this->customWheres[] = "ko.createdBy = '".$createdById."'";
			$_SESSION['searchTerms']['searchCreatedBy'] = $_REQUEST['searchCreatedBy'];
		}
		if(isset($_REQUEST['searchModifiedBy']) && !empty($_REQUEST['searchModifiedBy'])) {
			$modifiedBy = $_SESSION['User']->getUserId($_REQUEST['searchModifiedBy']);
			// get modifiedBy id
			$this->customWheres[] = "ko.modifiedBy = '".$modifiedBy."'";
			$_SESSION['searchTerms']['searchModifiedBy'] = $_REQUEST['searchModifiedBy'];
		}
		
		// Handle date/time searches
		if(isset($_REQUEST['searchCreationStartDate']) && !empty($_REQUEST['searchCreationStartDate'])) {
			$this->customWheres[] = "ko.created >= '".str_replace('/','',$_REQUEST['searchCreationStartDate'])."000000'";
			$_SESSION['searchTerms']['searchCreationStartDate'] = $_REQUEST['searchCreationStartDate'];
		}
	    if(isset($_REQUEST['searchCreationFinishDate']) && !empty($_REQUEST['searchCreationFinishDate'])) {
			$this->customWheres[] = "ko.created <= '".str_replace('/','',$_REQUEST['searchCreationFinishDate'])."000000'";
			$_SESSION['searchTerms']['searchCreationFinishDate'] = $_REQUEST['searchCreationFinishDate'];
	    }
		if(isset($_REQUEST['searchModificationStartDate']) && !empty($_REQUEST['searchModificationStartDate'])) {
			$this->customWheres[] = "ko.modified >= '".str_replace('/','',$_REQUEST['searchModificationStartDate'])."000000'";
			$_SESSION['searchTerms']['searchModificationStartDate'] = $_REQUEST['searchModificationStartDate'];
		}
		if(isset($_REQUEST['searchModificationFinishDate']) && !empty($_REQUEST['searchModificationFinishDate'])) {		
			$this->customWheres[] = "ko.modified <= '".str_replace('/','',$_REQUEST['searchModificationFinishDate'])."000000'";
			$_SESSION['searchTerms']['searchModificationFinishDate'] = $_REQUEST['searchModificationFinishDate'];
		}
		
		// handle moduleType searches
		if(isset($_REQUEST['searchModtypes']) && !empty($_REQUEST['searchModtypes'])) {
			$this->includedModules = $_REQUEST['searchModtypes'];
			$_SESSION['searchTerms']['searchModtypes'] = $_REQUEST['searchModtypes'];
		}
		
		// handles role searches
		if(isset($_REQUEST['searchRoles']) && !empty($_REQUEST['searchRoles'])) {
			foreach($_REQUEST['searchRoles'] as $searchRole) {
				if ($searchRole == 'owner') {
					$this->perms[] = 1;
				}
				else if ($searchRole == 'publisher') {
					$this->perms[] = 2;
				}
				else if ($searchRole == 'collaborator') {
					$this->perms[] = 3;
				}
				else if ($searchRole == 'viewer') {
					$this->perms[] = 4;
				}
				else if ($searchRole == 'creator') {
					$this->customWheres[] = sprintf('ko.createdBy = %d', $_SESSION['User']->userId);
				}
			}
			
			$_SESSION['searchTerms']['searchRoles'] = $_REQUEST['searchRoles'];
		}
		
		
		// handle metadata searches
		$metadataObject =& new $GLOBALS['classes']['metadata']['classname']('','');
		$metadataKbSearch =& $metadataObject->getPassedData();
		
		// :TODO: this is a little bit of a hack
		// i wish i knew a better way to merge objects - dwc
		if(!empty($metadataKbSearch->fetchColumns)) $this->fetchColumns .= ",".$metadataKbSearch->fetchColumns;
		if(!empty($metadataKbSearch->tables)) $this->tables .= ", ".$metadataKbSearch->tables;
		$this->customWheres = array_merge($this->customWheres, $metadataKbSearch->customWheres);
		//$this->appendToURL = array_merge($this->appendToURL, $metadataKbSearch->appendToURL);
	

		// Look for a submitted result
		if (isset($_REQUEST['kbSearchResultKoId'])) {
			if ($this->resultType == 'single') {
				$this->userResult = $_REQUEST['kbSearchResultKoId'];
			}
		}

		// Look for a submitted column to order by
		if (isset($_REQUEST['orderColumn'])) {
			$this->sortColumn = $_REQUEST['orderColumn'];
		}

		// Look for a submitted ordering
		if (isset($_REQUEST['direction']) && ($_REQUEST['direction'] == 'ASC' || $_REQUEST['direction'] == 'DESC')) {
			$this->sortDirection = $_REQUEST['direction'];
		}
		return TRUE;
	}


	/*
	 *
	 * Function:  isComplete()
	 *
	 * 		If the user is finished choosing what they wanted, this returns true
	 *
	 * @access public
	 * @return TBD
	 *
	 */
	function isComplete()
	{
		if ($this->resultType == 'single' && !empty($this->userResult)) {
			return TRUE;
		}
		else {
			return FALSE;
		}
	}


	/*
	 *
	 * Function:  getNextResult()
	 *
	 * 		Returns the next result as a generic object
	 *
	 * @access public
	 * @return TBD
	 *
	 */
	function getNextResult()
	{
		if ($this->results == NULL) {
			return FALSE;
		}
		else if ($this->currentResult >= $this->numResults) {
			return FALSE;
		}
		else if ($this->currentResult >= ($this->currentPage * $this->pageSize)) {
			return FALSE;
		}
		else {
			$this->result = $this->results->fetchRow(DB_FETCHMODE_OBJECT, $this->currentResult);
			$this->currentResult++;
			return $this->result;
		}
	}


	/*
	 *
	 * Function:  search()
	 *
	 * 		Performs the search
	 *
	 * @access public
	 * @return TBD
	 *
	 */
	function search()
	{
		// Build the SQL statement
		$sql = sprintf('SELECT %s FROM %s
						WHERE %s
						GROUP BY ko.koId
						ORDER BY %s %s',
						$this->fetchColumns, $this->tables,
						$this->getSQLWhere(), $this->sortColumn, $this->sortDirection);
		
		d($sql, 3);
						
		// Perform the query
		$db = &Cln_Db::singleton(MAIN_CLN_DSN);
		$this->results = $db->query($sql);

		if (PEAR::isError($this->results)) {
			PEAR::raiseError('Error on kbSearch query: '.$sql, E_ERROR);
			return FALSE;
		}
		else if($this->results->numRows() == 0) {
			// :QUESTION: we need to do something special here - dwc
			PEAR::raiseError('Your search returned no results. Please try again.', E_USER_NOTICE);
			return TRUE;
		}
		else {
			// Get the number of results
			$this->numResults = $this->results->numRows();
			$this->numPages = ceil((float)($this->numResults / $this->pageSize));

			if ($this->currentPage > $this->numPages) {
				$this->currentPage = $this->numPages;
			}

			$this->currentResult = $this->currentPage * $this->pageSize - $this->pageSize;
				//echo "current result is $this->currentResult";
			return TRUE;
		}
	}


	/*
	 *
	 * Function:  getSQLWhere()
	 *
	 * 		Builds the WHERE part of the sql
	 *
	 * @access public
	 * @return TBD
	 *
	 */
	function getSQLWhere()
	{
		$whereAnds = Array();
		// The join of KO and PERM tables
		$whereAnds[] = ' ko.koId = perm.koId ';

		// Acceptable roles
		if(count($this->perms) > 0) {
			$whereAnds[] = ' perm.roleId IN (' . join(',',$this->perms) . ') ';
		}

		// Acceptable groups
		$whereAnds[] = ' perm.groupId IN (' . implode(',', $_SESSION['User']->groupList) . ')';

		// Included modules
		if (count($this->includedModules) > 0) {
			foreach ($this->includedModules as $key => $modId) {
				$acceptSQL[] = ' ko.modId = ' . $modId;
			}
			$whereAnds[] = ' (' . implode(' OR ', $acceptSQL) . ') ';
		}

		// Excluded modules
		if (count($this->excludedModules) > 0) {
			foreach ($this->excludedModules as $key => $modId) {
				$whereAnds[] = 'ko.modId != ' . $modId;
			}
		}

		// Any custom WHEREs
		foreach ($this->customWheres as $where) {
			$whereAnds[] = $where;
		}

		return implode(' AND ', $whereAnds);
	}


	/*
	 *
	 * Function:  getInterface()
	 *
	 * 		Loads the interface
	 *
	 * @access public
	 * @return TBD
	 *
	 */
	function getInterface($interface = '')
	{
		if(!empty($interface)) {
			$this->interfacePath = $interface;
		}

		ob_start();
		include($this->interfacePath);
		$form = ob_get_contents();
		ob_end_clean();
		return $form;
	}


	/*
	 *
	 * Function:  getCoreSearchForm()
	 *
	 * 		get the form to search core ko properties
	 *
	 * @access public
	 * @return TBD
	 *
	 */
	function getCoreSearchForm()
	{
		return $this->getInterface(CLN_CORE_KBSEARCH_INTERFACE);
	}


	/*
	 *
	 * Function:  getMetadataSearchForm()
	 *
	 * 		get the form to search metadata
	 *
	 * @access public
	 * @return TBD
	 *
	 */
	function getMetadataSearchForm()
	{
		return $this->getInterface(CLN_METADATA_KBSEARCH_INTERFACE);
	}
	

	/*
	 *
	 * Function:  getSearchResults()
	 *
	 * 		get the search results (total versuses displayed
	 *
	 * @access public
	 * @return TBD
	 *
	 */
	function getSearchResults()
	{
		$searchResults = '';


		if($this->numResults > 0) {
			$searchResults = '<p>Your search found <b>' . $this->numResults . ' results</b>. '
				 . '<b>Results '
				 . ($this->currentPage * $this->pageSize - $this->pageSize + 1) . ' to '
				 . (min(($this->currentPage ) * $this->pageSize, $this->numResults))
				 . '</b> are displayed below:</p>';
		}

		return $searchResults;
	}


	/*
	 *
	 * Function:  getPagingNavigation()
	 *
	 * 		get the paging links
	 *
	 * @access public
	 * @return TBD
	 *
	 */
	function getPagingNavigation()
	{
		if($this->numResults > 0) {
			$pagingNavigation = '<p><b>Results Page: ';

			$sortOrderColString = isset($_REQUEST['orderColumn']) ? '&orderColumn=' . $_REQUEST['orderColumn'] : '';
			$sortOrderColString .= isset($_REQUEST['direction']) ? '&direction=' . $_REQUEST['direction'] : '';

			$pages = Array();
			if ($this->currentPage > 1) {
				$pages[] = '<a href="' . appendToURL(cleanURL($GLOBALS['path']), $this->getParams() . '&amp;kbSearchPage=' . ($this->currentPage - 1) . $sortOrderColString) . '">Previous</a>';
			}
			for ($x = 1; $x <= $this->numPages; $x++) {
				if ($x == $this->currentPage) {
					$pages[] = $x;
				}
				else {
					$pages[] = '<a href="' . appendToURL(cleanURL($GLOBALS['path']), $this->getParams() . '&amp;kbSearchPage=' . $x . $sortOrderColString) . '">' . $x . '</a>';
				}
			}
			if ($this->currentPage < $this->numPages) {
				$pages[] = '<a href="' . appendToURL(cleanURL($GLOBALS['path']), $this->getParams() . '&amp;kbSearchPage=' . ($this->currentPage + 1) . $sortOrderColString) . '">Next</a>';
			}

			$pagingNavigation .= implode(' | ', $pages).'</b></p>';
		} else {
			$pagingNavigation = '<p><b>There are no results.</b></p>';
		}

		return $pagingNavigation;
	}


	/*
	 *
	 * Function:  getNumPages()
	 *
	 * 		Gets the number of pages
	 *
	 * @access public
	 * @return TBD
	 *
	 */
	function getNumPages()
	{
		if (!$this->results) return FALSE;
		return ceil(mysql_num_rows($this->results) / (float)$this->pageSize);
	}


	/*
	 *
	 * Function:  getNumPages()
	 *
	 * 		Gets the number of pages
	 *
	 * @access public
	 * @return TBD
	 *
	 */
	function getPageNum()
	{
		return $this->page;
	}


	/*
	 *
	 * Function:  getNumPages()
	 *
	 * 		Gets the number of pages
	 *
	 * @access public
	 * @return TBD
	 *
	 */
	function isLastPage()
	{
		return ($this->page >= $this->getNumPages());
	}


	/*
	 *
	 * Function:  getNumPages()
	 *
	 * 		Gets the number of pages
	 *
	 * @access public
	 * @return TBD
	 *
	 */
	function isFirstPage()
	{
		return ($this->page <= 1);
	}
	
	
	/*
	 *
	 * Function:  getParams()
	 *
	 * 		forms name/value pairs from appendToURL array
	 *
	 * @access public
	 * @return TBD
	 *
	 */
	function getParams()
	{
		$nameValuePairs = array();
		
		foreach($this->nameValuePairs as $name => $value) {
			$nameValuePairs[] = $name.'='.$value;
		}
		
		return join("&amp;",$nameValuePairs);
	}

}

?>
Return current item: Community Learning Network