Index: inc/class.ipc_addressbook.inc.php
===================================================================
RCS file: /cvsroot/phpgroupware/addressbook/inc/Attic/class.ipc_addressbook.inc.php,v
retrieving revision 1.1.2.1
diff -u -r1.1.2.1 class.ipc_addressbook.inc.php
--- inc/class.ipc_addressbook.inc.php	24 Feb 2004 18:01:35 -0000	1.1.2.1
+++ inc/class.ipc_addressbook.inc.php	26 Nov 2004 10:54:25 -0000
@@ -1,168 +1,243 @@
 <?php
 	/**
 	* IPC Layer
-	*
-	* @author      Dirk Schaller <dschaller@probusiness.de>
-	* @copyright   Copyright (C) 2003 Free Software Foundation http://www.fsf.org/
-	* @license     http://www.fsf.org/licenses/gpl.html GNU General Public License
-	* @package     phpgwapi
-	* @subpackage  ipc
-	* @version     $Id: class.ipc_addressbook.inc.php,v 1.1.2.1 2004/02/24 18:01:35 jarg Exp $
+	* @author Dirk Schaller <dschaller@probusiness.de>
+	* @copyright Copyright (C) 2003-2004, Free Software Foundation, Inc. http://www.fsf.org/
+	* @license http://www.fsf.org/licenses/gpl.html GNU General Public License
+	* @package phpgwapi
+	* @subpackage ipc
+	* @version $Id: class.ipc_addressbook.inc.php,v 1.1.2.1.52.16 2004/10/20 14:12:33 cwederhake Exp $
 	*/
 
