Index: branches/2.2/workflow/inc/class.so_userinterface.inc.php
===================================================================
--- branches/2.2/workflow/inc/class.so_userinterface.inc.php	(revision 1470)
+++ branches/2.2/workflow/inc/class.so_userinterface.inc.php	(revision 3167)
@@ -1,4 +1,3 @@
 <?php
-require_once($_SESSION['phpgw_info']['workflow']['phpgw_api_inc'] . '/class.config.inc.php');
 
 /**
@@ -22,5 +21,5 @@
 	function so_userinterface()
 	{
-		$this->db = &$GLOBALS['workflow']['workflowObjects']->getDBWorkflow()->Link_ID;
+		$this->db =& Factory::getInstance('WorkflowObjects')->getDBWorkflow()->Link_ID;
 		$this->db->SetFetchMode(ADODB_FETCH_ASSOC);
 	}
@@ -61,5 +60,5 @@
 		$oldDB = $GLOBALS['phpgw']->db;
 		$GLOBALS['phpgw']->db = $GLOBALS['ajax']->db;
-		$config = new config('workflow');
+		$config = &Factory::getInstance('config', 'workflow');
 		$configValues = $config->read_repository();
 		$submasksString = $configValues['intranet_subnetworks'];
@@ -93,5 +92,5 @@
 		if (!empty($externalApplicationsID))
 		{
-			$result = $GLOBALS['workflow']['workflowObjects']->getDBGalaxia()->Link_ID->query("SELECT DISTINCT external_application_id, name, address, image, authentication, intranet_only FROM egw_wf_external_application WHERE (external_application_id IN (" . implode(', ', $externalApplicationsID)  . ")) ORDER BY name");
+			$result = Factory::getInstance('WorkflowObjects')->getDBGalaxia()->Link_ID->query("SELECT DISTINCT external_application_id, name, address, image, authentication, intranet_only FROM egw_wf_external_application WHERE (external_application_id IN (" . implode(', ', $externalApplicationsID)  . ")) ORDER BY name");
 			$preOutput = $result->GetArray(-1);
 
@@ -234,5 +233,5 @@
 
 		/* gather some info from the area */
-		$areaInfo = $this->db->query('SELECT COALESCE(titular_funcionario_id, -1) AS titular_funcionario_id, COALESCE(substituto_funcionario_id, -1) AS substituto_funcionario_id FROM area WHERE (organizacao_id = ?) AND (area_id = ?)', array($organizationID, $areaID))->GetArray(-1);
+		$areaInfo = $this->db->query('SELECT COALESCE(a.titular_funcionario_id, -1) AS titular_funcionario_id, COALESCE(s.funcionario_id, -1) AS substituto_funcionario_id FROM area a LEFT OUTER JOIN substituicao s ON ((a.area_id = s.area_id) AND (CURRENT_DATE BETWEEN s.data_inicio AND s.data_fim)) WHERE (a.organizacao_id = ?) AND (a.area_id = ?)', array($organizationID, $areaID))->GetArray(-1);
 		if (empty($areaInfo))
 			return false;
@@ -245,5 +244,5 @@
 
 		$employees = $result->GetArray(-1);
-		$cachedLDAP = $GLOBALS['workflow']['factory']->newInstance('CachedLDAP');
+		$cachedLDAP = Factory::newInstance('CachedLDAP');
 		$cachedLDAP->setOperationMode($cachedLDAP->OPERATION_MODE_NORMAL);
 		$categoriesCount = array();
@@ -318,5 +317,5 @@
 
 		$employees = $result->GetArray(-1);
-		$cachedLDAP = $GLOBALS['workflow']['factory']->newInstance('CachedLDAP');
+		$cachedLDAP = Factory::newInstance('CachedLDAP');
 		$cachedLDAP->setOperationMode($cachedLDAP->OPERATION_MODE_NORMAL);
 		for ($i = 0; $i < count($employees); $i++)
