Location: PHPKode > projects > Community Learning Network > cln/lib/CLN/Cln_User.php
<?php
/*
 * User 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_User.php,v 1.99 2005/01/26 04:48:30 cbooth7575 Exp $
 *
 */
require_once 'PEAR.php';

class Cln_User extends PEAR {

	/*
	 *
	 * Class Attributes:  Cln_Room
	 *
	 * 		The attributes for this class are:
	 *
	 *		TBD
	 *
	 */
	var $userId;
	var $memberName;
	var $firstName;
	var $lastName;
	var $email;
	var $password;
	var $confirmed;
	var $groupList;		//  (comma separated list)
	var $auth = array();


	/*
	 *
	 * Function:  Cln_User()
	 *
	 * 		Class Constructor
	 *
	 * @access public
	 * @return TBD
	 *
	 */
	function Cln_User()
	{
		$this->userId = '';
		$this->memberName = '';
		$this->firstName = '';
		$this->lastName = '';
		$this->company = '';
		$this->email = '';
		$this->password = '';
		$this->groupList = Array('1');		// default group is 1 (ie. public)
		$this->lang = 'en';

		// this should be set for each user
		$this->preferredLanguages = array(
			'en', 'fr', 'es'
		);

		$this->auth = array(
			'exp' => 0x7fffffff,
			'refresh' => 0x7fffffff
		);
	}


	/*
	 *
	 * Function:  login()
	 *
	 * 		Performs the login
	 *
	 * @access public
	 * @return TBD
	 *
	 */
	function login($confirmed = FALSE)
	{
		includeLangFile('lib/CLN/lang/General');

		/* both $this->email and $this->password are required to login. */
		if(empty($this->email)) {
			PEAR::raiseError(CLN_LOGIN_NO_EMAIL,E_USER_ERROR);
			return FALSE;
		}
		if(empty($this->password)) {
			PEAR::raiseError(CLN_LOGIN_NO_PASSWORD,E_USER_ERROR);
			return FALSE;
		}

		/* establish db connection */
		$db = &Cln_Db::singleton(MAIN_CLN_DSN);

		/* sql to authenicate email and password */
		$sql = sprintf("SELECT userId, memberName, firstName, lastName, company, email, password, confirmed FROM %s "
					  ."WHERE email = '%s' AND password = password('%s')",
					  USER_TABLE, addslashes($this->email), addslashes($this->password));

		$result = $db->query($sql);

		if (PEAR::isError($result))  {
			PEAR::raiseError("Error with the database during authentication: $sql", E_ERROR);
			PEAR::raiseError(CLN_DB_ERROR , E_USER_ERROR);
			return FALSE;
		} elseif ($result->numRows() == 0) {
			PEAR::raiseError(CLN_LOGIN_WRONG_EMAIL_PASS, E_USER_WARNING);
			return FALSE;
		}

		/* Parse the object returned from query	*/
		$row = $result->fetchRow(DB_FETCHMODE_OBJECT);

		// check whether user has agreed to the terms
		if(!$confirmed) {
			$this->confirmed = $row->confirmed;
			if(!isset($this->confirmed) || $this->confirmed != 1) {
				clnRedirect(appendToURL(cleanURL('MyHouse/index.php'),'userProcess=confirmAccount', TRUE));
				exit;
			}
		}

		$this->userId = $row->userId;
		$this->memberName = stripslashes($row->memberName);
		$this->firstName = stripslashes($row->firstName);
		$this->lastName = stripslashes($row->lastName);
		$this->company = stripslashes($row->company);

		$this->groupList = $this->getGroupList();

        $this->auth['exp'] = (time() + (60 * CLN_AUTHENTICATION_LIFETIME));
        $this->auth['refresh'] = (time() + (60 * CLN_AUTHENTICATION_REFRESH));

        $_SESSION['editMode'] = 'browse';

		PEAR::raiseError('You have successfully logged into the CLN.<br/><br/>You can now flip between BROWSE mode and EDIT mode by clicking those words at the top of each page.<br/>EDIT mode allows you to change the content on a page - ONLY if you have been assigned permission by an administrator. Different people will have permission to edit different parts of the web site.', E_USER_NOTICE);

		// If so desired (by a setting in the config file) forward the logged in users
		// to a specific page
		if (CLN_LOGIN_REDIRECT != '' && (!isset($this->currentSubprocess) || $this->currentSubprocess != 'confirmAccount')) {
			clnRedirect(cleanURL(CLN_LOGIN_REDIRECT));
			exit;
		}

		return TRUE;
	}


	/*
	 *
	 * Function:  logout()
	 *
	 * 		Performs the logout
	 *
	 * @access public
	 * @return TBD
	 *
	 */
	function logout()
	{
		PEAR::raiseError('You have been logged out of the system.', E_USER_NOTICE);

		$_SESSION['User'] = new Cln_User;
		$_SESSION['editMode'] = 'browse';

		foreach($_SESSION['Module_Loader']->moduleTypes as $module) {
			// :HACK: it's choking on quiz's submod - dwc
			if($module['modPath'] == 'modules/Quiz/MultipleChoice/Cln_Module_Quiz_MC.php') continue;
			if (!empty($module['modPath'])) { // :HACK: it's also getting some empty values in the SessionModLoader, causing issues
				require_once($module['modPath']);
				if(class_exists($module['modClass'])) {
					if (in_array('logout', get_class_methods($module['modClass']))) {
						call_user_func(array($module['modClass'], 'logout'));
					}
				}
			}
		}

		// send the person back to the homepage
		clnRedirect(CLN_BASE_URL);
		exit;
	}


