From 61b6d0b993fcf20a97052f445e6913ac58638d37 Mon Sep 17 00:00:00 2001 From: Ralf Becker Date: Sat, 17 Jun 2006 18:47:02 +0000 Subject: [PATCH] moved contact-data (firstname, lastname and email) from the account-table to the contact table: - all (sql) accounts have now allways a contact associated with them (account_id is added as new column to the contacts table) - contacts queries are simplefied a lot now, as no more join with the accouns-table, union and case when statesments are necessary - lot of the special handling for accounts in the contacts class is no longer needed - new contact-repository mode "sql-ldap" which additional writes all changes to the ldap repository, to allow to use it read-only from eg. thunderbird and still have the full sql speed and features within eGW (not yet fully working!) ==> requites update of API and addressbook to work (setup!) --- phpgwapi/inc/class.accounts_sql.inc.php | 230 ++++++++++++------ phpgwapi/setup/setup.inc.php | 3 +- phpgwapi/setup/tables_current.inc.php | 87 ++++++- phpgwapi/setup/tables_update.inc.php | 296 ++++++++++++++++++++++++ 4 files changed, 533 insertions(+), 83 deletions(-) diff --git a/phpgwapi/inc/class.accounts_sql.inc.php b/phpgwapi/inc/class.accounts_sql.inc.php index 27f5adb748..92bffa61a9 100644 --- a/phpgwapi/inc/class.accounts_sql.inc.php +++ b/phpgwapi/inc/class.accounts_sql.inc.php @@ -46,6 +46,18 @@ class accounts_backend * @var string */ var $table = 'egw_accounts'; + /** + * table name for the contacts + * + * @var string + */ + var $contacts_table = 'egw_addressbook'; + /** + * Join with the accounts-table used in contacts::search + * + * @var string + */ + var $contacts_join = ' RIGHT JOIN egw_accounts ON egw_accounts.account_id=egw_addressbook.account_id'; /** * total number of found entries from get_list method * @@ -73,6 +85,9 @@ class accounts_backend /** * Reads the data of one account + * + * For performance reasons and because the contacts-object itself depends on the accounts-object, + * we directly join with the contacts table for reading! * * @param int $account_id numeric account-id * @return array/boolean array with account data (keys: account_id, account_lid, ...) or false if account not found @@ -81,7 +96,19 @@ class accounts_backend { if (!(int)$account_id) return false; - $this->db->select($this->table,'*',array('account_id' => abs($account_id)),__LINE__,__FILE__); + $join = $extra_cols = ''; + if ($account_id > 0) + { + $extra_cols = $this->contacts_table.'.n_given AS account_firstname,'. + $this->contacts_table.'.n_family AS account_lastname,'. + $this->contacts_table.'.contact_email AS account_email,'. + $this->contacts_table.'.n_fn AS account_fullname,'. + $this->contacts_table.'.contact_id AS person_id,'; + $join = 'LEFT JOIN '.$this->contacts_table.' ON '.$this->table.'.account_id='.$this->contacts_table.'.account_id'; + } + $this->db->select($this->table,$extra_cols.$this->table.'.*',$this->table.'.account_id='.abs($account_id), + __LINE__,__FILE__,false,'',false,0,$join); + if (!($data = $this->db->row(true))) { return false; @@ -90,8 +117,20 @@ class accounts_backend { $data['account_id'] = -$data['account_id']; } - $data['account_fullname'] = $data['account_firstname'].' '.$data['account_lastname']; + if (!$data['account_firstname']) $data['account_firstname'] = $data['account_lid']; + if (!$data['account_lastname']) + { + $data['account_lastname'] = $data['account_type'] == 'g' ? 'Group' : 'User'; + // if we call lang() before the translation-class is correctly setup, + // we can't switch away from english language anymore! + if ($GLOBALS['egw']->translations->lang_arr) + { + $data['account_lastname'] = lang($data['account_lastname']); + } + } + if (!$data['account_fullname']) $data['account_fullname'] = $data['account_firstname'].' '.$data['account_lastname']; + //echo "accounts_sql::read($account_id)"; _debug_array($data); return $data; } @@ -140,14 +179,37 @@ class accounts_backend if ($data['account_type'] == 'g') $data['account_id'] *= -1; } } - else + else // update of existing account { unset($to_write['account_id']); if (!$this->db->update($this->table,$to_write,array('account_id' => abs($data['account_id'])),__LINE__,__FILE__)) { return false; } + // check if account and the contact-data changed + if ($data['account_type'] == 'g' || ($old = $this->read($data['account_id'])) && + $old['account_firstname'] == $data['account_firstname'] && + $old['account_lastname'] == $data['account_lastname'] && + $old['account_email'] == $data['account_email']) + { + return $data['account_id']; // group or no change --> no need to update the contact + } + if (!$data['person_id']) $data['person_id'] = $old['person_id']; } + if (!is_object($GLOBALS['egw']->contacts)) + { + $GLOBALS['egw']->contacts =& CreateObject('phpgwapi.contacts'); + } + $contact = array( + 'n_given' => $data['account_firstname'], + 'n_family' => $data['account_lastname'], + 'email' => $data['account_email'], + 'account_id' => $data['account_id'], + 'id' => $data['person_id'], + 'owner' => 0, + ); + $GLOBALS['egw']->contacts->save($contact); + return $data['account_id']; } @@ -160,8 +222,22 @@ class accounts_backend function delete($account_id) { if (!(int)$account_id) return false; + + $contact_id = $this->id2name($account_id,'person_id'); - return !!$this->db->delete($this->table,array('account_id' => abs($account_id)),__LINE__,__FILE__); + if (!$this->db->delete($this->table,array('account_id' => abs($account_id)),__LINE__,__FILE__)) + { + return false; + } + if ($contact_id) + { + if (!is_object($GLOBALS['egw']->contacts)) + { + $GLOBALS['egw']->contacts =& CreateObject('phpgwapi.contacts'); + } + $GLOBALS['egw']->contacts->delete($contact_id); + } + return true; } /** @@ -249,112 +325,101 @@ class accounts_backend * * ToDo: implement a search like accounts::search * - * @param string $_type - * @param int $start=null - * @param string $sort='' + * @param string $_type='both', 'accounts', 'groups' + * @param int $start=null + * @param string $sort='' ASC or DESC * @param string $order='' - * @param string $query + * @param string $query='' * @param int $offset=null - * @param string $query_type + * @param string $query_type='all' 'start', 'all' (default), 'exact' * @return array */ - function get_list($_type='both', $start = '',$sort = '', $order = '', $query = '', $offset = null, $query_type='') + function get_list($_type='both', $start = null,$sort = '', $order = '', $query = '', $offset = null, $query_type='') { - if (! $sort) + if (!is_object($GLOBALS['egw']->contacts)) { - $sort = "DESC"; + $GLOBALS['egw']->contacts =& CreateObject('phpgwapi.contacts'); } - - if (!empty($order) && preg_match('/^[a-zA-Z_0-9, ]+$/',$order) && (empty($sort) || preg_match('/^(DESC|ASC|desc|asc)$/',$sort))) - { - $orderclause = "ORDER BY $order $sort"; - } - else - { - $orderclause = "ORDER BY account_lid ASC"; - } - + static $order2contact = array( + 'account_firstname' => 'n_given', + 'account_lastname' => 'n_family', + 'account_email' => 'contact_email', + ); + if (isset($order2contact[$order])) $order = $account2contact[$order]; + if ($sort) $order .= ' '.$sort; + switch($_type) { case 'accounts': - $whereclause = "WHERE account_type = 'u'"; + $filter = array('owner' => 0); break; case 'groups': - $whereclause = "WHERE account_type = 'g'"; + $filter = "account_type = 'g'"; break; default: - $whereclause = ''; + case 'both': + $filter = "(contact_owner=0 OR contact_owner IS NULL)"; + break; } - + $criteria = array(); + $wildcard = $query_type == 'start' || $query_type == 'exact' ? '' : '%'; if ($query) { - if ($whereclause) - { - $whereclause .= ' AND ( '; - } - else - { - $whereclause = ' WHERE ( '; - } switch($query_type) { + case 'start': + $query .= '*'; + // fall-through case 'all': default: - $query = '%'.$query; - // fall-through - case 'start': - $query .= '%'; - // fall-through case 'exact': - $query = $this->db->quote($query); - $whereclause .= " account_firstname LIKE $query OR account_lastname LIKE $query OR account_lid LIKE $query )"; + foreach(array('account_lid','n_family','n_given','email') as $col) + { + $criteria[$col] = $query; + } break; + case 'account_firstname': case 'firstname': + $criteria['n_given'] = $query; + break; + case 'account_lastname': case 'lastname': + $criteria['n_family'] = $query; + break; + case 'account_lid': case 'lid': + $criteria['account_lid'] = $query; + break; + case 'account_email': case 'email': - $query = $this->db->quote('%'.$query.'%'); - $whereclause .= " account_$query_type LIKE $query )"; + $criteria['email'] = $query; break; } } - - $sql = "SELECT * FROM $this->table $whereclause $orderclause"; - if ($offset) + $accounts = array(); + if (($contacts =& $GLOBALS['egw']->contacts->search($criteria,false,$order,'account_lid,account_type', + $wildcard,false,'OR',$offset ? array($start,$offset) : $start,$filter,$this->contacts_join))) { - $this->db->limit_query($sql,$start,__LINE__,__FILE__,$offset); + foreach($contacts as $contact) + { + $accounts[] = array( + 'account_id' => ($contact['account_type'] == 'g' ? -1 : 1) * $contact['account_id'], + 'account_lid' => $contact['account_lid'], + 'account_type' => $contact['account_type'], + 'account_firstname' => $contact['n_given'], + 'account_lastname' => $contact['n_family'], + 'account_email' => $contact['email'], + 'person_id' => $contact['id'], + ); + } } - elseif (is_numeric($start)) - { - $this->db->limit_query($sql,$start,__LINE__,__FILE__); - } - else - { - $this->db->query($sql,__LINE__,__FILE__); - } - while ($this->db->next_record()) - { - $accounts[] = Array( - 'account_id' => ($this->db->f('account_type') == 'g' ? -1 : 1) * $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'), - 'account_primary_group' => $this->db->f('account_primary_group'), - 'account_email' => $this->db->f('account_email'), - ); - } - $this->db->query("SELECT count(*) FROM $this->table $whereclause"); - $this->total = $this->db->next_record() ? $this->db->f(0) : 0; + $this->total = $GLOBALS['egw']->contacts->total; return $accounts; } /** - * convert an alphanumeric account-value (account_lid, account_email) to the account_id + * convert an alphanumeric account-value (account_lid, account_email, account_fullname) to the account_id * * Please note: * - if a group and an user have the same account_lid the group will be returned (LDAP only) @@ -367,21 +432,34 @@ class accounts_backend */ function name2id($name,$which='account_lid',$account_type=null) { + if ($account_type === 'g' && $which != 'account_lid') return false; + $where = array(); + $cols = 'account_id'; switch($which) { case 'account_fullname': - $where[] = '('.$this->db->concat('account_firstname',"' '",'account_lastname').')='.$this->db->quote($name); + $table = $this->contacts_table; + $where['n_fn'] = $name; break; - + case 'account_email': + $table = $this->contacts_table; + $where['contact_email'] = $name; + break; + case 'person_id': + $table = $this->contacts_table; + $where['contact_id'] = $name; + break; default: + $table = $this->table; + $cols .= ',account_type'; $where[$which] = $name; } if ($account_type) { $where['account_type'] = $account_type; } - $this->db->select($this->table,'account_id,account_type',$where,__LINE__,__FILE__); + $this->db->select($table,$cols,$where,__LINE__,__FILE__); if(!$this->db->next_record()) return false; return ($this->db->f('account_type') == 'g' ? -1 : 1) * $this->db->f('account_id'); diff --git a/phpgwapi/setup/setup.inc.php b/phpgwapi/setup/setup.inc.php index a969f82296..7742dc0b5e 100755 --- a/phpgwapi/setup/setup.inc.php +++ b/phpgwapi/setup/setup.inc.php @@ -14,7 +14,7 @@ /* Basic information about this app */ $setup_info['phpgwapi']['name'] = 'phpgwapi'; $setup_info['phpgwapi']['title'] = 'eGroupWare API'; - $setup_info['phpgwapi']['version'] = '1.3.007'; + $setup_info['phpgwapi']['version'] = '1.3.008'; $setup_info['phpgwapi']['versions']['current_header'] = '1.28'; $setup_info['phpgwapi']['enable'] = 3; $setup_info['phpgwapi']['app_order'] = 1; @@ -66,3 +66,4 @@ + diff --git a/phpgwapi/setup/tables_current.inc.php b/phpgwapi/setup/tables_current.inc.php index 10e0b310a0..757c876f98 100644 --- a/phpgwapi/setup/tables_current.inc.php +++ b/phpgwapi/setup/tables_current.inc.php @@ -55,17 +55,13 @@ 'account_id' => array('type' => 'auto','nullable' => False), 'account_lid' => array('type' => 'varchar','precision' => '64','nullable' => False), 'account_pwd' => array('type' => 'varchar','precision' => '100','nullable' => False), - 'account_firstname' => array('type' => 'varchar','precision' => '50'), - 'account_lastname' => array('type' => 'varchar','precision' => '50'), 'account_lastlogin' => array('type' => 'int','precision' => '4'), 'account_lastloginfrom' => array('type' => 'varchar','precision' => '255'), 'account_lastpwd_change' => array('type' => 'int','precision' => '4'), 'account_status' => array('type' => 'char','precision' => '1','nullable' => False,'default' => 'A'), 'account_expires' => array('type' => 'int','precision' => '4'), 'account_type' => array('type' => 'char','precision' => '1'), - 'person_id' => array('type' => 'int','precision' => '4'), - 'account_primary_group' => array('type' => 'int','precision' => '4','nullable' => False,'default' => '0'), - 'account_email' => array('type' => 'varchar','precision' => '100') + 'account_primary_group' => array('type' => 'int','precision' => '4','nullable' => False,'default' => '0') ), 'pk' => array('account_id'), 'fk' => array(), @@ -492,5 +488,84 @@ 'fk' => array(), 'ix' => array(array('link_app1','link_id1','link_lastmod'),array('link_app2','link_id2','link_lastmod')), 'uc' => array() - ) + ), + 'egw_addressbook' => array( + 'fd' => array( + 'contact_id' => array('type' => 'auto','nullable' => False), + 'contact_tid' => array('type' => 'char','precision' => '1','default' => 'n'), + 'contact_owner' => array('type' => 'int','precision' => '8','nullable' => False), + 'contact_private' => array('type' => 'int','precision' => '1','default' => '0'), + 'cat_id' => array('type' => 'varchar','precision' => '32'), + 'n_family' => array('type' => 'varchar','precision' => '64'), + 'n_given' => array('type' => 'varchar','precision' => '64'), + 'n_middle' => array('type' => 'varchar','precision' => '64'), + 'n_prefix' => array('type' => 'varchar','precision' => '64'), + 'n_suffix' => array('type' => 'varchar','precision' => '64'), + 'n_fn' => array('type' => 'varchar','precision' => '128'), + 'n_fileas' => array('type' => 'varchar','precision' => '255'), + 'contact_bday' => array('type' => 'varchar','precision' => '10'), + 'org_name' => array('type' => 'varchar','precision' => '64'), + 'org_unit' => array('type' => 'varchar','precision' => '64'), + 'contact_title' => array('type' => 'varchar','precision' => '64'), + 'contact_role' => array('type' => 'varchar','precision' => '64'), + 'contact_assistent' => array('type' => 'varchar','precision' => '64'), + 'contact_room' => array('type' => 'varchar','precision' => '64'), + 'adr_one_street' => array('type' => 'varchar','precision' => '64'), + 'adr_one_street2' => array('type' => 'varchar','precision' => '64'), + 'adr_one_locality' => array('type' => 'varchar','precision' => '64'), + 'adr_one_region' => array('type' => 'varchar','precision' => '64'), + 'adr_one_postalcode' => array('type' => 'varchar','precision' => '64'), + 'adr_one_countryname' => array('type' => 'varchar','precision' => '64'), + 'contact_label' => array('type' => 'text'), + 'adr_two_street' => array('type' => 'varchar','precision' => '64'), + 'adr_two_street2' => array('type' => 'varchar','precision' => '64'), + 'adr_two_locality' => array('type' => 'varchar','precision' => '64'), + 'adr_two_region' => array('type' => 'varchar','precision' => '64'), + 'adr_two_postalcode' => array('type' => 'varchar','precision' => '64'), + 'adr_two_countryname' => array('type' => 'varchar','precision' => '64'), + 'tel_work' => array('type' => 'varchar','precision' => '40'), + 'tel_cell' => array('type' => 'varchar','precision' => '40'), + 'tel_fax' => array('type' => 'varchar','precision' => '40'), + 'tel_assistent' => array('type' => 'varchar','precision' => '40'), + 'tel_car' => array('type' => 'varchar','precision' => '40'), + 'tel_pager' => array('type' => 'varchar','precision' => '40'), + 'tel_home' => array('type' => 'varchar','precision' => '40'), + 'tel_fax_home' => array('type' => 'varchar','precision' => '40'), + 'tel_cell_private' => array('type' => 'varchar','precision' => '40'), + 'tel_other' => array('type' => 'varchar','precision' => '40'), + 'tel_prefer' => array('type' => 'varchar','precision' => '32'), + 'contact_email' => array('type' => 'varchar','precision' => '64'), + 'contact_email_home' => array('type' => 'varchar','precision' => '64'), + 'contact_url' => array('type' => 'varchar','precision' => '128'), + 'contact_url_home' => array('type' => 'varchar','precision' => '128'), + 'contact_freebusy_uri' => array('type' => 'varchar','precision' => '128'), + 'contact_calendar_uri' => array('type' => 'varchar','precision' => '128'), + 'contact_note' => array('type' => 'text'), + 'contact_tz' => array('type' => 'varchar','precision' => '8'), + 'contact_geo' => array('type' => 'varchar','precision' => '32'), + 'contact_pubkey' => array('type' => 'text'), + 'contact_created' => array('type' => 'int','precision' => '8'), + 'contact_creator' => array('type' => 'int','precision' => '4','nullable' => False), + 'contact_modified' => array('type' => 'int','precision' => '8','nullable' => False), + 'contact_modifier' => array('type' => 'int','precision' => '4'), + 'contact_jpegphoto' => array('type' => 'blob'), + 'account_id' => array('type' => 'int','precision' => '4','default' => '0') + ), + 'pk' => array('contact_id'), + 'fk' => array(), + 'ix' => array('contact_owner','cat_id','n_fileas',array('n_family','n_given'),array('n_given','n_family'),array('org_name','n_family','n_given')), + 'uc' => array() + ), + 'egw_addressbook_extra' => array( + 'fd' => array( + 'contact_id' => array('type' => 'int','precision' => '4','nullable' => False), + 'contact_owner' => array('type' => 'int','precision' => '8'), + 'contact_name' => array('type' => 'varchar','precision' => '255','nullable' => False), + 'contact_value' => array('type' => 'text') + ), + 'pk' => array('contact_id','contact_name'), + 'fk' => array(), + 'ix' => array(), + 'uc' => array() + ), ); diff --git a/phpgwapi/setup/tables_update.inc.php b/phpgwapi/setup/tables_update.inc.php index 6f9aab3a97..123bca4319 100644 --- a/phpgwapi/setup/tables_update.inc.php +++ b/phpgwapi/setup/tables_update.inc.php @@ -219,3 +219,299 @@ } return $GLOBALS['setup_info']['phpgwapi']['currentver'] = '1.3.007'; } + + /** + * Updates the addressbook table to the new addressbook in 1.3 + * + * The addressbook table was moved to the addressbook, but has to be moved back, + * as the addressdata of the accounts is no stored only in the addressbook! + * + * It is called, if needed, from phpgwap_upgrade1_3_007 function + */ + function addressbook_upgrade1_2() + { + $GLOBALS['egw_setup']->oProc->RefreshTable('egw_addressbook',array( + 'fd' => array( + 'contact_id' => array('type' => 'auto','nullable' => False), + 'contact_tid' => array('type' => 'char','precision' => '1','default' => 'n'), + 'contact_owner' => array('type' => 'int','precision' => '8','nullable' => False), + 'contact_private' => array('type' => 'int','precision' => '1','default' => '0'), + 'cat_id' => array('type' => 'varchar','precision' => '32'), + 'n_family' => array('type' => 'varchar','precision' => '64'), + 'n_given' => array('type' => 'varchar','precision' => '64'), + 'n_middle' => array('type' => 'varchar','precision' => '64'), + 'n_prefix' => array('type' => 'varchar','precision' => '64'), + 'n_suffix' => array('type' => 'varchar','precision' => '64'), + 'n_fn' => array('type' => 'varchar','precision' => '128'), + 'n_fileas' => array('type' => 'varchar','precision' => '255'), + 'contact_bday' => array('type' => 'varchar','precision' => '10'), + 'org_name' => array('type' => 'varchar','precision' => '64'), + 'org_unit' => array('type' => 'varchar','precision' => '64'), + 'contact_title' => array('type' => 'varchar','precision' => '64'), + 'contact_role' => array('type' => 'varchar','precision' => '64'), + 'contact_assistent' => array('type' => 'varchar','precision' => '64'), + 'contact_room' => array('type' => 'varchar','precision' => '64'), + 'adr_one_street' => array('type' => 'varchar','precision' => '64'), + 'adr_one_street2' => array('type' => 'varchar','precision' => '64'), + 'adr_one_locality' => array('type' => 'varchar','precision' => '64'), + 'adr_one_region' => array('type' => 'varchar','precision' => '64'), + 'adr_one_postalcode' => array('type' => 'varchar','precision' => '64'), + 'adr_one_countryname' => array('type' => 'varchar','precision' => '64'), + 'contact_label' => array('type' => 'text'), + 'adr_two_street' => array('type' => 'varchar','precision' => '64'), + 'adr_two_street2' => array('type' => 'varchar','precision' => '64'), + 'adr_two_locality' => array('type' => 'varchar','precision' => '64'), + 'adr_two_region' => array('type' => 'varchar','precision' => '64'), + 'adr_two_postalcode' => array('type' => 'varchar','precision' => '64'), + 'adr_two_countryname' => array('type' => 'varchar','precision' => '64'), + 'tel_work' => array('type' => 'varchar','precision' => '40'), + 'tel_cell' => array('type' => 'varchar','precision' => '40'), + 'tel_fax' => array('type' => 'varchar','precision' => '40'), + 'tel_assistent' => array('type' => 'varchar','precision' => '40'), + 'tel_car' => array('type' => 'varchar','precision' => '40'), + 'tel_pager' => array('type' => 'varchar','precision' => '40'), + 'tel_home' => array('type' => 'varchar','precision' => '40'), + 'tel_fax_home' => array('type' => 'varchar','precision' => '40'), + 'tel_cell_private' => array('type' => 'varchar','precision' => '40'), + 'tel_other' => array('type' => 'varchar','precision' => '40'), + 'tel_prefer' => array('type' => 'varchar','precision' => '32'), + 'contact_email' => array('type' => 'varchar','precision' => '64'), + 'contact_email_home' => array('type' => 'varchar','precision' => '64'), + 'contact_url' => array('type' => 'varchar','precision' => '128'), + 'contact_url_home' => array('type' => 'varchar','precision' => '128'), + 'contact_freebusy_uri' => array('type' => 'varchar','precision' => '128'), + 'contact_calendar_uri' => array('type' => 'varchar','precision' => '128'), + 'contact_note' => array('type' => 'text'), + 'contact_tz' => array('type' => 'varchar','precision' => '8'), + 'contact_geo' => array('type' => 'varchar','precision' => '32'), + 'contact_pubkey' => array('type' => 'text'), + 'contact_created' => array('type' => 'int','precision' => '8'), + 'contact_creator' => array('type' => 'int','precision' => '4','nullable' => False), + 'contact_modified' => array('type' => 'int','precision' => '8','nullable' => False), + 'contact_modifier' => array('type' => 'int','precision' => '4'), + 'contact_jpegphoto' => array('type' => 'blob'), + ), + 'pk' => array('contact_id'), + 'fk' => array(), + 'ix' => array('cat_id','contact_owner','n_fileas',array('n_family','n_given'),array('n_given','n_family'),array('org_name','n_family','n_given')), + 'uc' => array() + ),array( + // new colum prefix + 'contact_id' => 'id', + 'contact_tid' => 'tid', + 'contact_owner' => 'owner', + 'contact_private' => "CASE access WHEN 'private' THEN 1 ELSE 0 END", + 'n_fn' => 'fn', + 'contact_title' => 'title', + 'contact_bday' => 'bday', + 'contact_note' => 'note', + 'contact_tz' => 'tz', + 'contact_geo' => 'geo', + 'contact_url' => 'url', + 'contact_pubkey' => 'pubkey', + 'contact_label' => 'label', + 'contact_email' => 'email', + 'contact_email_home' => 'email_home', + 'contact_modified' => 'last_mod', + // remove stupid old default values, rename phone-numbers, tel_bbs and tel_video are droped + 'tel_work' => "CASE tel_work WHEN '+1 (000) 000-0000' THEN NULL ELSE tel_work END", + 'tel_cell' => "CASE tel_cell WHEN '+1 (000) 000-0000' THEN NULL ELSE tel_cell END", + 'tel_fax' => "CASE tel_fax WHEN '+1 (000) 000-0000' THEN NULL ELSE tel_fax END", + 'tel_assistent' => "CASE tel_msg WHEN '+1 (000) 000-0000' THEN NULL ELSE tel_msg END", + 'tel_car' => "CASE tel_car WHEN '+1 (000) 000-0000' THEN NULL ELSE tel_car END", + 'tel_pager' => "CASE tel_pager WHEN '+1 (000) 000-0000' THEN NULL ELSE tel_pager END", + 'tel_home' => "CASE tel_home WHEN '+1 (000) 000-0000' THEN NULL ELSE tel_home END", + 'tel_fax_home' => "CASE tel_modem WHEN '+1 (000) 000-0000' THEN NULL ELSE tel_modem END", + 'tel_cell_private' => "CASE tel_isdn WHEN '+1 (000) 000-0000' THEN NULL ELSE tel_isdn END", + 'tel_other' => "CASE tel_voice WHEN '+1 (000) 000-0000' THEN NULL ELSE tel_voice END", + 'tel_prefer' => "CASE tel_prefer WHEN 'tel_voice' THEN 'tel_other' WHEN 'tel_msg' THEN 'tel_assistent' WHEN 'tel_modem' THEN 'tel_fax_home' WHEN 'tel_isdn' THEN 'tel_cell_private' WHEN 'ophone' THEN 'tel_other' ELSE tel_prefer END", + // set creator from owner + 'contact_creator' => 'owner', + // set contact_fileas from org_name, n_family and n_given + 'n_fileas' => "CASE WHEN org_name='' THEN (". + ($name_sql = "CASE WHEN n_given='' THEN n_family ELSE ".$GLOBALS['egw_setup']->db->concat('n_family',"', '",'n_given').' END'). + ") ELSE (CASE WHEN n_family='' THEN org_name ELSE ".$GLOBALS['egw_setup']->db->concat('org_name',"': '",$name_sql).' END) END', + + )); + + // migrate values saved in custom fields to the new table + $db2 = clone($GLOBALS['egw_setup']->db); + $GLOBALS['egw_setup']->db->select('egw_addressbook_extra','contact_id,contact_name,contact_value', + "contact_name IN ('ophone','address2','address3','freebusy_url') AND contact_value != '' AND NOT contact_value IS NULL" + ,__LINE__,__FILE__,false,'','addressbook'); + $old2new = array( + 'ophone' => 'tel_other', + 'address2' => 'adr_one_street2', + 'address3' => 'adr_two_street2', + 'freebusy_url' => 'contact_freebusy_uri', + ); + while (($row = $GLOBALS['egw_setup']->db->row(true))) + { + $db2->update('egw_addressbook',array($old2new[$row['contact_name']] => $row['contact_value']),array( + 'contact_id' => $row['contact_id'], + '('.$old2new[$row['contact_name']].'IS NULL OR '.$old2new[$row['contact_name']]."='')", + ),__LINE__,__FILE__,'addressbook'); + } + // delete the not longer used custom fields plus rubish from old bugs + $GLOBALS['egw_setup']->db->delete('egw_addressbook_extra',"contact_name IN ('ophone','address2','address3','freebusy_url','cat_id','tid','lid','id','ab_id','access','owner','rights')". + " OR contact_value='' OR contact_value IS NULL". + ($db2->capabilities['subqueries'] ? " OR contact_id NOT IN (SELECT contact_id FROM egw_addressbook)" : ''), + __LINE__,__FILE__,'addressbook'); + + // change the m/d/Y birthday format to Y-m-d + $GLOBALS['egw_setup']->db->select('egw_addressbook','contact_id,contact_bday',"contact_bday != ''", + __LINE__,__FILE__,false,'','addressbook'); + while (($row = $GLOBALS['egw_setup']->db->row(true))) + { + list($m,$d,$y) = explode('/',$row['contact_bday']); + $db2->update('egw_addressbook',array( + 'contact_bday' => sprintf('%04d-%02d-%02d',$y,$m,$d) + ),array( + 'contact_id' => $row['contact_id'], + ),__LINE__,__FILE__,'addressbook'); + } + return $GLOBALS['setup_info']['addressbook']['currentver'] = '1.3.001'; + } + + $test[] = '1.3.007'; + function phpgwapi_upgrade1_3_007() + { + // check for a pre 1.3 addressbook, and run the upgrade if needed + if ((float) $GLOBALS['setup_info']['addressbook']['currentver'] < 1.3) + { + addressbook_upgrade1_2(); + } + $GLOBALS['egw_setup']->oProc->AddColumn('egw_addressbook','account_id',array( + 'type' => 'int', + 'precision' => '4', + 'default' => '0' + )); + $GLOBALS['egw_setup']->db->select($GLOBALS['egw_setup']->config_table,'config_value,config_name',array( + 'config_app' => 'phpgwapi', + "(config_name LIKE '%_repository' OR config_name='auth_type')", + ),__LINE__,__FILE__); + while (($row = $GLOBALS['egw_setup']->db->row(true))) + { + $config[$row['config_name']] = $row['config_value']; + } + // migrate account_{firstname|lastname|email} to the contacts-repository + if (!$config['account_repository'] || $config['account_repository'] == 'sql') + { + $accounts = array(); + $GLOBALS['egw_setup']->db->select('egw_accounts','*',array('account_type' => 'u'),__LINE__,__FILE__); + while (($account = $GLOBALS['egw_setup']->db->row(true))) + { + $accounts[] = $account; + } + foreach($accounts as $account) + { + $contact = array( + 'n_given' => $account['account_firstname'], + 'n_family' => $account['account_lastname'], + 'n_fn' => $account['account_firstname'].' '.$account['account_lastname'], + 'contact_email' => $account['account_email'], + 'account_id' => $account['account_id'], + 'contact_owner' => 0, + 'contact_modified' => time(), + 'contact_modifier' => 0, // no user + ); + if (!(int)$account['person_id']) // account not already linked with a contact + { + $contact['contact_created'] = time(); + $contact['contact_creator'] = 0; // no user + $GLOBALS['egw_setup']->db->insert('egw_addressbook',$contact,false,__LINE__,__FILE__); + } + else + { + $GLOBALS['egw_setup']->db->update('egw_addressbook',$contact,array( + 'contact_id' => $data['person_id'], + '(n_given != '.$GLOBALS['egw_setup']->db->quote($account['account_firstname']). + ' OR n_family != '.$GLOBALS['egw_setup']->db->quote($account['account_lastname']). + ' OR contact_email != '.$GLOBALS['egw_setup']->db->quote($account['account_email']).')', + ),__LINE__,__FILE__); + } + } + } + // dropping the no longer used account_{firstname|lastname|email} columns + $GLOBALS['egw_setup']->oProc->DropColumn('egw_accounts',array( + 'fd' => array( + 'account_id' => array('type' => 'auto','nullable' => False), + 'account_lid' => array('type' => 'varchar','precision' => '64','nullable' => False), + 'account_pwd' => array('type' => 'varchar','precision' => '100','nullable' => False), + 'account_lastname' => array('type' => 'varchar','precision' => '50'), + 'account_lastlogin' => array('type' => 'int','precision' => '4'), + 'account_lastloginfrom' => array('type' => 'varchar','precision' => '255'), + 'account_lastpwd_change' => array('type' => 'int','precision' => '4'), + 'account_status' => array('type' => 'char','precision' => '1','nullable' => False,'default' => 'A'), + 'account_expires' => array('type' => 'int','precision' => '4'), + 'account_type' => array('type' => 'char','precision' => '1'), + 'person_id' => array('type' => 'int','precision' => '4'), + 'account_primary_group' => array('type' => 'int','precision' => '4','nullable' => False,'default' => '0'), + 'account_email' => array('type' => 'varchar','precision' => '100') + ), + 'pk' => array('account_id'), + 'fk' => array(), + 'ix' => array(), + 'uc' => array('account_lid') + ),'account_firstname'); + $GLOBALS['egw_setup']->oProc->DropColumn('egw_accounts',array( + 'fd' => array( + 'account_id' => array('type' => 'auto','nullable' => False), + 'account_lid' => array('type' => 'varchar','precision' => '64','nullable' => False), + 'account_pwd' => array('type' => 'varchar','precision' => '100','nullable' => False), + 'account_lastlogin' => array('type' => 'int','precision' => '4'), + 'account_lastloginfrom' => array('type' => 'varchar','precision' => '255'), + 'account_lastpwd_change' => array('type' => 'int','precision' => '4'), + 'account_status' => array('type' => 'char','precision' => '1','nullable' => False,'default' => 'A'), + 'account_expires' => array('type' => 'int','precision' => '4'), + 'account_type' => array('type' => 'char','precision' => '1'), + 'person_id' => array('type' => 'int','precision' => '4'), + 'account_primary_group' => array('type' => 'int','precision' => '4','nullable' => False,'default' => '0'), + 'account_email' => array('type' => 'varchar','precision' => '100') + ), + 'pk' => array('account_id'), + 'fk' => array(), + 'ix' => array(), + 'uc' => array('account_lid') + ),'account_lastname'); + $GLOBALS['egw_setup']->oProc->DropColumn('egw_accounts',array( + 'fd' => array( + 'account_id' => array('type' => 'auto','nullable' => False), + 'account_lid' => array('type' => 'varchar','precision' => '64','nullable' => False), + 'account_pwd' => array('type' => 'varchar','precision' => '100','nullable' => False), + 'account_lastlogin' => array('type' => 'int','precision' => '4'), + 'account_lastloginfrom' => array('type' => 'varchar','precision' => '255'), + 'account_lastpwd_change' => array('type' => 'int','precision' => '4'), + 'account_status' => array('type' => 'char','precision' => '1','nullable' => False,'default' => 'A'), + 'account_expires' => array('type' => 'int','precision' => '4'), + 'account_type' => array('type' => 'char','precision' => '1'), + 'account_primary_group' => array('type' => 'int','precision' => '4','nullable' => False,'default' => '0'), + 'account_email' => array('type' => 'varchar','precision' => '100') + ), + 'pk' => array('account_id'), + 'fk' => array(), + 'ix' => array(), + 'uc' => array('account_lid') + ),'person_id'); + $GLOBALS['egw_setup']->oProc->DropColumn('egw_accounts',array( + 'fd' => array( + 'account_id' => array('type' => 'auto','nullable' => False), + 'account_lid' => array('type' => 'varchar','precision' => '64','nullable' => False), + 'account_pwd' => array('type' => 'varchar','precision' => '100','nullable' => False), + 'account_lastlogin' => array('type' => 'int','precision' => '4'), + 'account_lastloginfrom' => array('type' => 'varchar','precision' => '255'), + 'account_lastpwd_change' => array('type' => 'int','precision' => '4'), + 'account_status' => array('type' => 'char','precision' => '1','nullable' => False,'default' => 'A'), + 'account_expires' => array('type' => 'int','precision' => '4'), + 'account_type' => array('type' => 'char','precision' => '1'), + 'account_primary_group' => array('type' => 'int','precision' => '4','nullable' => False,'default' => '0') + ), + 'pk' => array('account_id'), + 'fk' => array(), + 'ix' => array(), + 'uc' => array('account_lid') + ),'account_email'); + + return $GLOBALS['setup_info']['phpgwapi']['currentver'] = '1.3.008'; + } +?>