-
 	/**
 	* Fassade of the adressbook application.
-	*
-	* @package  notes
+	* @package addressbook
 	*/
 	class ipc_addressbook extends ipc_
 	{
 		/**
-		* @var     object   $contacts  phpgwapi contacts object
-		* @access  private
+		* @var object $contacts phpgwapi contacts object
+		* @access private
 		*/
 		var $contacts;
 
 		/**
-		* @var     object   $vcard  import/export vcard object
-		* @access  private
+		* @var object $vcard import/export vcard object
+		* @access private
 		*/
 		var $vcard;
-	
+		
+		/**
+		* @var object $validator object of validator class for check email syntax
+		* @access private
+		*/
+		var $validator;
+
 
 		/**
 		* Constructor
-		*
-		* @access  public
 		*/
 		function ipc_addressbook()
 		{
-			$this->contacts = CreateObject('phpgwapi.contacts');
-			$this->vcard    = CreateObject('phpgwapi.vcard');
+			$this->contacts  = CreateObject('phpgwapi.contacts');
+			$this->vcard     = CreateObject('phpgwapi.vcard');
+			$this->validator = CreateObject('phpgwapi.validator');
 		}
   
 
 		/**
 		* Add data in a certain mime type format to the application.
-		*
-		* @access  public
-		* @param   mixed    $data  data for adding to the application, the datatype depends on the mime type
-		* @param   string   $type  specifies the mime type of the passed data
-		* @return  integer         id of the added data
+		* @param mixed $data data for adding to the application, the datatype depends on the mime type
+		* @param string $type specifies the mime type of the passed data
+		* @param string $version specifies the mime type version of the passed data (still no need for this because the version would be recognized automaticly)
+		* @param string $timestamp the timestamp is used to set in db instead of current time
+    * @return integer id of the added data
 		*/
-		function addData($data, $type)
+		function addData($data, $type, $version='', $timestamp=null)
 		{
+			$fields = array();
+
 			// 1: mapping the mime type to application data
-			if($type != 'text/x-vcard')
+			$convertTypeIn     = $type;
+			$convertVersionIn  = $version;
+			$convertTypeOut    = 'x-phpgroupware/addressbook-appl-data-array';
+			$convertVersionOut = '';
+
+			$fields = $this->convertData($data, $convertTypeIn, $convertVersionIn, $convertTypeOut, $convertVersionOut);
+			if(count($fields) == 0)
 				return false;
 
-			$data = ereg_replace("\n\n", "\r\n", $data);
-			$data_lines = explode("\r\n", $data);
-		
-			$buffer = array();
-			$temp_line = '';
+			if(!isset($fields['owner']) || !$fields['owner'])
+				$fields['owner'] = $GLOBALS['phpgw_info']['user']['account_id'];
 
-			while(list(, $line) = each($data_lines))
-			{
-				$line = trim($line);
-				if(substr($line, -1) == '=')
-				{
-					// '=' at end-of-line --line to be continued with next line
-					$temp_line .= substr($line, 0, -1);
-					continue;
-				}
-				else
-				{
-					$line = $temp_line . $line;
-					$temp_line = ''; // important for next line which ends with =
-				}
-
-				if (strstr($line, 'BEGIN:VCARD'))
-				{
-					// added for p800 vcards: problem if vcard starts with "<![CDATA["
-					$line = strstr($line, 'BEGIN:VCARD');
-				}
+			if(!isset($fields['access']))
+				$fields['access'] = 'private';
 
-				$buffer += $this->vcard->parse_vcard_line($line);
+			if($timestamp != null)
+			{
+				$fields['createon'] = $timestamp;
+				$fields['modon']    = $timestamp;
+			}
+			else
+			{
+				$now = time();
+				$fields['createon'] = $now;
+				$fields['modon']    = $now;
 			}
 
-			$fields = $this->vcard->in($buffer);
-			$fields['owner'] = $GLOBALS['phpgw_info']['user']['account_id'];
-			$fields['access'] = 'private';
-
+			// 2. Add data to application
 			$id = $this->contacts->contact_import($fields);
 			return $id;
 		}
 
-
-		/**
-		* Convert data from a mime type to another.
-		*
-		* @access  public
-		* @param   mixed    $data     data for converting, the datatype depends on the input mime type
-		* @param   string   $typeIn   specifies the input mime type of the passed data
-		* @param   string   $typeOut  specifies the output mime type of the passed data
-		* @return  mixed              converted data from application, the datatype depends on the passed output mime type
-		*/
-		function convertData($data, $typeIn, $typeOut)
-		{
-			return false;
-		}
-
-
 		/**
 		* Get data from the application in a certain mime type format.
-		*
-		* @param   integer  $id    id of data to get from the application
-		* @param   string   $type  specifies the mime type of the returned data
-		* @return  mixed           data from application, the datatype depends on the passed mime type, false if no data exists for the passed id
+		* @param integer $id id of data to get from the application
+		* @param string $type specifies the mime type of the returned data
+		* @param string $version specifies the mime type version of the returned data
+		* @return mixed data from application, the datatype depends on the passed mime type, false if no data exists for the passed id
 		*/
-		function getData($id, $type)
+		function getData($id, $type, $version='')
 		{
-			if($type != 'text/x-vcard')
+			if($type == 'x-phpgroupware/addressbook-view-url')
 			{
-				return false;
+				$link_data['menuaction'] = 'addressbook.uiaddressbook.view_contact';
+				$link_data['ab_id'] = $id;
+				return $GLOBALS['phpgw']->link('/index.php',$link_data);
 			}
-
-			if(!$this->contacts->check_read($id))
+			
+			if($type != 'x-phpgroupware/search-index-data-item')
 			{
+				$owner = $GLOBALS['phpgw_info']['user']['account_id'];
+				// First, make sure they have permission to this entry
+				if(!$this->contacts->check_read($id, $owner))
+				{
+					return false;
+				}
+				unset($owner);
+			}
+
+			$contact_type = $this->contacts->search_contact_type_id($this->contacts->get_type_contact($id));
+
+			$fields['type']            = $contact_type;
+			$fields['id']              = $id;
+			$fields['adr_one_type']    = 'WORK';
+			$fields['adr_two_type']    = 'HOME';
+			$fields['email_type']      = 'INTERNET';
+			$fields['email_home_type'] = 'INTERNET';
+
+			if($contact_type == $this->contacts->get_person_name())
+			{ // person
+				$fieldlist = $this->contacts->person_complete_data($id);
+
+				$fields['owner']    = $fieldlist['owner'];
+				$fields['access']   = ($fieldlist['access']?$fieldlist['access']:'private');
+				$fields['createon'] = $fieldlist['createon'];
+				$fields['modon']    = $fieldlist['modon'];
+	
+				$fields['first_name']   = $fieldlist['first_name'];
+				$fields['last_name']    = $fieldlist['last_name'];
+				$fields['middle_name']  = $fieldlist['middle_name'];
+
+				// bug in get_person_name: fullname has two spaces, build fullname again:
+				$fieldlist['full_name']  = $fieldlist['first_name'];
+				if($fieldlist['full_name'] != '')
+					$fieldlist['full_name'] .= ($fields['middle_name'] != '') ? ' '.$fields['middle_name'] : '';
+				else
+					$fieldlist['full_name'] .= ($fields['middle_name'] != '') ? $fields['middle_name'] : '';
+				if($fieldlist['full_name'] != '')
+					$fieldlist['full_name'] .= ($fields['last_name'] != '') ? ' '.$fields['last_name'] : '';
+				else
+					$fieldlist['full_name'] .= ($fields['last_name'] != '') ? $fields['last_name'] : '';
+				$fields['full_name']    = $fieldlist['full_name'];
+
+				$fields['prefix']       = $fieldlist['prefix'];
+				$fields['suffix']       = $fieldlist['suffix'];
+				$fields['sound']        = $fieldlist['sound'];
+				$fields['birthday']     = preg_replace('/-/', '', $fieldlist['birthday']);
+				//$fields['note']       = $fieldlist[''];
+				//$fields['tz']         = $fieldlist['locations'][$type_work][''];
+				//$fields['geo']        = $fieldlist[''];
+				$fields['pubkey']       = $fieldlist['pubkey'];
+				$fields['org_name']     = $fieldlist['org_name'];
+				$fields['org_unit']     = $fieldlist['department'];
+				$fields['title']        = $fieldlist['title'];
+				//$fields['tel_prefer'] = $fieldlist[''];
+
+				$cats = $this->contacts->get_cats_by_person($id);
+				if(is_array($cats))
+					$fields['cat_id'] = implode(",", $cats);
+				else
+					$fields['cat_id'] = false;
+			}
+			elseif($contact_type == $this->contacts->get_org_name())
+			{ // organization
+				$fieldlist = array();
+
+				$data = array('contact_id','owner','access','cat_id','org_name','org_creaton','org_modon');
+				$org_data = $this->contacts->get_orgs($data, null, null, null, 'ASC', array('contact_id' => $id), null);
+
+				if(!isset($org_data[0]))
+				{
+					return false;
+				}
+
+				$fields['owner']	  = $org_data[0]['owner'];
+				$fields['access']	  = $org_data[0]['access']?$org_data[0]['access']:'';
+				$fields['createon']	= $org_data[0]['org_creaton']?$org_data[0]['org_creaton']:'';
+				$fields['modon']	  = $org_data[0]['org_modon']?$org_data[0]['org_modon']:'';
+				$fields['org_name']	= $org_data[0]['org_name'];
+				$fields['cat_id']	  = $org_data[0]['cat_id']?$org_data[0]['cat_id']:'';
+				
+				$loclist = $this->contacts->get_addr_contact_data($id);
+				if(is_array($loclist))
+				{
+					$fieldlist['locations'] = array();
+					while(list($no_use, $loc) = each($loclist))
+					{
+						$addr_id = $loc['key_addr_id'];
+						$fieldlist['locations'][$addr_id] = array(
+							'type'        => $loc['addr_description'],
+							'add1'        => $loc['addr_add1'],
+							'add2'        => $loc['addr_add2'],
+							'city'        => $loc['addr_city'],
+							'state'       => $loc['addr_state'],
+							'postal_code' => $loc['addr_postal_code'],
+							'country'     => $loc['addr_country']
+						);
+					}
+				}
+
+				$commlist = $this->contacts->get_comm_contact_data($id);
+				if(is_array($commlist))
+				{
+					$fieldlist['comm_media'] = array();
+					while(list($no_use, $comm) = each($commlist))
+					{
+						$comm_type = $comm['comm_description'];
+						$fieldlist['comm_media'][$comm_type] = $comm['comm_data'];
+					}
+				}
+
+				$cats = $this->contacts->get_cats_by_org($id);
+				while(list($no_use, $cat_id) = each($cats))
+				{
+					if($cat_id)
+						$cat_id_list[] = $cat_id;
+				}
+				$cats = $cat_id_list;
+				if(is_array($cats))
+					$fields['cat_id'] = implode(",", $cats);
+				else
+					$fields['cat_id'] = false;
+			}
+			else
+			{ // no person and no no org
 				return false;
 			}
 
-			// First, make sure they have permission to this entry
-			$fieldlist = $this->contacts->person_complete_data($id);
 			$type_work = $this->contacts->search_location_type('work');
 			$type_home = $this->contacts->search_location_type('home');
-			/*
-			$fields['full_name']            = $fieldlist['full_name'];
-			bug: $fieldlist['full_name'] contains two spaces between first and last name, when middle name is empty
-			workaround: calculate the fullname like shown below
-			*/
-			$fields['first_name']           = $fieldlist['first_name'];
-			$fields['last_name']            = $fieldlist['last_name'];
-			$fields['middle_name']          = $fieldlist['middle_name'];
-
-			$fields['full_name']            = $fields['first_name'] . ' ';
-			$fields['full_name']           .= ($fields['middle_name'] != '') ? $fields['middle_name'] . ' ' : '';
-			$fields['full_name']           .= $fields['last_name'];
-
-			$fields['prefix']               = $fieldlist['prefix'];
-			$fields['suffix']               = $fieldlist['suffix'];
-			$fields['sound']                = $fieldlist['sound'];
-			$fields['birthday']             = $fieldlist['birthday'];
-			//$fields['note']               = $fieldlist[''];
-			//$fields['tz']                 = $fieldlist['locations'][$type_work][''];
-			//$fields['geo']                = $fieldlist[''];
-			$fields['pubkey']               = $fieldlist['pubkey'];
-			$fields['org_name']             = $fieldlist['org_name'];
-			$fields['org_unit']             = $fieldlist['department'];
-			$fields['title']                = $fieldlist['title'];
-			$fields['adr_one_type']         = 'WORK';
-			$fields['adr_two_type']         = 'HOME';
-			//$fields['tel_prefer']         = $fieldlist[''];
-			$fields['email_type']           = 'INTERNET';
-			$fields['email_home_type']      = 'INTERNET';
 
 			// locations contains a list of loc_id and its date
 			if (isset($fieldlist['locations']) && is_array($fieldlist['locations']))
@@ -182,7 +257,6 @@
 						break;
 					default:
 						continue;
-						break;
 					}
 					$fields[$adr.'street']       = $loc_data['add1'];
 					$fields[$adr.'ext']          = $loc_data['add2'];
@@ -193,58 +267,59 @@
 				}
 			}
 