	/*
	 *
	 * Function:  saveUser()
	 *
	 * 		saves a user's profile info
	 *
	 * @access public
	 * @return BOOLEAN 	 TRUE or FALSE
	 *
	 */
	function saveUser()
	{
		if (!empty($this->password)) {
			$sql = sprintf("UPDATE %s SET memberName = '%s', firstName = '%s', lastName = '%s',
							email = '%s', company = '%s', password = password('%s') WHERE userId = '%s'",
							USER_TABLE, addslashes($this->memberName), addslashes($this->firstName),
							addslashes($this->lastName), addslashes($this->email), addslashes($this->company),
							addslashes($this->password), $this->userId);
		}
		else {
			$sql = sprintf("UPDATE %s SET memberName = '%s', firstName = '%s', lastName = '%s',
							email = '%s', company = '%s' WHERE userId = '%s'",
							USER_TABLE, addslashes($this->memberName), addslashes($this->firstName),
							addslashes($this->lastName), addslashes($this->email),
							addslashes($this->company), $this->userId);
		}

		$db = &Cln_Db::singleton(MAIN_CLN_DSN);
		$result = $db->query($sql);

		if (PEAR::isError($result)) {
			PEAR::raiseError('Problem saving profile: '.$sql, E_USER_WARNING);
			return FALSE;
		}

		return TRUE;
	}


	/*
	 *
	 * Function:  createNewUser()
	 *
	 * 		adds a user
	 *
	 * @access public
	 * @return BOOLEAN 	 TRUE or FALSE
	 *
	 */
	function createNewUser()
	{
		$this->password = $this->generatePassword();

		// Put them in the DB
		$db = &Cln_Db::singleton(MAIN_CLN_DSN);
		$this->userId = $db->nextId(USER_TABLE);

		$emailParts = split('@',$this->email);
		//$this->memberName = substr($emailParts[0],22);
		$this->memberName = $emailParts[0];
		if(strlen($this->memberName) > 22) {
			$this->memberName = substr($this->memberName,0,22);
		}

		$memberNameisValid = false;
		$number = '';
		while(!$memberNameisValid) {
			$thisMemberName = $this->memberName.$number;
			$sql = sprintf("SELECT userId FROM %s WHERE memberName = '%s'",
			 				USER_TABLE, $thisMemberName);

			$result = $db->query($sql);

			if ($result->numRows() <= 0) {
				$memberNameisValid = true;
				$this->memberName = $thisMemberName;
			} else {
				$number++;
			}
		}

		$sql = sprintf("INSERT INTO %s SET memberName = '%s', firstName = '%s', lastName = '%s', email = '%s',
						password = password('%s'), userId = %d, created = NOW()",
			 			USER_TABLE, addslashes($this->memberName), addslashes($this->firstName), addslashes($this->lastName),
			 			addslashes($this->email), addslashes($this->password), $this->userId);

		$result = $db->query($sql);

		if (PEAR::isError($result)) {
			if($result->getMessage() == 'DB Error: already exists') {
				PEAR::raiseError('A user with that email address already exists',E_USER_WARNING);
				return FALSE;
			} else {
				PEAR::raiseError('An error occurred during processing. Please try again.',E_USER_WARNING);
				return FALSE;
			}
		}

		if (!$this->emailTemporaryPassword()) {
			PEAR::raiseError('An error occurred while sending the email. Please try again.', E_USER_WARNING);
			$sql= sprintf("DELETE FROM %s WHERE userId = '%s'",
						   USER_TABLE, $this->userId);
			$result = $db->query($sql);
			return FALSE;
		}

		if($this->userId == 1) {
			// first user into the system becomes a super user and is logged in automatically
			$superUserGroup = new $GLOBALS['classes']['group']['classname'](3);
			$superUserGroup->users[$this->userId]['name'] = $this->firstname.' '.$this->lastname;
			$superUserGroup->users[$this->userId]['editor'] = 1;
			$superUserGroup->save();

			$GLOBALS['makeSuperUser'] = TRUE;
		}

		return TRUE;
	}

	/*
	 *
	 * Function: checkMemberName()
	 *
	 * 		checks to see if memberName is available
	 *
	 * @access public
	 * @return bool   TRUE on success or FALSE on failure
	 *
	 */
	function checkMemberName($memberName) {
		$db = &Cln_Db::singleton(MAIN_CLN_DSN);
		$sql = sprintf("SELECT userId FROM %s WHERE memberName = '%s' AND userId != %d",
						USER_TABLE, $memberName, $this->userId);

		$result = $db->query($sql);

		if ($result->numRows() <= 0) {
			return TRUE;
		} else {
			return FALSE;
		}
	}