@@ -334,5 +333,5 @@
 			{
 				$employees[$i]['telephoneNumber'] = is_null($entry['telephonenumber']) ? '' : $entry['telephonenumber'];
-				$employees[$i]['cn'] = is_null($entry['cn']) ? '' : $entry['cn'] . (is_null($entry['last_update']) ? ' <font color="red">(excluído)</font>' : '');
+				$employees[$i]['cn'] = is_null($entry['cn']) ? '' : $entry['cn'] . (is_null($entry['last_update']) ? ' <font color="red">(inativo)</font>' : '');
 			}
 		}
@@ -343,5 +342,5 @@
 
 	/**
-	 * Search Employee
+	 * Search Employee by Name
 	 * @param int $searchTerm term to search
 	 * @param int $organizationID  Id of organization
@@ -349,97 +348,238 @@
 	 * @access public
 	 */
-	function searchEmployee($searchTerm, $organizationID)
-	{
-		/* initialize some variables */
-		$output = array('employees' => array(), 'bygroup' => array( ) );
-		$ldapResult = array();
-
-		/* search for the $searchTerm in the LDAP */
-		$ldap = &$GLOBALS['workflow']['workflowObjects']->getLDAP();
+	function searchEmployeeByName($searchTerm, $organizationID)
+	{
+		/* get ldap connection */
+		$ldap = &Factory::getInstance('WorkflowObjects')->getLDAP();
 
 		$searchTermExploded = explode(" ", $searchTerm);
 		$fullSearch = false;
 
-		if(count($searchTermExploded) > 0){
-			for($i=1; $i<count($searchTermExploded); $i++){
-				if(strlen($searchTermExploded[$i]) > 2){
+		if (count($searchTermExploded) > 0){
+			for ($i=1; $i<count($searchTermExploded); $i++) {
+				if (strlen($searchTermExploded[$i]) > 2) {
 					$fullSearch = true;
 				}
 			}
 
-			if($fullSearch){
+			if ($fullSearch){
 				$searchTerm = implode("*", $searchTermExploded);
 			}
 		}
 
-		$list = @ldap_search($ldap, $GLOBALS['workflow']['factory']->getInstance('WorkflowLDAP')->getLDAPContext(), ('(&(cn=*' . $searchTerm . '*)(phpgwaccounttype=u))'), array('uidNumber', 'cn', 'telephoneNumber'));
+		/* searching employees by name in the ldap server */
+		$list = @ldap_search($ldap, Factory::getInstance('WorkflowLDAP')->getLDAPContext(), ('(&(cn=*' . $searchTerm . '*)(phpgwaccounttype=u))'), array('uidNumber', 'cn', 'telephoneNumber'));
 		if ($list === false)
 			return false;
 
+		/* parsing ldap result */
 		$entries = ldap_get_entries($ldap, $list);
-		$employeesID = array();
+		$ldapResult = array();
+
 		for ($i = 0; $i < $entries['count']; $i++)
 			$ldapResult[$entries[$i]['uidnumber'][0]] = array('cn' => $entries[$i]['cn'][0], 'telephoneNumber' => $entries[$i]['telephonenumber'][0]);
 
+		/* no records found. bye. */
+		if (count($ldapResult) == 0)
+			return array();
+
 		$uids = implode( ',', array_keys( $ldapResult ) );
 
-		/* load employee information */
-		$query = 'SELECT f.funcionario_id AS funcionario_id, f.area_id AS area_id, a.sigla AS area';
-		$query .= ' FROM funcionario f, area a, funcionario_status s';
-		$query .= " WHERE (f.area_id = a.area_id) AND (f.organizacao_id = {$organizationID})";
-		$query .= " AND (" . ( ( ! empty( $uids ) ) ? "f.funcionario_id IN ({$uids}) OR " : '' );
-		$query .= " a.sigla LIKE UPPER(?))";
-		$query .= " AND (f.funcionario_status_id = s.funcionario_status_id) AND (s.exibir = 'S')";
-		$query .= " ORDER BY a.sigla asc";
-
-		$result = $this->db->query($query, array( "%{$searchTerm}%" ) );
-
-		if ( ! $result )
-			return array( );
-
-		$uids = array( );
-
-		$employees = $result->GetArray(-1);
-		for ($i = 0; $i < count($employees); $i++)
-		{
-			for ($j = 0; $j < $result->_numOfFields; $j++)
-				unset($employees[$i][$j]);
-
-			if ( array_key_exists( $employees[$i]['funcionario_id'], $ldapResult ) )
-			{
-				$employees[$i]['cn'] = is_null($ldapResult[$employees[$i]['funcionario_id']]['cn']) ? '' : $ldapResult[$employees[$i]['funcionario_id']]['cn'];
-				$employees[$i]['telephoneNumber'] = is_null($ldapResult[$employees[$i]['funcionario_id']]['telephoneNumber']) ? '' : $ldapResult[$employees[$i]['funcionario_id']]['telephoneNumber'];
+		/* searching for aditional employee information */
+		$query  = "SELECT ";
+		$query .= "		f.funcionario_id AS funcionario_id, f.area_id AS area_id, a.sigla AS area ";
+		$query .= " FROM ";
+		$query .= "			funcionario f ";
+		$query .= "		INNER JOIN ";
+		$query .= "			area a USING (area_id) ";
+		$query .= "		INNER JOIN ";
+		$query .= "			funcionario_status s ON ((f.funcionario_status_id = s.funcionario_status_id) AND (s.exibir = 'S')) ";
+		$query .= " WHERE ";
+		$query .= "		(f.organizacao_id = ?) ";
+		$query .= " 	AND ";
+		$query .= "		(f.funcionario_id IN ({$uids})) ";
+
+		$result = $this->db->query($query, array($organizationID))->GetArray(-1);
+		$employees = array();
+
+		/* filling return array with employee's information */
+		for ($i = 0; $i < count($result); $i++) {
+			$employees []= array(
+					'area'	 			=> $result[$i]['area'],
+					'area_id' 			=> $result[$i]['area_id'],
+					'funcionario_id'	=> $result[$i]['funcionario_id'],
+					'cn'			 	=> $ldapResult[$result[$i]['funcionario_id']]['cn'],
+					'telephoneNumber'	=> empty($ldapResult[$result[$i]['funcionario_id']]['telephoneNumber']) ? '': $ldapResult[$result[$i]['funcionario_id']]['telephoneNumber']
+			);
+		}
+
+		/* sorting by name (cn) */
+        $sort_function = create_function('$a, $b', 'return strcasecmp($a[\'cn\'],$b[\'cn\']);');
+        usort($employees, $sort_function );
+
+		return $employees;
+	}
+
+	/**
+	 * Search Employee by Area
+	 * @param int $searchTerm term to search
+	 * @param int $organizationID  Id of organization
+	 * @return array employee data information
+	 * @access public
+	 */
+	function searchEmployeeByArea($searchTerm, $organizationID)
+	{
+		/* get ldap connection */
+		$ldap = &Factory::getInstance('WorkflowObjects')->getLDAP();
+
+		/* makes no sense search for an area if the string has more than one word */
+		if (count(explode(" ", $searchTerm)) > 1)
+			return array();
+
+		/* searching for employees in areas that match 'searchTerm' */
+		$query  = "SELECT ";
+		$query .= "		f.funcionario_id AS funcionario_id, f.area_id AS area_id, a.sigla AS area ";
+		$query .= " FROM ";
+		$query .= "			funcionario f ";
+		$query .= "		INNER JOIN ";
+		$query .= "			area a USING (area_id) ";
+		$query .= "		INNER JOIN ";
+		$query .= "			funcionario_status s ON ((f.funcionario_status_id = s.funcionario_status_id) AND (s.exibir = 'S')) ";
+		$query .= " WHERE ";
+		$query .= "		(f.organizacao_id = ?) ";
+		$query .= " 	AND ";
+		$query .= "		(UPPER(a.sigla) LIKE UPPER(?)) ";
+
+		$result = $this->db->query($query, array($organizationID, '%'.$searchTerm.'%'))->GetArray(-1);
+	
+		/* no records found. bye */
+		if (count($result) == 0)
+			return array();
+
+		/* creating the ldap query */
+		$ldap_query = '(&(|';
+		for ($i = 0; $i < count($result); $i++) {
+			$ldap_query .= '(uidNumber=' . $result[$i]['funcionario_id'] . ')';
+		}
+		$ldap_query .= ')(phpgwAccountType=u))';
+
+		/* executing it */
+		$list = @ldap_search($ldap, Factory::getInstance('WorkflowLDAP')->getLDAPContext(), $ldap_query, array('uidNumber', 'cn', 'telephoneNumber'));
+		$entries = ldap_get_entries($ldap, $list);
+
+		/* parsing result */
+		$ldapResult = array();
+		for ($i = 0; $i < $entries['count']; $i++)
+			$ldapResult[$entries[$i]['uidnumber'][0]] = array('cn' => $entries[$i]['cn'][0], 'telephoneNumber' => $entries[$i]['telephonenumber'][0]);
+
+		/* we will need to search into database 'cache' for users deleted in ldap */
+		$cachedLDAP = Factory::newInstance( 'CachedLDAP' );
+		$cachedLDAP -> setOperationMode( $cachedLDAP -> OPERATION_MODE_DATABASE );
+
+		/* filling return array with employee's information */
+		$employees = array();
+		for ($i = 0; $i < count($result); $i++) {
+
+			$employee = array();
+
+			/* user deleted in ldap. Let's try to find him into database 'cache' */
+			if (empty($ldapResult[$result[$i]['funcionario_id']]['cn'])) {
+				$entry = $cachedLDAP->getEntryByID($result[$i]['funcionario_id']);
+
+				$employee['removed'] = is_null($entry['last_update']);
+
+				if ($entry && !empty($entry['cn']))
+					$employee['cn']	= $entry['cn'];
+				/* we cant find it anywhere */
+				else
+					$employee['cn']	= $result[$i]['funcionario_id'];
 			}
 			else
-			{
-				$employees[$i]['cn'] = $employees[$i]['funcionario_id'];
-				$employees[$i]['telephoneNumber'] = '';
-
-				$output['bygroup'][ $employees[$i]['funcionario_id'] ] = $employees[ $i ];
-				array_splice( $employees, $i--, 1 );
-			}
-		}
-
-		if ( count( $output['bygroup'] ) )
-		{
-			$list = ldap_search($ldap, $GLOBALS['workflow']['factory']->getInstance('WorkflowLDAP')->getLDAPContext(), ('(&(|(uidNumber=' . implode( ')(uidNumber=', array_keys( $output['bygroup'] ) ) . '))(phpgwaccounttype=u))'), array('uidNumber', 'cn', 'telephoneNumber'));
-
-			if ( $list !== false )
-			{
-				$entries = ldap_get_entries($ldap, $list);
-
-				for ( $i = 0; $i < $entries[ 'count' ]; $i++ )
-				{
-					$output[ 'bygroup' ][ $entries[$i]['uidnumber'][0] ][ 'cn' ] = $entries[$i]['cn'][0];
-					$output[ 'bygroup' ][ $entries[$i]['uidnumber'][0] ][ 'telephoneNumber' ] = $entries[$i]['telephonenumber'][0];
-				}
-			}
-		}
-
-		$output[ 'bygroup' ] = array_values( $output[ 'bygroup' ] );
-		$output[ 'employees' ] = $employees;
-
-		return $output;
-	}
+				$employee['cn']	= $ldapResult[$result[$i]['funcionario_id']]['cn'];
+
+			$employee['area']	 			= $result[$i]['area'];
+			$employee['area_id'] 			= $result[$i]['area_id'];
+			$employee['funcionario_id'] 	= $result[$i]['funcionario_id'];
+			$employee['telephoneNumber']	= empty($ldapResult[$result[$i]['funcionario_id']]['telephoneNumber']) ? '': $ldapResult[$result[$i]['funcionario_id']]['telephoneNumber'];
+
+			$employees []= $employee;
+		}
+
+		/* sorting by name (cn) */
+        $sort_function = create_function('$a, $b', 'return strcasecmp($a[\'cn\'],$b[\'cn\']);');
+        usort($employees, $sort_function );
+
+		return $employees;
+	}
+
+	/**
+	 * Search Employee by Telephone
+	 * @param int $searchTerm term to search
+	 * @param int $organizationID  Id of organization
+	 * @return array employee data information
+	 * @access public
+	 */
+	function searchEmployeeByTelephone($searchTerm, $organizationID)
+	{
+		/* we will just excute it if we just get numbers and '-' */
+		if (!preg_match('/^[0-9-]+$/', $searchTerm))
+			return array();
+
+		/* get ldap connection */
+		$ldap = &Factory::getInstance('WorkflowObjects')->getLDAP();
+
+		/* searching employees by telephoneNumber in the ldap server */
+		$list = @ldap_search($ldap, Factory::getInstance('WorkflowLDAP')->getLDAPContext(), ('(&(telephoneNumber=*' . $searchTerm . '*)(phpgwaccounttype=u))'), array('uidNumber', 'cn', 'telephoneNumber'));
+
+		if (!$list) return false;
+
+		/* parsing ldap result */
+		$entries = ldap_get_entries($ldap, $list);
+		$ldapResult = array();
+
+		for ($i = 0; $i < $entries['count']; $i++)
+			$ldapResult[$entries[$i]['uidnumber'][0]] = array('cn' => $entries[$i]['cn'][0], 'telephoneNumber' => $entries[$i]['telephonenumber'][0]);
+
+		/* no records found. bye. */
+		if (count($ldapResult) == 0)
+			return array();
+
+		$uids = implode( ',', array_keys( $ldapResult ) );
+
+		/* searching for aditional employee information */
+		$query  = "SELECT ";
+		$query .= "		f.funcionario_id AS funcionario_id, f.area_id AS area_id, a.sigla AS area ";
+		$query .= " FROM ";
+		$query .= "			funcionario f ";
+		$query .= "		INNER JOIN ";
+		$query .= "			area a USING (area_id) ";
+		$query .= "		INNER JOIN ";
+		$query .= "			funcionario_status s ON ((f.funcionario_status_id = s.funcionario_status_id) AND (s.exibir = 'S')) ";
+		$query .= " WHERE ";
+		$query .= "		(f.organizacao_id = ?) ";
+		$query .= " 	AND ";
+		$query .= "		(f.funcionario_id IN ({$uids})) ";
+
+		$result = $this->db->query($query, array($organizationID))->GetArray(-1);
+		$employees = array();
+
+		/* filling return array with employee's information */
+		for ($i = 0; $i < count($result); $i++) {
+			$employees []= array(
+					'area'	 			=> $result[$i]['area'],
+					'area_id'	 		=> $result[$i]['area_id'],
+					'funcionario_id'	=> $result[$i]['funcionario_id'],
+					'cn'			 	=> $ldapResult[$result[$i]['funcionario_id']]['cn'],
+					'telephoneNumber'	=> empty($ldapResult[$result[$i]['funcionario_id']]['telephoneNumber']) ? '': $ldapResult[$result[$i]['funcionario_id']]['telephoneNumber']
+			);
+		}
+
+		/* sorting by name (cn) */
+        $sort_function = create_function('$a, $b', 'return strcasecmp($a[\'cn\'],$b[\'cn\']);');
+        usort($employees, $sort_function );
+
+		return $employees;
+	}
+
 
 	/**
@@ -453,7 +593,5 @@
 	function getEmployeeInfo($employeeID, $organizationID)
 	{
-		require_once dirname(__FILE__) . '/class.so_orgchart.inc.php';
-
-		$SOOrgchart = new so_orgchart();
+		$SOOrgchart = &Factory::getInstance('so_orgchart');
 		$SOOrgchart->setExternalCalls(true);
 		$output = $SOOrgchart->getEmployeeInfo($employeeID, $organizationID);
@@ -473,7 +611,5 @@
 	function getAreaInfo($areaID, $organizationID)
 	{
-		require_once dirname(__FILE__) . '/class.so_orgchart.inc.php';
-
-		$SOOrgchart = new so_orgchart();
+		$SOOrgchart = &Factory::getInstance('so_orgchart');
 		$SOOrgchart->setExternalCalls(true);
 		$output = $SOOrgchart->getAreaInfo($areaID, $organizationID);
@@ -509,7 +645,7 @@
 	function getAreaWithSubtituteBoss( $organizationID )
 	{
-		$result = $this -> db -> query( "SELECT sigla as area, titular_funcionario_id as titular, substituto_funcionario_id as substituto FROM area WHERE (organizacao_id = ?) and substituto_funcionario_id is not null ORDER BY area", array( $organizationID ) );
-
-		$cachedLDAP = $GLOBALS[ 'workflow' ][ 'factory' ] -> newInstance( 'CachedLDAP' );
+		$result = $this -> db -> query( "SELECT a.sigla as area, a.titular_funcionario_id as titular, s.funcionario_id as substituto, s.data_inicio, s.data_fim FROM area a INNER JOIN substituicao s ON ((a.area_id = s.area_id) AND (CURRENT_DATE BETWEEN s.data_inicio AND s.data_fim)) WHERE (organizacao_id = ?) ORDER BY area", array( $organizationID ) );
+
+		$cachedLDAP = Factory::newInstance( 'CachedLDAP' );
 		$cachedLDAP -> setOperationMode( $cachedLDAP -> OPERATION_MODE_LDAP_DATABASE );
 
@@ -527,4 +663,7 @@
 			if ( $entry && ( ! is_null( $entry[ 'cn' ] ) ) )
 				$output[ $i ][ 'substituto' ] = $entry[ 'cn' ];
+
+			$output[$i]['data_inicio'] = implode('/', array_reverse(explode('-', $output[$i]['data_inicio'])));
+			$output[$i]['data_fim'] = implode('/', array_reverse(explode('-', $output[$i]['data_fim'])));
 		}
 
@@ -575,5 +714,5 @@
 
 		$employees = $result -> GetArray( -1 );
-		$cachedLDAP = $GLOBALS[ 'workflow' ][ 'factory' ] -> newInstance( 'CachedLDAP' );
+		$cachedLDAP = Factory::newInstance( 'CachedLDAP' );
 		$cachedLDAP -> setOperationMode( $cachedLDAP -> OPERATION_MODE_NORMAL );
 
@@ -647,5 +786,5 @@
 		$employees = $result -> GetArray( -1 );
 
-		$cachedLDAP = $GLOBALS[ 'workflow' ][ 'factory' ] -> newInstance( 'CachedLDAP' );
+		$cachedLDAP = Factory::newInstance( 'CachedLDAP' );
 		$cachedLDAP -> setOperationMode( $cachedLDAP -> OPERATION_MODE_NORMAL );
 
@@ -673,5 +812,5 @@
 		usort( $employees, create_function( '$a,$b', 'return strcasecmp($a[\'cn\'],$b[\'cn\']);' ) );
 
-		$paging = $GLOBALS['workflow']['factory']->newInstance('Paging', 50, $_POST);
+		$paging = Factory::newInstance('Paging', 50, $_POST);
 		$employees = $paging->restrictItems( $employees );
 