-			$fields['tel_work']             = $fieldlist['comm_media']['work phone'];
-			$fields['tel_home']             = $fieldlist['comm_media']['home phone'];
-			$fields['tel_voice']            = $fieldlist['comm_media']['voice phone'];
-			$fields['tel_work_fax']         = $fieldlist['comm_media']['work fax'];
-			$fields['tel_home_fax']         = $fieldlist['comm_media']['home fax'];
-			$fields['tel_msg']              = $fieldlist['comm_media']['msg phone'];
-			$fields['tel_cell']             = $fieldlist['comm_media']['mobile (cell) phone'];
-			$fields['tel_pager']            = $fieldlist['comm_media']['pager'];
-			$fields['tel_bbs']              = $fieldlist['comm_media']['bbs'];
-			$fields['tel_modem']            = $fieldlist['comm_media']['modem'];
-			$fields['tel_car']              = $fieldlist['comm_media']['car phone'];
-			$fields['tel_isdn']             = $fieldlist['comm_media']['isdn'];
-			$fields['tel_video']            = $fieldlist['comm_media']['video'];
-			$fields['email']                = $fieldlist['comm_media']['work email'];
-			$fields['email_home']           = $fieldlist['comm_media']['home email'];
-			$fields['url']                  = $fieldlist['comm_media']['website'];
-
-			$email = $fields['email'];
-			$emailtype = $fields['email_type'];
-			if (!$emailtype)
-			{
-				$fields['email_type'] = 'INTERNET';
-			}
-			$hemail       = $fields['email_home'];
-			$hemailtype   = $fields['email_home_type'];
-			if (!$hemailtype)
+			if (isset($fieldlist['comm_media']) && is_array($fieldlist['comm_media']))
 			{
-				$fields['email_home_type'] = 'INTERNET';
-			}
-
-			// set translation variable
-			$myexport = $this->vcard->export;
-			// check that each $fields exists in the export array and
-			// set a new array to equal the translation and original value
-			while( list($name,$value) = each($fields) )
-			{
-				if ($myexport[$name] && ($value != "") )
+				$fields['tel_work']             = $fieldlist['comm_media']['work phone'];
+				$fields['tel_home']             = $fieldlist['comm_media']['home phone'];
+				$fields['tel_voice']            = $fieldlist['comm_media']['voice phone'];
+				$fields['tel_work_fax']         = $fieldlist['comm_media']['work fax'];
+				$fields['tel_home_fax']         = $fieldlist['comm_media']['home fax'];
+				$fields['tel_msg']              = $fieldlist['comm_media']['msg phone'];
+				$fields['tel_cell']             = $fieldlist['comm_media']['mobile (cell) phone'];
+				$fields['tel_pager']            = $fieldlist['comm_media']['pager'];
+				$fields['tel_bbs']              = $fieldlist['comm_media']['bbs'];
+				$fields['tel_modem']            = $fieldlist['comm_media']['modem'];
+				$fields['tel_car']              = $fieldlist['comm_media']['car phone'];
+				$fields['tel_isdn']             = $fieldlist['comm_media']['isdn'];
+				$fields['tel_video']            = $fieldlist['comm_media']['video'];
+				$fields['email']                = $fieldlist['comm_media']['work email'];
+				$fields['email_home']           = $fieldlist['comm_media']['home email'];
+				$fields['url']                  = $fieldlist['comm_media']['website'];
+				
+				$email = $fields['email'];
+				$emailtype = $fields['email_type'];
+				if (!$emailtype)
 				{
-					//echo '<br>'.$name."=".$fields[$name]."\n";
-					$buffer[$myexport[$name]] = $value;
+					$fields['email_type'] = 'INTERNET';
+				}
+				$hemail       = $fields['email_home'];
+				$hemailtype   = $fields['email_home_type'];
+				if (!$hemailtype)
+				{
+					$fields['email_home_type'] = 'INTERNET';
 				}
 			}
 
-			// create a vcard from this translated array
-			$data = $this->vcard->out($buffer);
+			// fields are 'x-phpgroupware/addressbook-appl-data-array'
+			$convertTypeIn     = 'x-phpgroupware/addressbook-appl-data-array';
+			$convertVersionIn  = '';
+			$convertTypeOut    = $type;
+			$convertVersionOut = $version;
 
-			if ($data == false)
+			if($convertTypeOut == 'x-phpgroupware/addressbook-show-data-array')
 			{
-				return false;
+				// workaround
+				$tmp_type = 'text/x-vcard';
+				$tmp_version = '3.0';
+				$tmp_data = $this->convertData($fields, $convertTypeIn, $convertVersionIn, $tmp_type, $tmp_version);
+				// convert fields to mime type format
+				return $this->convertData($tmp_data, $tmp_type, $tmp_version, $convertTypeOut, $convertVersionOut);
+			}
+			else
+			{
+				// convert fields to mime type format
+				return $this->convertData($fields, $convertTypeIn, $convertVersionIn, $convertTypeOut, $convertVersionOut);
 			}
-
-			return $data;
 		}
 
 
@@ -252,49 +327,92 @@
 		* Return a list with the available id's in the application.
 		* The optional lastmod parameter allows a limitations of the data id list.
 		* The list contains all the id's of the modified data since the passed lastmod timestamp.
-		*
-		* @param   integer  $lastmod  last modification time, default is -1 and means return all data id's
-		* @return  array              list of data id's
+		* @param integer $lastmod last modification time, default is -1 and means return all data id's.
+		* @param string $restriction restrict the result for a special use of the id list. The possible restrictions are 'syncable' or 'searchable'. When using 'syncable' only person ids will be returned in the result. 'searchable' returns all ids for both persons and orgs without check the owner. Otherwise no restriction will be used and the result contains all ids for both persons and orgs from the owner.
+		* @return array list of data id's
 		*/