	/*
	 *
	 * Function: emailTemporaryPassword()
	 *
	 * sends email to new user with temporary password
	 *
	 * @access public
	 * @return bool   TRUE on success or FALSE on failure
	 *
	 */
	function emailTemporaryPassword()
	{
		if (defined('CLN_SERVER_EMAIL_ADDRESS')) {
			$emailSubject = 'New account created for '.CLN_SITE_NAME;
			$emailBody = $this->firstName.' '.$this->lastName.' now has an account on '.CLN_SITE_NAME.".\n"
			            ."If this account was generated in error, just ignore this email.\n\n"
						.'You have been given a temporary password.  Use this password to login for the first time.  Once '
						.'you have logged into the network, you can go to your preferences and change '
						."your password.\n  Your temporary password is: " . $this->password . "\n\n"
						."Follow this link in order to login:\n"
						.'     ' . CLN_BASE_URL;

			$emailFrom = CLN_SERVER_EMAIL_ADDRESS;

			if (mail($this->email,$emailSubject,$emailBody,'From: '.$emailFrom."\nBCC:".CLN_SERVER_EMAIL_ADDRESS)) {
				return TRUE;
			} else {
				return FALSE;
			}
		} else {
			PEAR::raiseError('constant CLN_SERVER_EMAIL_ADDRESS must be defined',E_USER_ERROR);
		}
	}


	/*
	 *
	 * Function: recoverPassword()
	 *
	 * generates a new password, and emails it to the user
	 *
	 * @access public
	 * @return bool   TRUE on success or FALSE on failure
	 *
	 */
	function recoverPassword()
	{
		if (isset($_POST['userEmail'])) {
			$newPassword = $this->generatePassword();

			$db = &Cln_Db::singleton(MAIN_CLN_DSN);

			$sql = sprintf("UPDATE %s SET password = password('%s') WHERE email = '%s'",USER_TABLE, addslashes($newPassword), addslashes($_POST['userEmail']));

			$result = $db->query($sql);

			// DB error?
			if (PEAR::isError($result)) {
				PEAR::raiseError('There was a database error. Please try again.',E_USER_ERROR);
				return FALSE;
			}

			// Was there no matching account?
			if ($db->affectedRows() == 0) {
				PEAR::raiseError('There wasn\'t an account matching that email address', E_USER_NOTICE);
				return FALSE;
			}

			// Otherwise, send the email.
			else {
				$toAddress = $_POST['userEmail'];
				$subject = 'New password for the CLN';
				$message = 'This is your temporary password: '.$newPassword."\n"
					   ."Once you login, you should change your password for future access.\n\n";
				$fromAddress = 'CLN Administrator <hide@address.com>';

				if(mail($toAddress,$subject,$message,'From: '.$fromAddress)) {
					PEAR::raiseError('Your password has been emailed to you.  Please check your email.',E_USER_NOTICE);
				} else {
					PEAR::raiseError('Error sending temporary password.',E_USER_ERROR);
					return FALSE;
				}
			}
		}
		else {
			return FALSE;
		}
	}


	/*
	 *
	 * Function:  generatePassword()
	 *
	 * 		Returns a random password
	 *
	 * @access public
	 * @return string		random password
	 *
	 */
	function generatePassword()
	{
		return CLN_PASSWORD_PREFIX.rand(1000,9999);
	}


	/*
	 *
	 * Function:  getContent()
	 *
	 * 		Returns the text content from the DB
	 *
	 * @access public
	 * @return TBD
	 *
	 */
	function getContent()
	{
		//if(isset($GLOBALS['MYHOUSE']) && !empty($_SESSION['User']->userId)) {
		//	$myHouseController = $_SESSION['User']->getInterface('myHouseController');
		//} else {
		//	$myHouseController = '';
		//}
		//$myHouseController = $_SESSION['User']->getInterface('myHouseController');

		$content = $this->getEditContent();

		//return $myHouseController.$content;
		return $content;
	}


