<?php
	/**
	* View and manipulate account records using SQL
	* @author Joseph Engo <jengo@phpgroupware.org>
	* @author Dan Kuykendall <seek3r@phpgroupware.org>
	* @author Bettina Gille <ceb@phpgroupware.org>
	* @copyright Copyright (C) 2000-2004 Free Software Foundation, Inc. http://www.fsf.org/
	* @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License
	* @package phpgwapi
	* @subpackage accounts
	* @version $Id: class.accounts_sql.inc.php,v 1.1.1.4.6.1 2004/09/27 10:08:27 kazuyan Exp $
	*/

	/**
	* View and manipulate handling user and group account records using SQL
	*
	* @package phpgwapi
	* @subpackage accounts
	*/
	class accounts extends accounts_
	{
		function accounts($account_id = '', $account_type = '')
		{
			$this->accounts_($account_id, $account_type);
		}

		function list_methods($_type='xmlrpc')
		{
			if (is_array($_type))
			{
				$_type = $_type['type'] ? $_type['type'] : $_type[0];
			}

			switch($_type)
			{
				case 'xmlrpc':
					$xml_functions = array(
						'get_list' => array(
							'function'  => 'get_list',
							'signature' => array(array(xmlrpcStruct)),
							'docstring' => lang('Returns a full list of accounts on the system.  Warning: This is return can be quite large')
						),
						'list_methods' => array(
							'function'  => 'list_methods',
							'signature' => array(array(xmlrpcStruct,xmlrpcString)),
							'docstring' => lang('Read this list of methods.')
						)
					);
					return $xml_functions;
					break;
 				case 'soap':
					return $this->soap_functions;
					break;
				default:
					return array();
					break;
			}
		}

		/**
		* Read account information from database
		*
		* @return array Array with the following information: userid, account_id, account_lid, firstname, lastname, account_firstname, account_lastname, fullname, lastlogin, lastloginfrom, lastpasswd_change, status, expires, person_id
		*/
		function read_repository()
		{
			$this->db->query('SELECT * FROM phpgw_accounts WHERE account_id=' . intval($this->account_id),__LINE__,__FILE__);
			$this->db->next_record();

			$this->data['userid']				= $this->db->f('account_lid');
			$this->data['account_id']			= $this->db->f('account_id');
			$this->data['account_lid']			= $this->db->f('account_lid');
			$this->data['firstname']			= $this->db->f('account_firstname');
			$this->data['lastname']				= $this->db->f('account_lastname');
			$this->data['account_firstname']	= $this->db->f('account_firstname');
			$this->data['account_lastname']		= $this->db->f('account_lastname');
			$this->data['fullname']				= $this->db->f('account_firstname') 
								  				. ' ' . $this->db->f('account_lastname');
			$this->data['lastlogin']			= $this->db->f('account_lastlogin');
			$this->data['lastloginfrom']		= $this->db->f('account_lastloginfrom');
			$this->data['lastpasswd_change']	= $this->db->f('account_lastpwd_change');
			$this->data['status']				= trim($this->db->f('account_status'));
			$this->data['expires']				= $this->db->f('account_expires');
			$this->data['person_id']			= $this->db->f('person_id');
			$this->data['quota']				= $this->db->f('account_quota');
			return $this->data;
		}

		/**
		* Save/update account information to/in database
		*/
		function save_repository()
		{
			$this->db->query("UPDATE phpgw_accounts SET account_firstname='" . $this->data['account_firstname']
							. "', account_lastname='" . $this->data['account_lastname'] . "', account_status='"
							. $this->data['status'] . "', account_expires=" . $this->data['expires']
							. ($this->data['account_lid']?", account_lid='".$this->data['account_lid']."'":'')
							. ($this->data['person_id']?', person_id=' . $this->data['person_id']:'') . ', account_quota=' . intval($this->data['quota'])
							. ' WHERE account_id=' . intval($this->account_id),__LINE__,__FILE__);
		}

		function delete($accountid = '')
		{
			$account_id = get_account_id($accountid);

			/* Do this last since we are depending upon this record to get the account_lid above */
			$tables_array = Array('phpgw_accounts');
			$this->db->lock($tables_array);
			$this->db->query('DELETE FROM phpgw_accounts WHERE account_id=' . $account_id);
			$this->db->unlock();
		}

		function get_list($_type='both',$start = -1,$sort = '', $order = '', $query = '', $offset = -1)
		{
			// For XML-RPC
/*			if (is_array($_type))
			{
				$p      = $_type;
				$_type  = $p[0]['type'];
				$start  = $p[0]['start'];
				$order  = $p[0]['order'];
				$query  = $p[0]['query'];
				$offset = $p[0]['offset'];
			}
*/
			if (! $sort)
			{
				$sort = "DESC";
			}

			if ($order)
			{
				$orderclause = "ORDER BY $order $sort";
			}
			else
			{
				$orderclause = "ORDER BY account_lid ASC";
			}

			switch($_type)
			{
				case 'accounts':
					$whereclause = "WHERE account_type = 'u'";
					break;
				case 'groups':
					$whereclause = "WHERE account_type = 'g'";
					break;
				default:
					$whereclause = '';
			}

			if ($query)
			{
				$query = $this->db->db_addslashes($query);
				if ($whereclause)
				{
					$whereclause .= ' AND ( ';
				}
				else
				{
					$whereclause = ' WHERE ( ';
				}

				$whereclause .= " account_firstname LIKE '%$query%' OR account_lastname LIKE "
					. "'%$query%' OR account_lid LIKE '%$query%' OR person_id LIKE '%$query%')";
			}

			$sql = "SELECT * FROM phpgw_accounts $whereclause $orderclause";
			if ($offset == -1 && $start == -1)
			{
				$this->db->query($sql,__LINE__,__FILE__);
			} 
			elseif ($start != -1)
			{
				$this->db->limit_query($sql,$start,__LINE__,__FILE__);
			}
			else
			{
				$this->db->limit_query($sql,$start,__LINE__,__FILE__,$offset);
			}

			while ($this->db->next_record())
			{
				$accounts[] = Array(
					'account_id'        => $this->db->f('account_id'),
					'account_lid'       => $this->db->f('account_lid'),
					'account_type'      => $this->db->f('account_type'),
					'account_firstname' => $this->db->f('account_firstname'),
					'account_lastname'  => $this->db->f('account_lastname'),
					'account_status'    => $this->db->f('account_status'),
					'account_expires'   => $this->db->f('account_expires'),
					'person_id'			=> $this->db->f('person_id')
				);
			}
			$this->db->query("SELECT count(*) FROM phpgw_accounts $whereclause");
			$this->db->next_record();
			$this->total = $this->db->f(0);

			return $accounts;
		}

		function name2id($account_lid)
		{
			static $name_list;

			if (! $account_lid)
			{
				return False;
			}

			if($name_list[$account_lid] && $name_list[$account_lid] != '')
			{
				return $name_list[$account_lid];
			}

			$account_lid = $this->db->db_addslashes($account_lid);

			$this->db->query('SELECT account_id FROM phpgw_accounts '
				. " WHERE account_lid='" . $account_lid . "'",__LINE__,__FILE__);
			if($this->db->num_rows())
			{
				$this->db->next_record();
				$name_list[$account_lid] = intval($this->db->f('account_id'));
			}
			else
			{
				$name_list[$account_lid] = False;
			}
			return $name_list[$account_lid];
		}

		function id2name($account_id)
		{
			static $id_list;

			if (! $account_id)
			{
				return False;
			}

			if($id_list[$account_id])
			{
				return $id_list[$account_id];
			}

			$this->db->query('SELECT account_lid FROM phpgw_accounts WHERE account_id=' . intval($account_id),__LINE__,__FILE__);
			if($this->db->num_rows())
			{
				$this->db->next_record();
				$id_list[$account_id] = $this->db->f('account_lid');
			}
			else
			{
				$id_list[$account_id] = False;
			}
			return $id_list[$account_id];
		}

		function search_person($person_id)
		{
			static $person_list;

			if (! $person_id)
			{
				return False;
			}

			if($person_list[$person_id])
			{
				return $person_list[$person_id];
			}

			$this->db->query('SELECT account_id FROM phpgw_accounts WHERE person_id=' . intval($person_id) ,__LINE__,__FILE__);
			if($this->db->num_rows())
			{
				$this->db->next_record();
				$person_list[$person_id] = $this->db->f('account_id');
			}
			else
			{
				$person_list[$person_id] = False;
			}
			return $person_list[$person_id];
		}

		function get_type($accountid)
		{
			static $account_type;
			$account_id = get_account_id($accountid);
			
			if (isset($this->account_type) && $account_id == $this->account_id)
			{
				return $this->account_type;
			}

			if(@isset($account_type[$account_id]) && @$account_type[$account_id])
			{
				return $account_type[$account_id];
			}
			elseif($account_id == '')
			{
				return False;
			}
			$this->db->Halt_On_Error = 'no';
			$this->db->query('SELECT account_type FROM phpgw_accounts WHERE account_id=' .intval($account_id), __LINE__,__FILE__);
			if ($this->db->num_rows())
			{
				$this->db->next_record();
				$account_type[$account_id] = $this->db->f('account_type');
			}
			else
			{
				$account_type[$account_id] = False;
			}
			$this->db->Halt_On_Error = 'yes';
			return $account_type[$account_id];
		}

		function exists($account_lid) // imho this should take $id, $lid as args
		{
			static $by_id, $by_lid;

			$sql = 'SELECT count(account_id) FROM phpgw_accounts WHERE ';
			if(is_integer($account_lid))
			{
				if(@isset($by_id[$account_lid]) && $by_id[$account_lid] != '')
				{
					return $by_id[$account_lid];
				}
				$sql .= 'account_id=' . intval($account_lid);
			}
			else
			{
				if(@isset($by_lid[$account_lid]) && $by_lid[$account_lid] != '')
				{
					return $by_lid[$account_lid];
				}
				$sql .= "account_lid = '" . $this->db->db_addslashes($account_lid) . "'";
			}

			$this->db->query($sql,__LINE__,__FILE__);
			$this->db->next_record();
			$ret_val = $this->db->f(0) > 0;
			if(is_integer($account_lid))
			{
				$by_id[$account_lid] = $ret_val;
				$by_lid[$this->id2name($account_lid)] = $ret_val;
			}
			else
			{
				$by_lid[$account_lid] = $ret_val;
				$by_id[$this->name2id($account_lid)] = $ret_val;
			}
			return $ret_val;
		}

		function create($account_info,$default_prefs=True)
		{
			if(!isset($account_info['person_id']) || $account_info['person_id']=='')
			{
				$account_info['person_id']='NULL';
			}
			

			$this->db->query('INSERT INTO phpgw_accounts (account_lid, account_type, account_pwd,'
							. 'account_firstname, account_lastname, account_status, account_expires,'
							. 'person_id,account_quota) '
							. "VALUES ('" . $this->db->db_addslashes($account_info['account_lid']) . "',"
							. "'" . $this->db->db_addslashes($account_info['account_type']) . "',"
							. "'" . md5($account_info['account_passwd']) . "',"
							. "'" . $this->db->db_addslashes($account_info['account_firstname']) . "',"
							. "'" . $this->db->db_addslashes($account_info['account_lastname']) . "',"
							. "'" . $this->db->db_addslashes($account_info['account_status']) . "',"
							. intval($account_info['account_expires']) . ',' . intval($account_info['person_id'])
							. ',' . intval($account_info['quota']) . ')',__LINE__,__FILE__);

			$accountid = $this->db->get_last_insert_id('phpgw_accounts','account_id');
			if($accountid && is_object($GLOBALS['phpgw']->preferences) && $default_prefs)
			{
				$GLOBALS['phpgw']->preferences->create_defaults($accountid);
			}
			return $accountid;
		}

		function auto_add($accountname, $passwd, $default_prefs = False, $default_acls = False, $expiredate = 0, $account_status = 'A')
		{
			if ($expiredate)
			{
				$expires = mktime(2,0,0,date('n',$expiredate), intval(date('d',$expiredate)), date('Y',$expiredate));
			}
			else
			{
				if($GLOBALS['phpgw_info']['server']['auto_create_expire'])
				{
					if($GLOBALS['phpgw_info']['server']['auto_create_expire'] == 'never')
					{
						$expires = -1;
					}
					else
					{
						$expiredate = time() + $GLOBALS['phpgw_info']['server']['auto_create_expire'];
						$expires   = mktime(2,0,0,date('n',$expiredate), intval(date('d',$expiredate)), date('Y',$expiredate));
					}
				}
				else
				{
					/* expire in 30 days by default */
					$expiredate = time() + ( ( 60 * 60 ) * (30 * 24) );
					$expires   = mktime(2,0,0,date('n',$expiredate), intval(date('d',$expiredate)), date('Y',$expiredate));
				}
			}

			$acct_info = array(
				'account_lid'       => $accountname,
				'account_type'      => 'u',
				'account_passwd'    => $passwd,
				'account_firstname' => '',
				'account_lastname'  => '',
				'account_status'    => $account_status,
				'account_expires'   => $expires,
				'person_id'			=> 'NULL'
			);

			$this->db->transaction_begin();
			$this->create($acct_info,$default_prefs);
			$accountid = $this->name2id($accountname);

			// this should be done via the acl class not direct db calls
			if ($default_acls == False)
			{
				$default_group_lid = intval($GLOBALS['phpgw_info']['server']['default_group_lid']);
				$default_group_id  = $this->name2id($default_group_lid);
				$defaultgroupid = $default_group_id ? $default_group_id : $this->name2id('Default');
				if ($defaultgroupid)
				{
					$this->db->query('INSERT INTO phpgw_acl (acl_appname, acl_location, acl_account, acl_rights) '
						. "VALUES('phpgw_group', " . $defaultgroupid . ', ' 
						.	intval($accountid) . ', 1'
						. ')',__LINE__,__FILE__);
					$this->db->query('INSERT INTO phpgw_acl (acl_appname, acl_location, acl_account, acl_rights) '
						. "VALUES('preferences' , 'changepassword', " 
						.	intval($accountid) . ', 1'
						. ')',__LINE__,__FILE__);
				}
				else
				{
					// If they don't have a default group, they need some sort of permissions.
					// This generally doesn't / shouldn't happen, but will (jengo)
					$this->db->query("insert into phpgw_acl (acl_appname, acl_location, acl_account, acl_rights) values('preferences', 'changepassword', " . $accountid . ', 1)',__LINE__,__FILE__);

					$apps = Array(
						'addressbook',
						'calendar',
						'email',
						'notes',
						'todo',
						'phpwebhosting',
						'manual'
					);

					@reset($apps);
					while(list($key,$app) = each($apps))
					{
						$this->db->query("INSERT INTO phpgw_acl (acl_appname, acl_location, acl_account, acl_rights) VALUES ('" . $app . "', 'run', " . intval($accountid) . ', 1)',__LINE__,__FILE__);
					}
				}
			}
			$this->db->transaction_commit();
			return $accountid;
		}

		function get_account_name($accountid,&$lid,&$fname,&$lname)
		{
			static $account_name;
			
			$account_id = get_account_id($accountid);
			if(isset($account_name[$account_id]))
			{
				$lid = $account_name[$account_id]['lid'];
				$fname = $account_name[$account_id]['fname'];
				$lname = $account_name[$account_id]['lname'];
				return;
			}
			$db = $GLOBALS['phpgw']->db;
			$db->query('select account_lid,account_firstname,account_lastname from phpgw_accounts where account_id=' . intval($account_id),__LINE__,__FILE__);
			$db->next_record();
			$account_name[$account_id]['lid']   = $db->f('account_lid');
			$account_name[$account_id]['fname'] = $db->f('account_firstname');
			$account_name[$account_id]['lname'] = $db->f('account_lastname');
			$lid   = $account_name[$account_id]['lid'];
			$fname = $account_name[$account_id]['fname'];
			$lname = $account_name[$account_id]['lname'];
			return;
		}

		function get_account_data($account_id)
		{
			$this->account_id = $account_id;
			$this->read_repository();

			$data[$this->data['account_id']]['lid']       = $this->data['account_lid'];
			$data[$this->data['account_id']]['firstname'] = $this->data['firstname'];
			$data[$this->data['account_id']]['lastname']  = $this->data['lastname'];
			$data[$this->data['account_id']]['fullname']  = $this->data['fullname'];
			$data[$this->data['account_id']]['type']      = $this->data['account_type'];
			$data[$this->data['account_id']]['person_id']      = $this->data['person_id'];
			return $data;
		}
		
		function get_account_with_contact()
		{
			$sql = 'SELECT account_id, person_id FROM phpgw_accounts '
				. 'WHERE person_id IS NOT NULL OR person_id != 0';
			$this->db->query($sql,__LINE__,__FILE__);
			while ($this->db->next_record())
			{
				$accounts[$this->db->f('account_id')] = $this->db->f('person_id');
			}
			return $accounts;
		}

		function get_account_without_contact()
		{
			$sql = 'SELECT account_id FROM phpgw_accounts '
				. 'WHERE person_id IS NULL OR person_id = 0';
			$this->db->query($sql,__LINE__,__FILE__);
			while ($this->db->next_record())
			{
				$accounts[] = $this->db->f('account_id');
			}
			return $accounts;
		}
	}
?>