-		function getIdList($lastmod=-1)
+		function getIdList($lastmod=-1, $restriction='')
 		{
 			$idList = array();
 			$lastmod = intval($lastmod);
-		
+			$owner = $GLOBALS['phpgw_info']['user']['account_id'];
+
 			//$this->contacts->read(null, false, null, null, null, null, null, $lastmod);
-			// read_contacts doesnt allow lastmod time -workaround:
-			$owner = intval($GLOBALS['phpgw_info']['user']['account_id']);
+			// read_contacts doesnt allow lastmod time -> workaround:
 
-			if($lastmod >= 0)
+			if($lastmod > 0)
 			{
-				$sql = 'SELECT DISTINCT c.contact_id AS contact_id '.
-					'FROM phpgw_contact c '.
-					'LEFT JOIN phpgw_contact_addr ca ON (c.contact_id=ca.contact_id) '.
-					'LEFT JOIN phpgw_contact_comm cc ON (c.contact_id=cc.contact_id) '.
-					'LEFT JOIN phpgw_contact_note cn ON (c.contact_id=cn.contact_id) '.
-					'LEFT JOIN phpgw_contact_person cp ON (c.contact_id=cp.person_id) '.
-					'WHERE '.
-					' (c.owner = '.$owner.')'.
-					' AND'.
-					' ('.
-					'  (ca.modified_on '.$lastmod.') OR '.
-					'  (cc.modified_on '.$lastmod.') OR '.
-					'  (cn.modified_on '.$lastmod.') OR '.
-					'  (cp.modified_on '.$lastmod.') '.
-					' ) '.
-					'ORDER BY c.contact_id';
+				$sql  = 'SELECT DISTINCT c.contact_id AS contact_id ';
+				$sql .=	'FROM phpgw_contact c ';
+				$sql .=	'LEFT JOIN phpgw_contact_addr ca ON (c.contact_id=ca.contact_id) ';
+				$sql .=	'LEFT JOIN phpgw_contact_comm cc ON (c.contact_id=cc.contact_id) ';
+				$sql .=	'LEFT JOIN phpgw_contact_note cn ON (c.contact_id=cn.contact_id) ';
+				if($restriction == 'syncable')
+				{ // only persons - no organizations
+					$sql .=	'JOIN phpgw_contact_person cp ON (c.contact_id=cp.person_id) ';				
+				}
+				else
+				{ // persons and organizations
+					$sql .=	'LEFT JOIN phpgw_contact_person cp ON (c.contact_id=cp.person_id) ';
+					$sql .=	'LEFT JOIN phpgw_contact_org co ON (c.contact_id=co.org_id) ';
+				}
+				$sql .=	'WHERE ';
+				if($restriction == 'searchable')
+				{ // all data
+					$sql .=	' (c.owner > 0)';
+				}
+				else
+				{ // only owners data
+					$sql .=	' (c.owner = '.$owner.')';
+				}
+				$sql .=	' AND';
+				$sql .=	' (';
+				$sql .=	'  (ca.modified_on > '.$lastmod.') OR ';
+				$sql .=	'  (cc.modified_on > '.$lastmod.') OR ';
+				$sql .=	'  (cn.modified_on > '.$lastmod.') OR ';
+
+				if($restriction == 'syncable')
+				{ // only persons - no organizations
+					$sql .=	'  (cp.modified_on > '.$lastmod.') ';
+				}
+				else
+				{ // persons and organizations
+					$sql .=	'  (cp.modified_on > '.$lastmod.') OR ';
+					$sql .=	'  (co.modified_on > '.$lastmod.') ';
+				}
+
+				$sql .=	' ) ';
+				$sql .=	'ORDER BY c.contact_id';
 			}
 			else
 			{
-				$sql = 'SELECT DISTINCT contact_id '.
-					'FROM phpgw_contact '.
-					'WHERE owner = '.$owner.' '.
-					'ORDER BY contact_id';
+				$sql  = 'SELECT DISTINCT c.contact_id AS contact_id ';
+				$sql .=	'FROM phpgw_contact c ';
+
+				if($restriction == 'syncable')
+				{ // only persons - no organizations
+					$sql .=	'JOIN phpgw_contact_person cp ON (c.contact_id=cp.person_id) ';
+				}
+
+				if($restriction == 'searchable')
+				{ // all data
+					$sql .=	'WHERE c.owner > 0 ';
+				}
+				else
+				{ // only owners data
+					$sql .=	'WHERE c.owner = '.$owner.' ';
+				}
+
+				$sql .=		'ORDER BY c.contact_id';
 			}
 			$contacts = $this->contacts->db->query($sql,__LINE__,__FILE__);
 			while ($this->contacts->db->next_record())
 			{
-				$idList[] = $this->contacts->db->Record['contact_id'];
+				$cid = $this->contacts->db->Record['contact_id'];
+				if($this->contacts->check_read($cid, $owner))
+				{
+					$idList[] =	$cid;
+				}
 			}
 
 			return $idList;
@@ -303,39 +421,242 @@
 
 		/**
 		* Remove data of the passed id.
-		*
-		* @param   integer  $id  id of data to remove from the application
-		* @return  boolean       true if the data is removed, otherwise false
+		* @param integer $id id of data to remove from the application
+		* @return boolean true if the data is removed, otherwise false
 		*/
 		function removeData($id)
 		{
-			return $this->contacts->delete_contact($id);
+			$owner = $GLOBALS['phpgw_info']['user']['account_id'];
+
+			if(!$this->contacts->check_delete($id, $owner))
+			{
+				return false;
+			}
+			else
+			{
+				$this->contacts->delete($id);
+
+				//$this->contacts->delete($id);
+				//provides no useable return value -> workaround: check for db error
+				if($GLOBALS['phpgw']->db->Error)
+					return false;
+				else
+					return true;
+			}
 		}
 
 
 		/**
 		* Replace the existing data of the passed id with the passed data in a certain mime type format.
-		*
-		* @param   integer  $id    id of data to replace
-		* @param   mixed    $data  the new data, the datatype depends on the passed mime type
-		* @param   string   $type  specifies the mime type of the passed data
-		* @return  boolean         true if the data is replaced, otherwise false
+		* @param integer $id id of data to replace
+		* @param mixed $data the new data, the datatype depends on the passed mime type
+		* @param string $type specifies the mime type of the passed data
+		* @param string $version specifies the mime type version of the passed data (still no need for this because the version would be recognized automaticly)
+    * @param string $timestamp the timestamp is used to set in db instead of current time
+    * @return boolean true if the data is replaced, otherwise false
 		*/
-		function replaceData($id, $data, $type)
+		function replaceData($id, $data, $type, $version='', $timestamp=null)
 		{
-			if($type != 'text/x-vcard')
+			$owner = $GLOBALS['phpgw_info']['user']['account_id'];
+			if(!$this->contacts->check_edit($id, $owner))
 			{
 				return false;
 			}
-		
+
+			// 1: mapping the mime type to application data
+			$convertTypeIn     = $type;
+			$convertVersionIn  = $version;
+			$convertTypeOut    = 'x-phpgroupware/addressbook-appl-data-array';
+			$convertVersionOut = '';
+
+			$fields = $this->convertData($data, $convertTypeIn, $convertVersionIn, $convertTypeOut, $convertVersionOut);
+
+			if(!$fields || count($fields) == 0)
+				return false;
+
+			if(!isset($fields['owner']) || !$fields['owner'])
+				$fields['owner'] = $GLOBALS['phpgw_info']['user']['account_id'];
+
+			if(!isset($fields['access']))
+				$fields['access'] = 'private';
+
+			if(!isset($fields['contact_id']))
+				$fields['contact_id'] = $id;
+
+			if($timestamp != null)
+			{
+				$fields['modon'] = $timestamp;
+			}
+			else
+			{
+				$fields['modon'] = time();
+			}
+
+			// 2. Replace data to application
+			return $this->contacts->contact_import($fields, '', true);
+		}
+
+
+		/**
+		* Checks if data for the passed id exists.
+		* @param integer $id id to check
+		* @return boolean true if the data with id exist, otherwise false
+		*/
+		function existData($id)
+		{
 			if(!$this->contacts->check_read($id))
 			{
 				return false;
 			}
+			else
+			{
+				return true;
+			}
+		}
+
 
-			$data = ereg_replace("\n\n", "\r\n", $data);
+		/**
+		* Convert the given data from a mime type into another.
+		* @param mixed $data data for converting
+		* @param string $typeIn specifies the mime type of the passed data
+		* @param string $versionIn specifies the mime type version of the passed data
+		* @param string $typeOut specifies the mime type of the returned data
+		* @param string $versionOut specifies the mime type version of the returned data
+		* @return mixed data from application, the datatype depends on the passed typeOut and versionOut parameters
+		*/
+		function convertData($data, $typeIn, $versionIn, $typeOut, $versionOut)
+		{
+			// data import: if data typeIn != x-phpgroupware/addressbook-appl-data-array
+      //   convert given data into x-phpgroupware/addressbook-appl-data-array
+			switch($typeIn)
+			{
+				case 'text/x-vcard':
+				case 'text/vcard':
+					$appl_data_array = $this->_import_vcard($data);
+				break;
+				case 'x-phpgroupware/addressbook-ldap':
+					$appl_data_array = $this->_import_ldap_array($data);
+				break;
+				case 'x-phpgroupware/addressbook-data-array':
+					$appl_data_array = $this->_import_data_array($data);
+				break;
+				case 'x-phpgroupware/addressbook-serialized-appl-data-array':
+					$appl_data_array = unserialize(base64_decode(trim($data)));
+				break;
+				case 'x-phpgroupware/addressbook-appl-data-array':
+					// no import convert
+					$appl_data_array = $data;
+				break;
+				default:
+					return false;
+			}
+
+			if(!$appl_data_array)
+				return false;
+
+			// data export: if data typeOut != x-phpgroupware/addressbook-appl-data-array
+      //   convert data into typeOut
+			switch($typeOut)
+			{
+				case 'text/x-vcard':
+				case 'text/vcard':
+					$ret_data = $this->_export_vcard($appl_data_array, $versionOut);
+				break;
+				case 'text/xml':
+					$ret_data = $this->_export_xml($appl_data_array, $versionOut);
+				break;
+				case 'x-phpgroupware/search-index-data-item':
+					$ret_data = $this->_export_index_data_item($appl_data_array, $versionOut);
+				break;
+				case 'x-phpgroupware/addressbook-show-data-array':
+					$ret_data = $this->_export_show_data_array($appl_data_array, $versionOut);
+				break;
+				case 'x-phpgroupware/addressbook-serialized-appl-data-array':
+					$ret_data = base64_encode(serialize($data));
+				break;
+				case 'x-phpgroupware/addressbook-appl-data-array':
+					// no export convert
+					$ret_data = $appl_data_array;
+				break;
+				default:
+					return false;
+			}
+			
+			return $ret_data;
+		}
+
+
+		// below are some private helper methods
+
+		// ##########################
+		// ##### IMPORT METHODS #####
+		// ##########################
+
+		/**
+		* Convert the extern data array structure into intern application array
+		* @access private
+		* @param array $fields extern data array
+		* @return string xml
+		*/
+		function _import_data_array($fields)
+		{
+			if(!is_array($fields))
+				return false;
+
+			$appl_data_array = array();
+			
+			$data = array();
+			$comm = array();
+			$loc  = array();
+			
+			while(list($field_name, $field_data) = each($fields))
+			{
+				if(strpos($field_name, 'comm_') === 0)
+				{
+					$field_name = str_replace('comm_', '', $field_name);
+					$comm[$field_name] = html_entity_decode($field_data);
+				}
+				elseif(strpos($field_name, 'loc_') === 0)
+				{
+					$field_name = str_replace('loc_', '', $field_name);
+					$field_name = explode('_', $field_name, 2);
+					
+					if(count($field_name) == 2)
+					{
+						$loc_type = $field_name[0];
+						$loc_name = $field_name[1];
+
+						if(!isset($loc[$loc_type]))
+						{
+							$loc[$loc_type] = array('type' => $loc_type);
+						}
+						
+						$loc[$loc_type] += array($loc_name => html_entity_decode($field_data));
+					}
+				}
+				else
+				{
+					$data[$field_name] = html_entity_decode($field_data);
+				}
+			}
+
+			$appl_data_array = $data;
+			$appl_data_array['comm_media'] = $comm;
+			$appl_data_array['locations']  = $loc;
+			return $appl_data_array;
+		}
+
+		/**
+		* Convert the passed vcard into the internal array structure
+		* @access private
+		* @param string $data vcard data string
+		* @return array internal fields
+		*/
+		function _import_vcard($data)
+		{
+			$data = ereg_replace("\n\n", "\r\n", $data); // xml-rpc bug: \r\n -> \n\n
 			$data_lines = explode("\r\n", $data);
-		
+
 			$buffer = array();
 			$temp_line = '';
 
@@ -362,33 +683,608 @@
 
 				$buffer += $this->vcard->parse_vcard_line($line);
 			}
+			
+			if(count($buffer) == 0)
+				return array();
+			else
+				return $this->vcard->in($buffer);
+		}
 