	/*
	 *
	 * Function:  getEditContent()
	 *
	 * 		Returns the edit form for this module
	 *
	 * @access public
	 * @return TBD
	 *
	 */
	function getEditContent($override = FALSE)
	{
		// Figure out the subprocess we're on
		if (isset($_GET['userProcess'])) {
			$this->currentSubprocess = $_GET['userProcess'];
		}
		if (!isset($this->currentSubprocess)) {
			$this->currentSubprocess = 'myProfile';
		}

		// Load the language files needed
		includeLangFile('lib/CLN/lang/User-Process');

		switch ($this->currentSubprocess) {

			case 'myProfile':
				if (isset($_POST['editProfile'])) {
					if($this->captureEditFormData()) {
						if($this->saveUser()) {
							PEAR::raiseError('Your profile has been updated.', E_USER_NOTICE);
						}
					}
					return $this->getInterface('myProfile');
				} else {
					return $this->getInterface('myProfile');
				}
			break;

			case 'myShortcuts':
				$shortcutType = (!isset($_REQUEST['shortcutType'])) ? '' : $_REQUEST['shortcutType'];
				$roleSelector = (!isset($_REQUEST['roleSelector'])) ? '' : $_REQUEST['roleSelector'];

				return $this->getMyStuff($shortcutType, $roleSelector);
			break;

			case 'myWorkshop':
				return $this->getInterface('myWorkshop');
			break;

			case 'register':
				if (isset($_POST['registerUser'])) {
					// it's important to create another instance of Cln_User, so as to not clobber an
					// existing one
					$newUser = new Cln_User();
					if($newUser->captureEditFormData()) {
						if($newUser->createNewUser()) {
							PEAR::raiseError('<b>'. $newUser->firstName.' '.$newUser->lastName.'</b> has been registered. An email has been sent to <b>' . $newUser->email . '</b> with the password. Once you receive that email, you can come back here and log into your account.', E_USER_NOTICE);
						}
						if(isset($GLOBALS['makeSuperUser'])) {
							$newUser->saveUser();
							$newUser->login(TRUE);
							$newUser->confirmed = 1;
							$newUser->accountIsConfirmed();

							PEAR::raiseError($newUser->firstName.' '.$newUser->lastName.' has been made a Super User.', E_USER_NOTICE);

							PEAR::raiseError('Remember to change your password in your House, under profile. An email has been sent to you with a temporary password as well.', E_USER_NOTICE);

							$_SESSION['User'] = $newUser;
						}
					}
					clnRedirect(CLN_BASE_URL);
				} else {
					return $this->getInterface('register');
				}
			break;

			case 'getPassword':
				if (isset($_POST['getPassword'])) {
					$this->recoverPassword();
					return FALSE;
				} else {
					return $this->getInterface('getPassword');
				}
			break;

			case 'confirmAccount':
				if(isset($_POST['agreeToTerms'])) {
					$this->login(TRUE);		// TRUE says account should be treated as confirmed

					if($this->accountIsConfirmed()) {
						$_SESSION['User']->confirmed = 1;
						PEAR::raiseError('Your account has been confirmed.', E_USER_NOTICE);
						// If so desired (by a setting in the config file) forward the logged in users
						// to a specific page
						if (CLN_LOGIN_REDIRECT != '') {
							clnRedirect(cleanURL(CLN_LOGIN_REDIRECT));
							exit;
						}
					} else {
						PEAR::raiseError('We were unable to confirm your account.', E_USER_ERROR);
						return $this->getInterface('confirmAccount');
					}

					clnRedirect(cleanURL('MyHouse/index.php'));
				}
				else if(isset($_POST['disagreeToTerms'])) {
					PEAR::raiseError('You are unable to log into the system because you did not agree to the terms of the system.', E_USER_ERROR);

					clnRedirect(cleanURL('MyHouse/index.php'));
				}
				return $this->getInterface('confirmAccount');
			break;

			default:
				return FALSE;
			break;
		}
	}


	/*
	 *
	 * Function:  captureEditFormData()
	 *
	 * 		Captures the form data for the edit form
	 *
	 * @access public
	 * @return TBD
	 *
	 */
	function captureEditFormData()
	{
		$status = TRUE;

		if(isset($_POST['userMemberName'])) {
			if (empty($_POST['userMemberName'])) {
				PEAR::raiseError('You need to enter a member name.', E_USER_WARNING);
				$status = FALSE;
			}
			else if($this->checkMemberName($_POST['userMemberName'])) {
				$this->memberName = $_POST['userMemberName'];
			} else {
				PEAR::raiseError('Sorry. The member name: '.$_POST['userMemberName'].' is already taken. Please try again.', E_USER_WARNING);
				$status = FALSE;
			}
		}

		if(isset($_POST['userFirstName'])) {
			if (empty($_POST['userFirstName'])) {
				PEAR::raiseError('You need to enter your first name', E_USER_WARNING);
				$status = FALSE;
			} else {
				$this->firstName = $_POST['userFirstName'];
			}
		}

		if(isset($_POST['userLastName'])) {
			if (empty($_POST['userLastName'])) {
				PEAR::raiseError('You need to enter your last name', E_USER_WARNING);
				$status = FALSE;
			}
			$this->lastName = $_POST['userLastName'];
		}

		if(isset($_POST['userEmail'])) {
			if (empty($_POST['userEmail'])) {
				PEAR::raiseError('You need to enter your email address', E_USER_WARNING);
				$status = FALSE;
			}
			// Else, is it a valid email
			else if (!validateString($_POST['userEmail'], 'email')) {
				PEAR::raiseError('That doesn\'t appear to be a valid email address', E_USER_WARNING);
				$status = FALSE;
			}
			$this->email = $_POST['userEmail'];
		}

		if(isset($_POST['userCompany'])) {
			$this->company = $_POST['userCompany'];
		}

		if(isset($_POST['userTelephone'])) {
			$this->telephone = $_POST['userTelephone'];
		}

		if(isset($_POST['userStreet'])) {
			$this->street = $_POST['userStreet'];
		}

		if(isset($_POST['userCity'])) {
			$this->city = $_POST['userCity'];
		}

		if(isset($_POST['userProvince'])) {
			$this->province = $_POST['userProvince'];
		}

		if(isset($_POST['userPostalCode'])) {
			$this->postalCode = $_POST['userPostalCode'];
		}

		if(isset($_POST['password'])) {
			if(isset($_POST['password']) && isset($_POST['passwordConfirm']) && $_POST['password'] != $_POST['passwordConfirm']) {
				// this is to catch users who do not use javascript
				PEAR::raiseError('Passwords do not match', E_USER_WARNING);
				$status = FALSE;
			}
			$this->password = $_POST['password'];
		}

		return $status;
	}


	/*
	 *
	 * Function:  createMyHouse()
	 *
	 * 		A check if the user is logged in our not
	 *
	 * @access public
	 * @return TBD
	 *
	 */
	function createMyHouse()
	{
		d('Cln_User: createMyHouse');

		// Create the new virtual room and page

		$usersRoomId = $this->getRoomId(CLN_USERS_ROOM);
		$myHouseId = $this->getRoomId(CLN_MY_HOUSE_TEMPLATE);
		$myWorkshopId = $this->getRoomId(CLN_MY_WORKSHOP_TEMPLATE);

		// 1.  create /Users/<userId>/	- copy
		// 2.  create /Users/<userId>/index.php	- copy
		// 3.  create /Users/<userId>/index.php[introBlock] - link

		if(empty($usersRoomId)) {
			PEAR::raiseError('There is no template ('.CLN_USERS_ROOM.') for Users Room', E_USER_ERROR);
			return FALSE;
		}

		if(empty($myHouseId)) {
			PEAR::raiseError('There is no template ('.CLN_MY_HOUSE_TEMPLATE.') for My House', E_USER_ERROR);
			return FALSE;
		}

		// Create myHouseRoom
		$myHouseRoom = & new $GLOBALS['classes']['ko']['classname']('NEW',1);
		$myHouseRoom = $myHouseRoom->copy($myHouseId, TRUE, $this->userId);
		$myHouseRoom->save();
		$myHouseRoomKoId = $myHouseRoom->koId;
		unset($myHouseRoom);
		$myHouseRoom = & new $GLOBALS['classes']['ko']['classname']($myHouseRoomKoId);
		$myHouseRoom->loadAllParts();
		$myHouseRoom->loadPartObject(0);

		// Add myHouseRoom to the Users room nav
		// Because of permissions, in order to be able to make this work, we need
		// to _temporarily_ add the user to the SuperUser group.
		$_SESSION['User']->groupList[] = 3;
		$usersRoom = & new $GLOBALS['classes']['ko']['classname']($usersRoomId);
		$usersRoom->loadPartObject(0);

		$newNodeName = $usersRoom->currentPart['object']->addRoomToRoom($myHouseRoom->koId, 'User'.$this->userId, TRUE);
		$usersRoom->publishKO();

		// Then we pull them out of the SuperUser group we added them to.
		array_pop($_SESSION['User']->groupList);

		// Remove all the children from the current myHouseRoom
		$myHouseRoom->currentPart['object']->childrenNodes = Array();

		// Get all the children that should be inside the myHouse
		$myHouseTemplate = new $GLOBALS['classes']['ko']['classname']($myHouseId);
		$myHouseTemplate->loadPartObject(0);
		$childrenNodes = $myHouseTemplate->currentPart['object']->getNodes();

		// Add copy of subrooms and pages within my house
		foreach($childrenNodes as $childNode) {
			if($childNode['modId'] == 1) {
				$newRoom = new $GLOBALS['classes']['ko']['classname']('NEW',1);
				$newRoom = $newRoom->copy($childNode['koId'], TRUE, $this->userId);
				$newRoom->save();

				$myHouseRoom->currentPart['object']->addRoomToRoom($newRoom->koId, FALSE, TRUE);
			}
			else {
				$newPage = new $GLOBALS['classes']['ko']['classname']('NEW',2);
				$newPage = $newPage->copy($childNode['koId'], TRUE, $this->userId);
				$newPage->save();
				$myHouseRoom->currentPart['object']->addPageToRoom($newPage->koId, $childNode['nodeName']);
			}
		}

		$myHouseRoom->save();
		$myHouseRoom->publishKO();

		// 4.  create /Users/<userId>/MyWorkshop/	- copy
		// 5.  create /Users/<userId>/MyWorkshop/index.php	- copy
		// 6.  create /Users/<userId>/MyWorkshop/index.php[introBlock] - link

		if(empty($myWorkshopId)) {
			PEAR::raiseError('There is no template ('.CLN_MY_WORKSHOP_TEMPLATE.') for My Workshop', E_USER_ERROR);
			return FALSE;
		}

		// Create myWorkshop
		$myWorkshopRoom = & new $GLOBALS['classes']['ko']['classname']('NEW',1);
		$myWorkshopRoom = $myWorkshopRoom->copy($myWorkshopId, TRUE, $this->userId);
		$myWorkshopRoom->save();
		$myWorkshopRoomId = $myWorkshopRoom->koId;
		unset($myWorkshopRoom);
		$myWorkshopRoom = &new $GLOBALS['classes']['ko']['classname']($myWorkshopRoomId);
		$myWorkshopRoom->loadAllParts();
		$myWorkshopRoom->loadPartObject(0);

		// Add myWorkshop to the MyHouse room Nav
		$newNodeName = $myHouseRoom->currentPart['object']->addRoomToRoom($myWorkshopRoom->koId, FALSE, TRUE);
		$myHouseRoom->save();
		$myHouseRoom->publishKO();


		// Remove all the children from the current myWorkshop
		$myWorkshopRoom->currentPart['object']->childrenNodes = Array();

		// Get all the children that should be inside the myWorkshop
		$myWorkshopTemplate = new $GLOBALS['classes']['ko']['classname']($myWorkshopId);
		$myWorkshopTemplate->loadPartObject(0);
		$childrenNodes = $myWorkshopTemplate->currentPart['object']->getNodes();

		// Add a copy of subrooms and pages within myworkshop
		foreach($childrenNodes as $childNode) {
			if($childNode['modId'] == 1) {
				$newRoom = & new $GLOBALS['classes']['ko']['classname']('NEW',1);
				$newRoom = $newRoom->copy($childNode['koId'], TRUE, $this->userId);
				$newRoom->save();

				$myWorkshopRoom->currentPart['object']->addRoomToRoom($newRoom->koId, FALSE, TRUE);
			} else {
				$newPage = & new $GLOBALS['classes']['ko']['classname']('NEW',2);
				$newPage = $newPage->copy($childNode['koId'], TRUE, $this->userId);
				$newPage->save();

				$myWorkshopRoom->currentPart['object']->addPageToRoom($newPage->koId, $childNode['nodeName']);
			}
		}

		$myWorkshopRoom->save();
		$myWorkshopRoom->publishKO();

		return TRUE;
	}