-			$fields = $this->vcard->in($buffer);
-			$fields['owner'] = $GLOBALS['phpgw_info']['user']['account_id'];
-			$fields['access'] = 'private';
-			$fields['contact_id'] = $id;
+		/**
+		* Convert the passed ldap array into the internal array structure
+		* @access private
+		* @param string $data vcard data string
+		* @return array list of arrays with internal fields
+		*/
+		function _import_ldap_array($data)
+		{
+			$fields = array();
 
-			return $this->contacts->contact_import($fields, '', true);
+			if(!is_array($data) || !isset($data['count']))
+				return $fields;
+
+			for($a=0;$a<$data['count'];++$a)
+			{
+				$attribute = strtolower($data[$a]);
+				switch($attribute)
+				{
+					case 'objectclass':
+					break;
+					case 'rdn':
+					break;
+					case 'cn': // common name
+						if(isset($data[$attribute][0]) && !(isset($fields['first_name']) || isset($fields['last_name'])))
+						{
+							$fields['full_name'] = utf8_decode($data[$attribute][0]);
+							$names = explode(' ', $fields['full_name'], 3);
+							switch(count($names))
+							{
+								case 2:
+									$fields['first_name'] = $names[0];
+									$fields['last_name'] = $names[1];
+								break;
+								case 3:
+									$fields['first_name'] = $names[0];
+									$fields['middle_name'] = $names[1];
+									$fields['last_name'] = $names[2];
+								break;
+							}
+						}
+					break;
+					case 'sn': // last name
+					case 'surname':
+						if(isset($data[$attribute][0]))
+							$fields['last_name'] = utf8_decode($data[$attribute][0]);
+					break;
+					case 'givenname': // first name
+						if(isset($data[$attribute][0]))
+							$fields['first_name'] = utf8_decode($data[$attribute][0]);
+					break;
+					case 'initials':
+						if(isset($data[$attribute][0]) && !isset($fields['initials']))
+							$fields['initials'] = utf8_decode($data[$attribute][0]);
+					break;
+					case 'title':
+					case 'personaltitle':
+						if(isset($data[$attribute][0]))
+							$fields['title'] = utf8_decode($data[$attribute][0]);
+					break;
+					case 'distinguishedname':
+						if(isset($data[$attribute][0]))
+						{
+							$add_parts = explode(',', utf8_decode($data[$attribute][0]));
+							for($k=0;$k<count($add_parts);++$k)
+							{
+								list($name, $value) = split('=', $add_parts[$k], 2);
+								$value = utf8_decode($value);
+								switch(strtolower($name))
+								{
+									case 'cn': // common name
+									break;
+									case 'ou': // org unit -> department
+										if($value && !isset($fields['department']))
+											$fields['department'] = $value;
+									break;
+									case 'o': // org -> preferred_org
+										if($value && !isset($fields['preferred_org']))
+											$fields['preferred_org'] = $value;
+									break;
+									case 'c': // country
+									break;
+								}
+							}
+						}
+					break;
+					case 'department':
+						if(isset($data[$attribute][0]))
+							$fields['department'] = utf8_decode($data[$attribute][0]);
+					break;
+
+					// location
+					case 'postaladdress':
+						if(isset($data[$attribute][0]))
+							$fields['locations']['work']['add1'] = utf8_decode($data[$attribute][0]);
+						if(isset($data[$attribute][1]))
+							$fields['locations']['home']['add1'] = utf8_decode($data[$attribute][1]);
+					break;
+					case 'postofficebox':
+						if(isset($data[$attribute][0]))
+							$fields['locations']['work']['add2'] = utf8_decode($data[$attribute][0]);
+						if(isset($data[$attribute][1]))
+							$fields['locations']['home']['add2'] = utf8_decode($data[$attribute][1]);
+					break;
+					case 'postalcode':
+						if(isset($data[$attribute][0]))
+							$fields['locations']['work']['postal_code'] = utf8_decode($data[$attribute][0]);
+						if(isset($data[$attribute][1]))
+							$fields['locations']['home']['postal_code'] = utf8_decode($data[$attribute][1]);
+					break;
+					case 'l': // Locality -> city
+					case 'locality':
+						if(isset($data[$attribute][0]))
+							$fields['locations']['work']['city'] = utf8_decode($data[$attribute][0]);
+						if(isset($data[$attribute][1]))
+							$fields['locations']['home']['city'] = utf8_decode($data[$attribute][1]);
+					break;
+					case 'countryname':
+						if(isset($data[$attribute][0]))
+							$fields['locations']['work']['country'] = utf8_decode($data[$attribute][0]);
+						if(isset($data[$attribute][1]))
+							$fields['locations']['home']['country'] = utf8_decode($data[$attribute][1]);
+					break;
+					case 'textencodedoraddress':
+						if(isset($data[$attribute][0]))
+						{
+							$add_parts = explode(';', utf8_decode($data[$attribute][0]));
+							for($k=0;$k<count($add_parts);++$k)
+							{
+								list($name, $value) = split('=', $add_parts[$k], 2);
+								switch(strtolower($name))
+								{
+									case 'c':
+									break;
+									case 'a':
+									break;
+									case 'p':
+									break;
+									case 'o':
+									break;
+									case 's': // sur name -> last name
+										if($value && !isset($fields['last_name']))
+											$fields['last_name'] = $value;
+									break;
+									case 'g': // given name -> first name
+										if($value && !isset($fields['first_name']))
+											$fields['first_name'] = $value;
+									break;
+									case 'i': // initials
+										if($value && !isset($fields['initials']))
+											$fields['initials'] = $value;
+									break;
+								}
+							}
+						}
+					break;
+
+					// comm_media
+					case 'facsimiletelephonenumber':
+					case 'homephone':
+					case 'telephonenumber':
+					case 'mail':
+					case 'rfc822mailbox':
+					case 'othermailbox':
+						for($k=0;$k<$data[$attribute]['count'];++$k)
+						{
+							if(!isset($data[$attribute][$k]))
+							{
+								break;
+							}
+							else
+							{
+								$is_found = false;
+								$is_saved = false;
+								$continue_next = false;
+								$value = $data[$attribute][$k];
+
+								switch($attribute)
+								{
+									case 'facsimiletelephonenumber':
+										$fill_map = array('work fax', 'home fax');
+										$save_other = true;
+									break;
+									case 'homephone':
+										$fill_map = array('home phone', 'voice phone', 'car phone', 'msg phone', 'work phone');
+										$save_other = true;
+									break;
+									case 'telephonenumber':
+										$fill_map = array('work phone', 'voice phone', 'car phone', 'msg phone', 'home phone');
+										$save_other = true;
+									break;
+									case 'mail':
+									case 'rfc822mailbox':
+									case 'othermailbox':
+										$fill_map = array('work email', 'home email');
+										$save_other = true;
+										if(!$this->validator->is_email($value))
+										{
+											$continue_next = true;
+										}
+									break;
+									default:
+										$continue_next = true;
+									break;
+								}
+								
+								if($continue_next == true)
+								{ // continue with next $k in for
+									continue;
+								}
+
+								foreach($fill_map as $fill)
+								{
+									if(isset($fields['comm_media'][$fill]))
+									{
+										if($value == $fields['comm_media'][$fill])
+										{
+											$is_found = true;
+											break;
+										}
+									}
+								}
+								
+								if(!$is_found)
+								{ // value was not found in fields -> save it
+									foreach($fill_map as $fill)
+									{
+										// search the first not set fill field
+										if(!isset($fields['comm_media'][$fill]))
+										{ // save value in fields
+											$fields['comm_media'][$fill] = $value;
+											$is_saved = true;
+											break;
+										}
+									}
+									
+									if(!$is_saved)
+									{ // save as other field
+										$fields[$attribute] = $value;
+									}
+								}
+							}
+						}
+					break;
+					case 'mobile':
+						if(isset($data[$attribute][0]))
+							$fields['comm_media']['mobile (cell) phone'] = $data[$attribute][0];
+					break;
+					case 'internationalisdnnumber':
+						if(isset($data[$attribute][0]))
+							$fields['comm_media']['isdn'] = $data[$attribute][0];
+					break;
+					case 'pager':
+						if(isset($data[$attribute][0]))
+							$fields['comm_media']['pager'] = $data[$attribute][0];
+					break;
+					case 'homepage':
+					case 'url':
+						if(isset($data[$attribute][0]))
+							$fields['comm_media']['website'] = utf8_decode($data[$attribute][0]);
+					break;
+
+					// other
+					default:
+						// save any other ldap info as other fields
+						//if(isset($data[$attribute][0]))
+						//	$fields[$attribute] = utf8_decode($data[$attribute][0]);
+					break;
+				}
+			}
+
+			if(isset($fields['locations']))
+			{
+				if(isset($fields['locations']['work']))
+					$fields['locations']['work']['type'] = 'work';
+				if(isset($fields['locations']['home']))
+					$fields['locations']['home']['type'] = 'home';
+			}
+
+			return $fields;
 		}
 
+		// ##########################
+		// ##### EXPORT METHODS #####
+		// ##########################
 
 		/**
-		* Checks if data for the passed id exists.
-		*
-		* @param   integer  $id  id to check
-		* @return  boolean       true if the data with id exist, otherwise false
+		* Convert the internal array structure into a vcard string
+		* @access private
+		* @param array $fields data array
+		* @param string $version specifies the exported vcard version
+		* @return string vcard
 		*/
-		function existData($id)
+		function _export_vcard($fields, $version)
 		{
-			if(!$this->contacts->check_read($id))
+			$vcardString = '';
+			$buffer      = array();
+
+			if(count($fields) == 0)
+				return $vcardString;
+
+			// set translation variable
+			$myexport = $this->vcard->export;
+			// check that each $fields exists in the export array and
+			// set a new array to equal the translation and original value
+			while( list($name,$value) = each($fields) )
 			{
+				if ($myexport[$name] && ($value != "") )
+				{
+					//echo '<br>'.$name."=".$fields[$name]."\n";
+					$buffer[$myexport[$name]] = $value;
+				}
+			}
+
+			// create a vcard from this translated array
+			if($version == '3.0')
+				$vcardString = $this->vcard->out_version_30($buffer);
+			else
+				$vcardString = $this->vcard->out($buffer);
+
+			return $vcardString;
+		}
+
+
+		/**
+		* Convert the internal application array structure into extern showable data array with translation and input field name data included
+		* @access private
+		* @param array $fields application data array
+		* @param string $version version of export array
+		* @return string xml
+		*/
+		function _export_show_data_array($fields, $version='1.0')
+		{
+			if(!is_array($fields))
 				return false;
+
+			$show_data_array = array();
+			$bo =& CreateObject('addressbook.boaddressbook');
+
+			if(isset($fields['comm_media']) && is_array($fields['comm_media']))
+			{
+				$comms = $fields['comm_media'];
+				unset($fields['comm_media']);
 			}
 			else
 			{
-				return true;
+				$comms = array();
+			}
+
+			if(isset($fields['locations']) && is_array($fields['locations']))
+			{
+				$locations = $fields['locations'];
+				unset($fields['locations']);
+			}
+			else
+			{
+				$locations = array();
+			}
+
+			$field_data = array();
+			if(isset($fields['org_name']))
+			{
+				$field_data[] = array('tf' => 'org_name', 'if' => 'org_name', 'vf' => $fields['org_name']);				
+			}
+			else
+			{
+				$fields['first_name']    = isset($fields['first_name'])    ? $fields['first_name']    : '';
+				$fields['last_name']     = isset($fields['last_name'])     ? $fields['last_name']     : '';
+				$fields['middle_name']   = isset($fields['middle_name'])   ? $fields['middle_name']   : '';
+				$fields['suffix']        = isset($fields['suffix'])        ? $fields['suffix']        : '';
+				$fields['prefix']        = isset($fields['prefix'])        ? $fields['prefix']        : '';
+				$fields['birthday']      = isset($fields['birthday'])      ? $fields['birthday']      : '';
+				$fields['pubkey']        = isset($fields['pubkey'])        ? $fields['pubkey']        : '';
+				$fields['title']         = isset($fields['title'])         ? $fields['title']         : '';
+				$fields['initials']      = isset($fields['initials'])      ? $fields['initials']      : '';
+				$fields['sound']         = isset($fields['sound'])         ? $fields['sound']         : '';
+				$fields['preferred_org'] = isset($fields['preferred_org']) ? $fields['preferred_org'] : '';
+				$fields['department']    = isset($fields['department'])    ? $fields['department']    : '';
+
+				$field_data[] = array('tf' => 'per_first_name',  'if' => 'first_name',    'vf' => $fields['first_name']);
+				$field_data[] = array('tf' => 'per_last_name',   'if' => 'last_name',     'vf' => $fields['last_name']);
+				$field_data[] = array('tf' => 'per_middle_name', 'if' => 'middle_name',   'vf' => $fields['middle_name']);
+				$field_data[] = array('tf' => 'per_suffix',      'if' => 'suffix',        'vf' => $fields['suffix']);
+				$field_data[] = array('tf' => 'per_prefix',      'if' => 'prefix',        'vf' => $fields['prefix']);
+				$field_data[] = array('tf' => 'per_birthday',    'if' => 'birthday',      'vf' => $fields['birthday']);
+				$field_data[] = array('tf' => 'per_pubkey',      'if' => 'pubkey',        'vf' => $fields['pubkey']);
+				$field_data[] = array('tf' => 'per_title',       'if' => 'title',         'vf' => $fields['title']);
+				$field_data[] = array('tf' => 'per_initials',    'if' => 'initials',      'vf' => $fields['initials']);
+				$field_data[] = array('tf' => 'per_sound',       'if' => 'sound',         'vf' => $fields['sound']);
+				$field_data[] = array('tf' => 'org_name',        'if' => 'preferred_org', 'vf' => $fields['preferred_org']);
+				$field_data[] = array('tf' => 'per_department',  'if' => 'department',    'vf' => $fields['department']);
+			}
+
+			while(list($no_use, $data) = each($field_data))
+			{
+				$show_data_array[] = array(
+					'displayName'  => $bo->display_name($data['tf']),
+					'displayValue' => htmlentities($data['vf']),
+					'fieldName'    => $data['if']
+				);
+			}
+
+			while(list($field, $data) = each($comms))
+			{
+				$show_data_array[] = array(
+					'displayName'  => lang($field),
+					'displayValue' => htmlentities($data),
+					'fieldName'    => 'comm_'.$field
+				);
 			}
+
+			$type_work = $this->contacts->search_location_type('work');
+			$type_home = $this->contacts->search_location_type('home');
+			while(list($loc_id, $loc_data) = each($locations))
+			{
+				unset($loc_data['type']);
+
+				while(list($field, $data) = each($loc_data))
+				{
+					$show_data_array[] = array(
+						'displayName'  => $bo->display_name('addr_'.$field),
+						'displayValue' => htmlentities($data),
+						'fieldName'    => 'loc_'.$loc_id.'_'.$field
+					);
+				}
+			}
+
+			return $show_data_array;
+		}
+		
+
+		/**
+		* Convert the internal application array structure into a xml string
+		* @access private
+		* @param array $fields data array
+		* @return string xml
+		*/
+		function _export_xml($fields, $version='1.0')
+		{
+			$dom_doc = domxml_new_doc($version);
+
+			// contact/
+			$elem_contact = $dom_doc->create_element('contact');
+			$node_contact = $dom_doc->append_child($elem_contact);
+			
+			while(list($element, $value) = each($fields))
+			{
+				// contact/<element>
+				$xmlElement = $dom_doc->create_element($element);
+				$xmlNode = $node_contact->append_child($xmlElement);
+				// contact/<element> text string
+				$xmlNode->set_content($value);
+			}
+			
+			$xml_string = $dom_doc->dump_mem(true);
+			return $xml_string;
 		}
 