	/*
	 *
	 * Function:  accountIsConfirmed()
	 *
	 * 		after accepting terms of system, user's status is changed to confirmed
	 *
	 * @access public
	 * @return bool		TRUE or FALSE
	 *
	 */
	function accountIsConfirmed()
	{
		$db = &Cln_Db::singleton(MAIN_CLN_DSN);

		$sql = sprintf('UPDATE %s SET confirmed = 1 WHERE userId = %d',
						USER_TABLE, $this->userId);

		$result = $db->query($sql);

		if (PEAR::isError($result)) {
			PEAR::raiseError('Could not set confirmed status: '.$sql,E_USER_ERROR);
			return FALSE;
		}
		else {
			$_SESSION['User'] = $this;
			$this->createMyHouse();
			return TRUE;
		}
	}


	/*
	 *
	 * Function:  isLoggedIn()
	 *
	 * 		A check if the user is logged in our not
	 *
	 * @access public
	 * @return TBD
	 *
	 */
	function isLoggedIn()
	{
		if(isset($this->userId) && is_numeric($this->userId) && (CLN_AUTHENTICATION_LIFETIME <= 0 || (time() < $this->auth['exp']))) {
		    if(CLN_AUTHENTICATION_REFRESH == 0) return TRUE;
		    if(CLN_AUTHENTICATION_REFRESH > 0 && $this->auth['refresh'] < time()) {
        		$this->auth['refresh'] = time() + (60 * CLN_AUTHENTICATION_REFRESH);
        		return TRUE;
        	    } else {
        		return FALSE;
        	    }
        	} else {
        		return FALSE;
        	}
	}


	/*
	 *
	 * Function:  getUserProfile()
	 *
	 * 		gets a user's profile information
	 *
	 * @access public
	 * @return BOOLEAN 	 TRUE or FALSE
	 *
	 */
	function getUserProfile($userId = '')
	{
		if(!empty($userId)) {
			$this->email = $userId;
		}

		$db = &Cln_Db::singleton(MAIN_CLN_DSN);
		
		$sql = sprintf("SELECT userId, memberName, firstName, lastName, company, email, password, confirmed FROM %s WHERE userId = %d",USER_TABLE,$this->userId);

		$result = $db->query($sql);

		if (PEAR::isError($result)) {
			PEAR::raiseError('unable to select from '.USER_TABLE.' table: '.$sql,E_USER_WARNING);
			return FALSE;
		} else {
			while($row = $result->fetchRow(DB_FETCHMODE_OBJECT)) {
				$this->userId = $row->userId;
				$this->memberName = $row->memberName;
				$this->firstName = $row->firstName;
				$this->lastName = $row->lastName;
				$this->company = $row->company;
				$this->email = $row->email;
				$this->password = $row->password;
				$this->confirmed = $row->confirmed;
			}
			return TRUE;
		}
	}


	/*
	 *
	 * Function:  getInterface()
	 *
	 * 		returns an admin interface
	 *
	 * @access public
	 * @return String 	$content
	 *
	 */
	function getInterface($formName)
	{
		ob_start();
		include('lib/CLN/interfaces/User/' . $formName . '.html');
		$content = ob_get_contents();
		ob_end_clean();
		return $content;
	}


	/*
	 *
	 * Function:  updateUserProfile()
	 *
	 * 		updates the information stored on the user
	 *
	 * @access public
	 * @return BOOLEAN 	 TRUE or FALSE
	 *
	 */
	function updateUserProfile($firstName,$lastName,$email,$password = '')
	{
		$this->firstName = $firstName;
		$this->lastName = $lastName;
		$this->email = $email;
		if(!empty($password)) $this->password = $password;

		$db = &Cln_Db::singleton(MAIN_CLN_DSN);

		$sql = "UPDATE user SET firstName = '" . addslashes($this->firstName) . "', lastName = '" . addslashes($this->lastName) . "', "
		  	  ." email = '". addslashes($this->email)."' ";
		if($_POST['password']) $sql .= ", password = password('" . addslashes($this->password) . "') ";
		$sql .= "WHERE userId = '" . $this->userId."'";
		//print $sql;

		$result = $db->query($sql);

		if (PEAR::isError($result)) {
			PEAR::raiseError('Unable to update '.USER_TABLE.' table: '.$sql,E_USER_WARNING);
			return FALSE;
		} else {
			return TRUE;
		}
	}


	/*
	 *
	 * Function:  getGroupList()
	 *
	 * 		gets list of groups
	 *
	 * @access public
	 * @return String (comma separated list)
	 *
	 */
	function getGroupList($userId = '')
	{
		if(!empty($userId)) {
			$this->userId = $userId;
		}

		$sql = sprintf('SELECT groupId FROM %s WHERE userId = %s',USER2GROUP_TABLE,$this->userId);

		$db = &Cln_Db::singleton(MAIN_CLN_DSN);
		$result = $db->query($sql);
		if (PEAR::isError($result)) {
			PEAR::raiseError('Unable to select from '.USER2GROUP_TABLE.' table: '.$sql, E_WARNING);
			return FALSE;
		}

		$groups[] = '1'; // Add them to the Public group
		if ($this->isLoggedIn()) {
			$groups[] = '2'; // Add them to the Registered Users group
		}

		while($row = $result->fetchRow(DB_FETCHMODE_ASSOC)) {
			$groups[] = $row['groupId'];
		}

		return $groups;
	}


	/*
	 *
	 * Function:  reloadGroupList()
	 *
	 * 		returns an array of the groups this user is in
	 *
	 * @access public
	 * @return String (comma separated list)
	 *
	 */
	function reloadGroupList()
	{
		$this->groupList = $this->getGroupList();
	}


	/*
	 *
	 * Function:  getUserName()
	 *
	 * 		returns the name of the user
	 * 		stores user names in $_SESSION['userNames'];
	 *
	 * @access public
	 * @return String	name of user
	 *
	 */
	function getUserName($userId, $style=CLN_DEFAULT_PUBLIC_NAME)
	{
		$db = &Cln_Db::singleton(MAIN_CLN_DSN);

		if (!isset($_SESSION['userNames'])) {
			$sql = sprintf('SELECT userId,firstName,lastName, memberName FROM `%s`',USER_TABLE);
		}
		else if (!isset($_SESSION['userNames'][$userId])) {
			$sql = sprintf('SELECT userId,firstName,lastName, memberName FROM `%s` WHERE userId = %d',USER_TABLE,$userId);
		}
		if (isset($sql)) {
			$result = $db->query($sql);

			if (PEAR::isError($result)) {
				PEAR::raiseError('unable to select from '.USER_TABLE.' table: '.$sql, E_ERROR);
				return 'Unknown User';
			} else {
				while($row = $result->fetchRow(DB_FETCHMODE_OBJECT)) {
					$_SESSION['userNames'][($row->userId)]['firstName'] = stripslashes($row->firstName);
					$_SESSION['userNames'][($row->userId)]['lastName'] = stripslashes($row->lastName);
					$_SESSION['userNames'][($row->userId)]['memberName'] = stripslashes($row->memberName);
				}
			}
		}

		if (!isset($_SESSION['userNames'][$userId])) {
			return "Anonymous";
		}
		else if ($style == 'memberName') {
			return $_SESSION['userNames'][$userId]['memberName'];
		}
		else if ($style == 'firstName') {
			return $_SESSION['userNames'][$userId]['firstName'];
		}
		else {
			return $_SESSION['userNames'][$userId]['firstName'] . ' ' . $_SESSION['userNames'][$userId]['lastName'];
		}
	}
	
	
	/*
	 *
	 * Function:  getUserId()
	 *
	 * 		returns the userId of the user, based upon memberName
	 * 		stores user names in $_SESSION['userNames'];
	 *
	 * @access public
	 * @return String	name of user
	 *
	 */
	function getUserId($memberName)
	{
		if(isset($_SESSION['userNames'])) {
			foreach($_SESSION['userNames'] as $userId => $userName) {
				if(isset($userName['memberName']) && $userName['memberName'] == $memberName) {
					return $userId;
				}
			}
		}
		
		$db = &Cln_Db::singleton(MAIN_CLN_DSN);

		$sql = sprintf('SELECT userId,firstName,lastName, memberName FROM `%s` WHERE memberName = \'%s\'',USER_TABLE,$memberName);
		
		if (isset($sql)) {
			$result = $db->query($sql);

			if (PEAR::isError($result)) {
				PEAR::raiseError('unable to select from '.USER_TABLE.' table: '.$sql, E_ERROR);
				return 'Unknown User';
			} else {
				$row = $result->fetchRow(DB_FETCHMODE_OBJECT);
				$_SESSION['userNames'][($row->userId)]['firstName'] = stripslashes($row->firstName);
				$_SESSION['userNames'][($row->userId)]['lastName'] = stripslashes($row->lastName);
				$_SESSION['userNames'][($row->userId)]['memberName'] = stripslashes($row->memberName);
				
				return $row->userId;
			}
		}
	}
	