+		function &_export_index_data_item($fields, $version='1.0')
+		{
+			$indexitem = CreateObject('pbsearch.IndexBaseDataItem', 'addressbook', $fields['id']);
+
+			if($fields['type'] == 'Persons')
+				$indexitem->setValue('DataDisplayName', $fields['full_name']);
+			elseif($fields['type'] == 'Organizations')
+				$indexitem->setValue('DataDisplayName', $fields['org_name']);
+
+			$indexitem->setValue('DataOwnerId', $fields['owner']);
+			$indexitem->setValue('DataAccess', $fields['access']);
+			$indexitem->setValue('DataTimeCreated', $fields['createon']);
+			$indexitem->setValue('DataTimeModified', $fields['modon']);
+			$indexitem->setValue('DataCategoryId', $fields['cat_id']);
+			
+			$data = $fields;
+			$indexitem->setValue('Data', $data);
+
+			return $indexitem;
+		}
+
+		function _export_html($fields)
+		{
+			$id = isset($fields['contact_id']) ? $fields['contact_id'] : '';
+			$owner = isset($fields['owner']) ? $fields['owner'] : $GLOBALS['phpgw_info']['user']['account_id'];
+			$access = isset($fields['access']) ? $fields['access'] : '';
+
+			if(isset($fields['comm_media']) && is_array($fields['comm_media']))
+			{
+				$comm_media = $fields['comm_media'];
+				unset($fields['comm_media']);
+			}
+			else
+			{
+				$comm_media = array();
+			}
+			
+			if(isset($fields['locations']) && is_array($fields['locations']))
+			{
+				$locations = $fields['locations'];
+				unset($fields['locations']);
+			}
+			else
+			{
+				$locations = array();
+			}
+
+			$contact['per_first_name']    = isset($fields['first_name'])        ? $fields['first_name']        : '';
+			$contact['per_last_name']     = isset($fields['last_name'])         ? $fields['last_name']         : '';
+			$contact['per_middle_name']   = isset($fields['middle_name'])       ? $fields['middle_name']       : '';
+			$contact['per_suffix']        = isset($fields['suffix'])            ? $fields['suffix']            : '';
+			$contact['per_prefix']        = isset($fields['prefix'])            ? $fields['prefix']            : '';
+			$contact['per_birthday']      = isset($fields['birthday'])          ? $fields['birthday']          : '';
+			$contact['per_pubkey']        = isset($fields['pubkey'])            ? $fields['pubkey']            : '';
+			$contact['per_title']         = isset($fields['title'])             ? $fields['title']             : '';
+			$contact['per_department']    = isset($fields['department'])        ? $fields['department']        : '';
+			$contact['per_initials']      = isset($fields['initials'])          ? $fields['initials']          : '';
+			$contact['per_sound']         = isset($fields['sound'])             ? $fields['sound']             : '';
+			$contact['per_active']        = isset($fields['active'])            ? $fields['active']            : '';
+			$contact['preferred_org']     = isset($fields['preferred_org'])     ? $fields['preferred_org']     : '';
+			$contact['preferred_address'] = isset($fields['preferred_address']) ? $fields['preferred_address'] : '';
+			$contact['relations']         = isset($fields['organizations'])     ? $fields['organizations']     : array();
+
+			$contact['org_name']   = isset($fields['org_name']) ? $fields['org_name'] : '';
+			$contact['org_active'] = isset($fields['active'])   ? $fields['active']   : '';
+			$contact['org_parent'] = isset($fields['parent'])   ? $fields['parent']   : '';
+			$contact['relations']  = isset($fields['people'])   ? $fields['people']   : '';
+
+			$bo       = CreateObject('addressbook.boaddressbook');
+			$template =& $GLOBALS['phpgw']->template;
+			$GLOBALS['phpgw']->nextmatchs = CreateObject('phpgwapi.nextmatchs');
+
+			$template->set_file(array('view_t' => 'view.tpl'));
+			$template->set_block('view_t','view_row','view_row');
+
+ 			$tr_color = $GLOBALS['phpgw_info']['theme']['row_on'];
+
+			while(list($field, $data) = each($contact))
+			{
+				$data = htmlentities($data);
+				if(!is_numeric($field) && $data!='')
+				{
+					$tr_color = $GLOBALS['phpgw']->nextmatchs->alternate_row_color($tr_color);
+					$template->set_var('th_bg', $tr_color);
+					$template->set_var('display_col', $bo->display_name($field));
+					$template->set_var('ref_data', $data);
+					$template->parse('cols', 'view_row', True);
+				}
+			}
+
+			if(count($comm_media) > 0)
+			{
+				$tr_color = $GLOBALS['phpgw']->nextmatchs->alternate_row_color($tr_color);
+				$template->set_var('th_bg', $tr_color);
+				$template->set_var('display_col', lang('communications'));
+				$template->set_var('ref_data', '');
+				$template->parse('cols', 'view_row', True);
+			}
+			
+			while(list($field, $data) = each($comm_media))
+			{
+				$data = htmlentities($data);
+				if(!is_numeric($field) && $data!='')
+				{
+					$tr_color = $GLOBALS['phpgw']->nextmatchs->alternate_row_color($tr_color);
+					$template->set_var('th_bg', $tr_color);
+					$template->set_var('display_col', lang($field));
+					$template->set_var('ref_data', $data);
+					$template->parse('cols', 'view_row', True);
+				}
+			}
+
+			while(list($loc_type, $loc_data) = each($locations))
+			{
+				while(list($field, $data) = each($loc_data))
+				{
+					if($field == 'type')
+						$data = '<b>'.htmlentities($data).'</b>';
+					else
+						$data = htmlentities($data);
+					
+					if(!is_numeric($field) && $data!='')
+					{
+						$field = 'addr_'.$field;
+						$tr_color = $GLOBALS['phpgw']->nextmatchs->alternate_row_color($tr_color);
+						$template->set_var('th_bg', $tr_color);
+						$template->set_var('display_col', $bo->display_name($field));
+						$template->set_var('ref_data', $data);
+						$template->parse('cols', 'view_row', True);
+					}
+				}
+			}
+
+			/* Following cleans up view_row, since we were only using it to fill {cols} */
+			$template->set_var('view_row','');
+
+			echo $template->subst('cols');
+			return true;
+		}
 	}
 ?>