	/*
	 *
	 * Function:  getMyObjects()
	 *
	 * 		gets list of things based upon type and roles
	 *
	 * @access public
	 * @return String 	 $things
	 *
	 */
	function getMyStuff($type,$role)
	{

		include_once('Cln_KB_Search.php');

		$search = new Cln_KB_Search();

		$permissionSQL = $this->getMyShortcutSearch($type,$role);
		
		$search->fetchColumns = $search->fetchColumns.', ko.createdBy, ko.modifiedBy, ko.lang ';
		$search->customWheres = Array($permissionSQL);

		$search->nameValuePairs['userProcess'] = 'myShortcuts';

		ob_start();

		echo $search->getContent('lib/CLN/interfaces/User/myShortcuts.html');

		$content = ob_get_contents();
		ob_end_clean();

		return $content;
	}


	/*
	 *
	 * Function:  getMyShortcutSearch()
	 *
	 * 		forms part of sql for my shortcut search
	 *
	 * @access public
	 * @return TBD
	 *
	 */
	function getMyShortcutSearch($type,$role)
	{	
		$permissionSQL = '';
		
		if($type == 'room') {
			$typeQuery = 'AND ko.modId = 1';
		}
		else if($type == 'page') {
			$typeQuery = 'AND ko.modId = 2';
		}
		else if($type == 'block') {
			$typeQuery = 'AND (ko.modId != 1 && ko.modId != 2)';
		}
		else {
			$typeQuery = '';
		}

		if ($role == 'owner') {
			$roleId = 1;
		}
		else if ($role == 'publisher') {
			$roleId = 2;
		}
		else if ($role == 'collaborator') {
			$roleId = 3;
		}
		else if ($role == 'viewer') {
			$roleId = 4;
		}
		else {
			$roleId = 'creator';
		}

		if($roleId == 'creator') {
			$permissionSQL = sprintf('ko.createdBy = %d AND ko.status = 0 %s', $this->userId, $typeQuery);
		}
		else {
			// :NOTE: commented superuser overridding here, because it is confusing
			// perhaps we should provide a button to enable superusers to choose to gain access
			// to everything - dwc
			//if(!$_SESSION['User']->isSuperUser()) {
				$permissionSQL = 'AND perm.roleId = '.$roleId.' AND ko.koId = perm.koId';
			//} else {
			//	$permissionSQL = '';
			//}

			if($type == 'everything') {
				$permissionSQL = sprintf('ko.status = 0 %s', $permissionSQL);
			} else {
				$permissionSQL = sprintf('perm.groupId IN (%s) AND ko.status = 0 %s %s',
								implode(',',$this->groupList), $typeQuery, $permissionSQL);
			}
		}
		
		return $permissionSQL;
	}
	
	
	/*
	 *
	 * Function:  getUsersRoomId()
	 *
	 * 		gets the koId for the Users Room, based on the config CLN_USERS_ROOM
	 *
	 * @access public
	 * @return String 	 $things
	 *
	 */
	function getRoomId($path)
	{
		$db = &Cln_Db::singleton(MAIN_CLN_DSN);

		$pathParts = split('/','/'.$path);

		$currentThisId = 1;
		while(count($pathParts) > 1) {
			$currentParentId = $currentThisId;
			$status = $_SESSION['editMode'] == 'edit' ? 0 : 1;

			$sql = sprintf("SELECT child.koId, child.nodeName FROM %s AS child, %s AS parent
							WHERE child.parentId = parent.koId AND parent.koId = '%s'
							AND parent.nodeName = '%s' AND child.nodeName = '%s'
							AND child.status = %d AND child.status = parent.status",
							ROOM_NODE_TABLE, ROOM_NODE_TABLE, $currentParentId, $pathParts[0],
							$pathParts[1], $status);

			$result = $db->query($sql);

			if (PEAR::isError($result)) {
				PEAR::raiseError('Unable to select from '.ROOM_NODE_TABLE.' table: '.$sql, E_ERROR);
				return FALSE;
			}

			$row = $result->fetchRow(DB_FETCHMODE_OBJECT);

			if(!isset($row) || count($row) == 0) {
				PEAR::raiseError('Unable to locate '.$path, E_ERROR);
				return FALSE;
			}

			$currentThisId = $row->koId;

			// used to construct breadcrumb
			$lastKoId = $row->koId;

			array_shift($pathParts);
		}

		return $lastKoId;
	}


	/*
	 *
	 * Function:  isSuperUser()
	 *
	 * 		checks to see if the user is a superuser
	 *
	 * @access public
	 * @return String 	 $things
	 *
	 */
	function isSuperUser()
	{
		if(in_array(CLN_SUPERUSER_GROUPID,$_SESSION['User']->groupList)) {
			return TRUE;
		} else {
			return FALSE;
		}
	}
}

?>
Return current item: Community Learning Network