From 86368a190306e81b022474e7cb0a52f3f5671a25 Mon Sep 17 00:00:00 2001 From: Ralf Becker Date: Fri, 25 Apr 2008 19:06:15 +0000 Subject: [PATCH] uid and etag (optimistic locking) for addressbook --- addressbook/inc/class.bocontacts.inc.php | 170 +++++++------------ addressbook/inc/class.socontacts.inc.php | 1 + addressbook/inc/class.socontacts_sql.inc.php | 132 +++++++++----- addressbook/inc/class.uicontacts.inc.php | 10 ++ addressbook/setup/egw_de.lang | 4 +- addressbook/setup/egw_en.lang | 2 + addressbook/setup/etemplates.inc.php | 4 +- addressbook/templates/default/edit.xet | 38 ++++- phpgwapi/setup/setup.inc.php | 5 +- phpgwapi/setup/tables_current.inc.php | 8 +- phpgwapi/setup/tables_update.inc.php | 27 ++- 11 files changed, 242 insertions(+), 159 deletions(-) diff --git a/addressbook/inc/class.bocontacts.inc.php b/addressbook/inc/class.bocontacts.inc.php index d5bc62e741..cdbb7c8301 100755 --- a/addressbook/inc/class.bocontacts.inc.php +++ b/addressbook/inc/class.bocontacts.inc.php @@ -8,7 +8,7 @@ * @package addressbook * @copyright (c) 2005/6 by Cornelius Weiss and Ralf Becker * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License - * @version $Id$ + * @version $Id$ */ require_once(EGW_INCLUDE_ROOT.'/addressbook/inc/class.socontacts.inc.php'); @@ -34,12 +34,12 @@ class bocontacts extends socontacts * @var int $now_su actual user (!) time */ var $now_su; - + /** * @var array $timestamps timestamps */ var $timestamps = array('modified','created'); - + /** * @var array $fileas_types */ @@ -61,7 +61,7 @@ class bocontacts extends socontacts 'n_family, n_prefix', 'n_fn', ); - + /** * @var array $org_fields fields belonging to the (virtual) organisation entry */ @@ -95,7 +95,7 @@ class bocontacts extends socontacts * @var double $org_common_factor minimum percentage of the contacts with identical values to construct the "common" (virtual) org-entry */ var $org_common_factor = 0.6; - + var $contact_fields = array(); var $business_contact_fields = array(); var $home_contact_fields = array(); @@ -128,17 +128,17 @@ class bocontacts extends socontacts function bocontacts($contact_app='addressbook') { $this->socontacts($contact_app); - + $this->tz_offset_s = 3600 * $GLOBALS['egw_info']['user']['preferences']['common']['tz_offset']; $this->now_su = time() + $this->tz_offset_s; $this->prefs =& $GLOBALS['egw_info']['user']['preferences']['addressbook']; // get the default addressbook from the users prefs - $this->default_addressbook = $GLOBALS['egw_info']['user']['preferences']['addressbook']['add_default'] ? + $this->default_addressbook = $GLOBALS['egw_info']['user']['preferences']['addressbook']['add_default'] ? (int)$GLOBALS['egw_info']['user']['preferences']['addressbook']['add_default'] : $this->user; - $this->default_private = substr($GLOBALS['egw_info']['user']['preferences']['addressbook']['add_default'],-1) == 'p'; + $this->default_private = substr($GLOBALS['egw_info']['user']['preferences']['addressbook']['add_default'],-1) == 'p'; if ($this->default_addressbook > 0 && $this->default_addressbook != $this->user && - ($this->default_private || + ($this->default_private || $this->default_addressbook == (int)$GLOBALS['egw']->preferences->forced['addressbook']['add_default'] || $this->default_addressbook == (int)$GLOBALS['egw']->preferences->default['addressbook']['add_default'])) { @@ -251,7 +251,7 @@ class bocontacts extends socontacts $this->org_fields = unserialize($GLOBALS['egw_info']['server']['org_fileds_to_update']); } } - + /** * calculate the file_as string from the contact and the file_as type * @@ -263,13 +263,13 @@ class bocontacts extends socontacts { if (is_null($type)) $type = $contact['fileas_type']; if (!$type) $type = $this->fileas_types[0]; - + if (strpos($type,'n_fn') !== false) $contact['n_fn'] = $this->fullname($contact); - + $fileas = str_replace(array('n_prefix','n_given','n_middle','n_family','n_suffix','n_fn','org_name','org_unit','adr_one_locality'), array($contact['n_prefix'],$contact['n_given'],$contact['n_middle'],$contact['n_family'],$contact['n_suffix'], $contact['n_fn'],$contact['org_name'],$contact['org_unit'],$contact['adr_one_locality']),$type); - + // removing empty delimiters, caused by empty contact fields $fileas = str_replace(array(', , : ',', : ',': , ',', , ',': : '),array(': ',': ',': ',', ',': '),$fileas); while ($fileas{0} == ':' || $fileas{0} == ',') $fileas = substr($fileas,2); @@ -289,7 +289,7 @@ class bocontacts extends socontacts function fileas_type($contact,$file_as=null) { if (is_null($file_as)) $file_as = $contact['n_fileas']; - + if ($file_as) { foreach($this->fileas_types as $type) @@ -355,7 +355,7 @@ class bocontacts extends socontacts * it gets called everytime when data is read from the db * This function needs to be reimplemented in the derived class * - * @param array $data + * @param array $data */ function db2data($data) { @@ -368,7 +368,7 @@ class bocontacts extends socontacts } } $data['photo'] = $this->photo_src($data['id'],$data['jpegphoto']); - + // set freebusy_uri for accounts if (!$data['freebusy_uri'] && !$data['owner'] && $data['account_id'] && !is_object($GLOBALS['egw_setup'])) { @@ -378,7 +378,7 @@ class bocontacts extends socontacts } return $data; } - + /** * src for photo: returns array with linkparams if jpeg exists or the $default image-name if not * @param int $id contact_id @@ -448,7 +448,7 @@ class bocontacts extends socontacts } return true; } - + /** * saves contact to db * @@ -488,7 +488,7 @@ class bocontacts extends socontacts // allow admins to import contacts with creator / created date set if (!$contact['creator'] || !$this->is_admin($contact)) $contact['creator'] = $this->user; if (!$contact['created'] || !$this->is_admin($contact)) $contact['created'] = $this->now_su; - + if (!$contact['tid']) $contact['tid'] = 'n'; } if (!$contact['owner']) @@ -529,8 +529,9 @@ class bocontacts extends socontacts if(!($this->error = parent::save($to_write)) && is_object($GLOBALS['egw']->contenthistory)) { $contact['id'] = $to_write['id']; + $contact['etag'] = $to_write['etag']; $GLOBALS['egw']->contenthistory->updateTimeStamp('contacts', $contact['id'],$isUpdate ? 'modify' : 'add', time()); - + if ($contact['account_id']) // invalidate the cache of the accounts class { $GLOBALS['egw']->accounts->cache_invalidate($contact['account_id']); @@ -545,11 +546,11 @@ class bocontacts extends socontacts return $this->error ? false : $contact['id']; } - + /** * reads contacts matched by key and puts all cols in the data array * - * @param int/string $contact_id + * @param int/string $contact_id * @return array/boolean array with contact data, null if not found or false on no view perms */ function read($contact_id) @@ -564,10 +565,10 @@ class bocontacts extends socontacts } // determine the file-as type $data['fileas_type'] = $this->fileas_type($data); - + return $data; } - + /** * Checks if the current user has the necessary ACL rights * @@ -581,13 +582,13 @@ class bocontacts extends socontacts */ function check_perms($needed,$contact,$deny_account_delete=false) { - if ((!is_array($contact) || !isset($contact['owner'])) && + if ((!is_array($contact) || !isset($contact['owner'])) && !($contact = parent::read(is_array($contact) ? $contact['id'] : $contact))) { return null; } $owner = $contact['owner']; - + // allow the user to edit his own account if (!$owner && $needed == EGW_ACL_EDIT && $contact['account_id'] == $this->user && $this->own_account_acl) { @@ -598,10 +599,10 @@ class bocontacts extends socontacts { return false; } - return ($this->grants[$owner] & $needed) && + return ($this->grants[$owner] & $needed) && (!$contact['private'] || ($this->grants[$owner] & EGW_ACL_PRIVATE) || in_array($owner,$this->memberships)); } - + /** * Read (virtual) org-entry (values "common" for most contacts in the given org) * @@ -611,7 +612,7 @@ class bocontacts extends socontacts function read_org($org_id) { if (!$org_id) return false; - + $org = array(); foreach(explode('|||',$org_id) as $part) { @@ -666,7 +667,7 @@ class bocontacts extends socontacts unset($contact); } } - + // create a statistic about the commonness of each fields values $fields = array(); foreach($contacts as $contact) @@ -716,7 +717,7 @@ class bocontacts extends socontacts } return $org; } - + /** * Return all org-members with same content in one or more of the given fields (only org_fields are counting) * @@ -736,7 +737,7 @@ class bocontacts extends socontacts } return parent::search($criteria,false,'n_family,n_given','','',false,'OR',false,array('org_name'=>$org_name)); } - + /** * Return the changed fields from two versions of a contact (not modified or modifier) * @@ -761,7 +762,7 @@ class bocontacts extends socontacts } return $changed; } - + /** * Change given fields in all members of the org with identical content in the field * @@ -770,7 +771,7 @@ class bocontacts extends socontacts * @param array $to changed/new version of the contact * @param array $members=null org-members to change, default null --> function queries them itself * @return array/boolean (changed-members,changed-fields,failed-members) or false if no org_fields changed or no (other) members matching that fields - */ + */ function change_org($org_name,$from,$to,$members=null) { if (!($changed = $this->changed_fields($from,$to,true))) return false; @@ -780,7 +781,7 @@ class bocontacts extends socontacts $members = $this->org_similar($org_name,$changed); } if (!$members) return false; - + $changed_members = $changed_fields = $failed_members = 0; foreach($members as $member) { @@ -812,7 +813,7 @@ class bocontacts extends socontacts /** * get title for a contact identified by $contact - * + * * Is called as hook to participate in the linking. The format is determined by the link_title preference. * * @param int/string/array $contact int/string id or array with contact @@ -839,7 +840,7 @@ class bocontacts extends socontacts /** * get title for multiple contacts identified by $ids - * + * * Is called as hook to participate in the linking. The format is determined by the link_title preference. * * @param array $ids array with contact-id's @@ -901,61 +902,22 @@ class bocontacts extends socontacts } return $result; } - - /** - * Hook called by link-class to include calendar in the appregistry of the linkage - * - * @param array/string $location location and other parameters (not used) - * @return array with method-names - */ - function search_link($location) - { - return array( - 'query' => 'addressbook.bocontacts.link_query', - 'title' => 'addressbook.bocontacts.link_title', - 'titles' => 'addressbook.bocontacts.link_titles', - 'view' => array( - 'menuaction' => 'addressbook.uicontacts.view' - ), - 'view_id' => 'contact_id', - 'add' => array( - 'menuaction' => 'addressbook.uicontacts.edit' - ), - 'add_app' => 'link_app', - 'add_id' => 'link_id', - 'add_popup' => '850x440', - ); - } - /** - * Register contacts as calendar resources (items which can be sheduled by the calendar) - * - * @param array $args hook-params (not used) - * @return array - */ - function calendar_resources($args) - { - return array( - 'type' => 'c',// one char type-identifiy for this resources - 'info' => 'addressbook.bocontacts.calendar_info',// info method, returns array with id, type & name for a given id - ); - } - /** * returns info about contacts for calender * * @param int/array $ids single contact-id or array of id's - * @return array + * @return array */ function calendar_info($ids) { if (!$ids) return null; - + $data = array(); foreach(!is_array($ids) ? array($ids) : $ids as $id) { if (!($contact = $this->read($id))) continue; - + $data[] = array( 'res_id' => $id, 'email' => $contact['email'] ? $contact['email'] : $contact['email_home'], @@ -980,7 +942,7 @@ class bocontacts extends socontacts /** * Called by edit-account hook, when an account get edited --> not longer used - * + * * This function is still there, to not give a fatal error, if the hook still exists. * Can be removed after the next db-update, which also reloads the hooks. RalfBecker 2006/09/18 * @@ -992,10 +954,10 @@ class bocontacts extends socontacts include(EGW_INCLUDE_ROOT.'/addressbook/setup/setup.inc.php'); $GLOBALS['egw']->hooks->register_hooks('addressbook',$setup_info['addressbook']['hooks']); } - + /** * Merges some given addresses into the first one and delete the others - * + * * If one of the other addresses is an account, everything is merged into the account. * If two accounts are in $ids, the function fails (returns false). * @@ -1012,7 +974,7 @@ class bocontacts extends socontacts if (!is_null($account)) { echo $this->error = 'Can not merge more then one account!'; - return false; // we dont deal with two accounts! + return false; // we dont deal with two accounts! } $account = $contact; continue; @@ -1053,7 +1015,7 @@ class bocontacts extends socontacts if (!is_array($target['cat_id'])) $target['cat_id'] = $target['cat_id'] ? explode(',',$target['cat_id']) : array(); $target['cat_id'] = array_unique(array_merge($target['cat_id'],is_array($value)?$value:explode(',',$value))); break; - + default: if (!$target[$name]) $target[$name] = $value; break; @@ -1061,7 +1023,7 @@ class bocontacts extends socontacts } } if (!$this->save($target)) return 0; - + $success = 1; foreach($contacts as $contact) { @@ -1077,7 +1039,7 @@ class bocontacts extends socontacts } return $success; } - + /** * Check if user has required rights for a list or list-owner * @@ -1089,12 +1051,12 @@ class bocontacts extends socontacts function check_list($list,$required,$owner=null) { if ($list && ($list_data = $this->read_list($list))) - { + { $owner = $list_data['list_owner']; } return !!($this->grants[$owner] & $required); } - + /** * Adds a distribution list * @@ -1106,10 +1068,10 @@ class bocontacts extends socontacts function add_list($name,$owner,$contacts=array()) { if (!$this->check_list(null,EGW_ACL_ADD,$owner)) return false; - + return parent::add_list($name,$owner,$contacts); } - + /** * Adds one contact to a distribution list * @@ -1120,10 +1082,10 @@ class bocontacts extends socontacts function add2list($contact,$list) { if (!$this->check_list($list,EGW_ACL_EDIT)) return false; - + return parent::add2list($contact,$list); } - + /** * Removes one contact from distribution list(s) * @@ -1134,7 +1096,7 @@ class bocontacts extends socontacts function remove_from_list($contact,$list=null) { if ($list && !$this->check_list($list,EGW_ACL_EDIT)) return false; - + return parent::remove_from_list($contact,$list); } @@ -1147,10 +1109,10 @@ class bocontacts extends socontacts function delete_list($list) { if (!$this->check_list($list,EGW_ACL_DELETE)) return false; - + return parent::delete_list($list); } - + /** * Read data of a distribution list * @@ -1160,20 +1122,20 @@ class bocontacts extends socontacts function read_list($list) { static $cache; - + if (isset($cache[$list])) return $cache[$list]; - - return $cache[$list] = parent::read_list($list); + + return $cache[$list] = parent::read_list($list); } - + /** * Get the address-format of a country * * This is a good reference where I got nearly all information, thanks to mikaelarhelger-AT-gmail.com * http://www.bitboost.com/ref/international-address-formats.html - * + * * Mail me (RalfBecker-AT-outdoor-training.de) if you want your nation added or fixed. - * + * * @param string $country * @return string 'city_state_postcode' (eg. US) or 'postcode_city' (eg. DE) */ @@ -1200,7 +1162,7 @@ class bocontacts extends socontacts case 'US': $adr_format = 'city_state_postcode'; break; - + case 'AR': case 'AT': case 'BE': @@ -1229,7 +1191,7 @@ class bocontacts extends socontacts case 'SE': $adr_format = 'postcode_city'; break; - + default: $adr_format = $this->prefs['addr_format'] ? $this->prefs['addr_format'] : 'postcode_city'; } @@ -1305,7 +1267,7 @@ class bocontacts extends socontacts { $contact['n_fn'] = $this->fullname($contact); } - + if (!isset($contact['n_fileas']) || empty($contact['n_fileas'])) { $contact['n_fileas'] = $this->fileas($contact); diff --git a/addressbook/inc/class.socontacts.inc.php b/addressbook/inc/class.socontacts.inc.php index 2b2cb3147f..6d6a53bfca 100755 --- a/addressbook/inc/class.socontacts.inc.php +++ b/addressbook/inc/class.socontacts.inc.php @@ -464,6 +464,7 @@ class socontacts if (!($error_nr = $this->somain->save())) { $contact['id'] = $this->somain->data['id']; + $contact['etag'] = $this->somain->data['etag']; if ($this->contact_repository == 'sql-ldap') { diff --git a/addressbook/inc/class.socontacts_sql.inc.php b/addressbook/inc/class.socontacts_sql.inc.php index 26318898a9..376f9d2ccf 100644 --- a/addressbook/inc/class.socontacts_sql.inc.php +++ b/addressbook/inc/class.socontacts_sql.inc.php @@ -7,7 +7,7 @@ * @package addressbook * @copyright (c) 2006-8 by Ralf Becker * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License - * @version $Id$ + * @version $Id$ */ include_once(EGW_INCLUDE_ROOT.'/etemplate/inc/class.so_sql.inc.php'); @@ -15,11 +15,11 @@ include_once(EGW_INCLUDE_ROOT.'/etemplate/inc/class.so_sql.inc.php'); /** * SQL storage object of the adressbook */ -class socontacts_sql extends so_sql +class socontacts_sql extends so_sql { /** * name of customefields table - * + * * @var string */ var $extra_table = 'egw_addressbook_extra'; @@ -29,7 +29,7 @@ class socontacts_sql extends so_sql var $account_repository = 'sql'; var $contact_repository = 'sql'; var $grants; - + /** * internal name of the id, gets mapped to uid * @@ -49,7 +49,7 @@ class socontacts_sql extends so_sql * @var string */ var $ab2list_table = 'egw_addressbook2list'; - + function socontacts_sql() { $this->so_sql('phpgwapi','egw_addressbook',null,'contact_',true); // true = using the global db object, no clone! @@ -67,7 +67,7 @@ class socontacts_sql extends so_sql $this->contact_repository = $GLOBALS['egw_info']['server']['contact_repository']; } } - + /** * Query organisations by given parameters * @@ -82,7 +82,7 @@ class socontacts_sql extends so_sql * @var int $param[num_rows] * @var string $param[sort] ASC or DESC * @return array or arrays with keys org_name,count and evtl. adr_one_location or org_unit - */ + */ function organisations($param) { $filter = is_array($param['col_filter']) ? $param['col_filter'] : array(); @@ -104,7 +104,7 @@ class socontacts_sql extends so_sql if ($param['owner']) { if (!$this->grants[(int) $filter['owner']]) return false; // we have no access to that addressbook - + $filter['owner'] = $param['owner']; $filter['private'] = 0; } @@ -142,7 +142,7 @@ class socontacts_sql extends so_sql else // by adr_one_location or org_unit { // org total for more then one $by - $by_expr = $by == 'org_unit_count' ? "COUNT(DISTINCT CASE WHEN org_unit IS NULL THEN '' ELSE org_unit END)" : + $by_expr = $by == 'org_unit_count' ? "COUNT(DISTINCT CASE WHEN org_unit IS NULL THEN '' ELSE org_unit END)" : "COUNT(DISTINCT CASE WHEN adr_one_locality IS NULL THEN '' ELSE adr_one_locality END)"; $append = "GROUP BY org_name HAVING $by_expr > 1 ORDER BY org_name $sort"; parent::search($param['search'],array('org_name'),$append,array( @@ -165,7 +165,7 @@ class socontacts_sql extends so_sql } $rows = parent::search($param['search'],array('org_name'),$append,$extra,'%',false,'OR', array($param['start'],$param['num_rows']),$filter); - + if (!$rows) return false; // query the values for *_count == 1, to display them instead @@ -177,10 +177,10 @@ class socontacts_sql extends so_sql $filter['org_name'][$row['org_name']] = $row['org_name']; // use as key too to have every org only once } $org_key = $row['org_name'].($by ? '|||'.($row[$by] || $row[$by.'_count']==1 ? $row[$by] : '|||') : ''); - $orgs[$org_key] = $row; + $orgs[$org_key] = $row; } unset($rows); - + if (count($filter['org_name'])) { foreach((array) parent::search($criteria,array('org_name','org_unit','adr_one_locality'),'GROUP BY org_name,org_unit,adr_one_locality', @@ -219,7 +219,7 @@ class socontacts_sql extends so_sql * For a union-query you call search for each query with $start=='UNION' and one more with only $order_by and $start set to run the union-query. * * @param array/string $criteria array of key and data cols, OR a SQL query (content for WHERE), fully quoted (!) - * @param boolean/string/array $only_keys=true True returns only keys, False returns all cols. or + * @param boolean/string/array $only_keys=true True returns only keys, False returns all cols. or * comma seperated list or array of columns to return * @param string $order_by='' fieldnames + {ASC|DESC} separated by colons ',', can also contain a GROUP BY (if it contains ORDER BY) * @param string/array $extra_cols='' string or array of strings to be added to the SELECT, eg. "count(*) as num" @@ -228,7 +228,7 @@ class socontacts_sql extends so_sql * @param string $op='AND' defaults to 'AND', can be set to 'OR' too, then criteria's are OR'ed together * @param mixed $start=false if != false, return only maxmatch rows begining with start, or array($start,$num), or 'UNION' for a part of a union query * @param array $filter=null if set (!=null) col-data pairs, to be and-ed (!) into the query without wildcards - * @param string $join='' sql to do a join, added as is after the table-name, eg. ", table2 WHERE x=y" or + * @param string $join='' sql to do a join, added as is after the table-name, eg. ", table2 WHERE x=y" or * "LEFT JOIN table2 ON (x=y)", Note: there's no quoting done on $join! * @param boolean $need_full_no_count=false If true an unlimited query is run to determine the total number of rows, default false * @return boolean/array of matching rows (the row is an array of the cols) or False @@ -250,7 +250,7 @@ class socontacts_sql extends so_sql $filter[] = $this->_cat_filter((int)$filter['cat_id'],$not); unset($filter['cat_id']); } - + // add filter for read ACL in sql, if user is NOT the owner of the addressbook if (isset($this->grants) && !(isset($filter['owner']) && $filter['owner'] == $GLOBALS['egw_info']['user']['account_id'])) { @@ -258,7 +258,7 @@ class socontacts_sql extends so_sql if (isset($filter['owner'])) { if (!$this->grants[(int) $filter['owner']]) return false; // we have no access to that addressbook - + $filter['private'] = 0; } else // search all addressbooks, incl. accounts @@ -400,16 +400,16 @@ class socontacts_sql extends so_sql } } $rows =& parent::search($criteria,$only_keys,$order_by,$extra_cols,$wildcard,$empty,$op,$start,$filter,$join,$need_full_no_count); - + if ($start === false) $this->total = is_array($rows) ? count($rows) : 0; // so_sql sets total only for $start !== false! - + return $rows; } - + /** * fix cat_id filter to search in comma-separated multiple cats and return subcats - * - * @internal + * + * @internal * @param int $cat_id * @return string sql to filter by given cat */ @@ -430,11 +430,11 @@ class socontacts_sql extends so_sql } return $cfilter; } - + /** * fix cat_id criteria to search in comma-separated multiple cats - * - * @internal + * + * @internal * @param int/array $cats * @return array of sql-strings to be OR'ed or AND'ed together */ @@ -447,7 +447,7 @@ class socontacts_sql extends so_sql } return $cat_filter; } - + /** * Change the ownership of contacts owned by a given account * @@ -472,7 +472,7 @@ class socontacts_sql extends so_sql * * @param array $uids user or group id's * @return array with list_id => array(list_id,list_name,list_owner,...) pairs - */ + */ function get_lists($uids) { $user = $GLOBALS['egw_info']['user']['account_id']; @@ -485,7 +485,7 @@ class socontacts_sql extends so_sql //echo "

socontacts_sql::get_lists(".print_r($uids,true).")

\n"; _debug_array($lists); return $lists; } - + /** * Adds a distribution list * @@ -497,7 +497,7 @@ class socontacts_sql extends so_sql function add_list($name,$owner,$contacts=array()) { if (!$name || !(int)$owner) return false; - + if ($this->db->select($this->lists_table,'list_id',array( 'list_name' => $name, 'list_owner' => $owner, @@ -511,7 +511,7 @@ class socontacts_sql extends so_sql 'list_created' => time(), 'list_creator' => $GLOBALS['egw_info']['user']['account_id'], ),array(),__LINE__,__FILE__)) return false; - + if ((int)($list_id = $this->db->get_last_insert_id($this->lists_table,'list_id')) && $contacts) { foreach($contacts as $contact) @@ -521,7 +521,7 @@ class socontacts_sql extends so_sql } return $list_id; } - + /** * Adds one contact to a distribution list * @@ -547,7 +547,7 @@ class socontacts_sql extends so_sql 'list_added_by' => $GLOBALS['egw_info']['user']['account_id'], ),array(),__LINE__,__FILE__); } - + /** * Removes one contact from distribution list(s) * @@ -558,7 +558,7 @@ class socontacts_sql extends so_sql function remove_from_list($contact,$list=null) { if (!(int)$list && !is_null($list) || !(int)$contact) return false; - + $where = array( 'contact_id' => $contact, ); @@ -566,7 +566,7 @@ class socontacts_sql extends so_sql return $this->db->delete($this->ab2list_table,$where,__LINE__,__FILE__); } - + /** * Deletes a distribution list (incl. it's members) * @@ -576,13 +576,65 @@ class socontacts_sql extends so_sql function delete_list($list) { if (!$this->db->delete($this->lists_table,array('list_id' => $list),__LINE__,__FILE__)) return false; - + $this->db->delete($this->ab2list_table,array('list_id' => $list),__LINE__,__FILE__); - - return $this->db->affected_rows(); + + return $this->db->affected_rows(); } - - + + /** + * Reads a contact, reimplemented to use the uid, if a non-numeric key is given + * + * @param int|string|array $keys + * @param string|array $extra_cols + * @param string $join + * @return array|boolean + */ + function read($keys,$extra_cols='',$join='') + { + if (!is_array($keys) && !is_numeric($keys)) + { + $keys = array('contact_uid' => $keys); + } + return parent::read($keys,$extra_cols,$join); + } + + /** + * Saves a contact, reimplemented to check a given etag and set a uid + * + * @param array $keys if given $keys are copied to data before saveing => allows a save as + * @param string|array $extra_where=null extra where clause, eg. to check the etag, returns 'nothing_affected' if not affected rows + * @return int 0 on success and errno != 0 else + */ + function save($keys=null) + { + if (is_array($keys) && count($keys)) $this->data_merge($keys); + + if (isset($this->data['etag'])) + { + $etag = $this->data['etag']; + unset($this->data['etag']); + if (!($err = parent::save(array('contact_etag=contact_etag+1'),array('contact_etag' => $etag)))) + { + $this->data['etag'] = $etag+1; + } + else + { + $this->data['etag'] = $etag; + } + } + else + { + $err = parent::save(); + } + if (!$err && !$this->data['uid']) + { + $this->update(array('uid' => common::generate_uid('addressbook',$this->data['id']))); + } + return $err; + } + + /** * Read data of a distribution list * @@ -592,7 +644,7 @@ class socontacts_sql extends so_sql function read_list($list) { if (!$list) return false; - + return $this->db->select($this->lists_table,'*',array('list_id'=>$list),__LINE__,__FILE__)->fetch(); - } + } } diff --git a/addressbook/inc/class.uicontacts.inc.php b/addressbook/inc/class.uicontacts.inc.php index 4a3bafdbbb..88388d41a3 100644 --- a/addressbook/inc/class.uicontacts.inc.php +++ b/addressbook/inc/class.uicontacts.inc.php @@ -1278,6 +1278,16 @@ class uicontacts extends bocontacts } } } + elseif($this->error === true) + { + $content['msg'] = lang('Error: the entry has been updated since you opened it for editing!').'
'. + lang('Copy your changes to the clipboard, %1reload the entry%2 and merge them.','',''); + break; // dont refresh the list + } else { $content['msg'] = lang('Error saving the contact !!!'). diff --git a/addressbook/setup/egw_de.lang b/addressbook/setup/egw_de.lang index eeb686cc82..095163d757 100644 --- a/addressbook/setup/egw_de.lang +++ b/addressbook/setup/egw_de.lang @@ -106,6 +106,7 @@ contacts to ldap, account contact-data to sql admin de Kontakte nach LDAP, Konta contains addressbook de beinhaltet copied by %1, from record #%2. addressbook de Kopiert von %1, vom Datensatz Nr. %2. copy a contact and edit the copy addressbook de Kopiert einen Kontakt und bearbeitet dann die Kopie +copy your changes to the clipboard, %1reload the entry%2 and merge them. addressbook de Kopieren Sie Ihre Änderungen in die Zwischenablage, %1laden Sie den Eintrag neu%2 und fügen diese wieder ein. country common de Land create new links addressbook de Neue Verknüpfung erstellen created addressbook de Angelegt @@ -158,6 +159,7 @@ end addressbook de Ende enter the path to the exported file here addressbook de Bitte geben Sie den Pfad für die exportierte Datei an error deleting the contact !!! addressbook de Fehler beim Löschen des Kontakts !!! error saving the contact !!! addressbook de Fehler beim Speichern des Kontakts !!! +error: the entry has been updated since you opened it for editing! addressbook de Fehler: der Eintrag wurde geändert, seit Sie ihn zum Bearbeiten geöffnet haben! example $$if n_prefix~mr~hello mr.~hello ms.$$ - search the field "n_prefix", for "mr", if found, write hello mr., else write hello ms. addressbook de Beispiel: "$$IF n_prefix~Herr~Sehr geehrter~Sehr geehrte$$" - suche in dem Feld "n_prefix" nach "Herr", wenn gefunden, schreibe "Sehr geehrter", wenn nicht gefunden schreibe "Sehr geehrte" existing links addressbook de Bestehende Verknüpfungen export addressbook de Export @@ -362,7 +364,7 @@ updated addressbook de Aktualisiert upload or delete the photo addressbook de Foto hochladen oder löschen url to link telephone numbers to (use %1 = number to call, %u = account name, %t = account phone) admin de URL mit denen Telefonnummern verlinkt werden sollen (verwenden Sie %1 = anzurufende Nummer, %u = Benutzernamen, %t = Telefon des Benutzers) use an extra category tab? addressbook de Separaten Reiter für Kategorien verwenden? -use an extra tab for private custom fields? admin de Soll ein extra Tab für private Benutzerdefinierte Felder benutzt werden? +use an extra tab for private custom fields? admin de Separaten Reiter für private benutzerdefinierte Felder verwenden? use country list addressbook de Länderliste benutzen use setup for a full account-migration admin de für eine komplette Benutzer Migration setup verwenden used for links and for the own sorting of the list addressbook de wird für Verküpfungen und die eigene Sortierung der Liste benützt diff --git a/addressbook/setup/egw_en.lang b/addressbook/setup/egw_en.lang index 050dd83cb4..e1be0085b9 100644 --- a/addressbook/setup/egw_en.lang +++ b/addressbook/setup/egw_en.lang @@ -106,6 +106,7 @@ contacts to ldap, account contact-data to sql admin en contacts to LDAP, account contains addressbook en contains copied by %1, from record #%2. addressbook en Copied by %1, from record #%2. copy a contact and edit the copy addressbook en Copy a contact and edit the copy +copy your changes to the clipboard, %1reload the entry%2 and merge them. addressbook en Copy your changes to the clipboard, %1reload the entry%2 and merge them. country common en Country create new links addressbook en Create new links created addressbook en Created @@ -158,6 +159,7 @@ end addressbook en End enter the path to the exported file here addressbook en Enter the path to the exported file here error deleting the contact !!! addressbook en Error deleting the contact !!! error saving the contact !!! addressbook en Error saving the contact !!! +error: the entry has been updated since you opened it for editing! addressbook en Error: the entry has been updated since you opened it for editing! example $$if n_prefix~mr~hello mr.~hello ms.$$ - search the field "n_prefix", for "mr", if found, write hello mr., else write hello ms. addressbook en Example $$IF n_prefix~Mr~Hello Mr.~Hello Ms.$$ - search the field "n_prefix", for "Mr", if found, write Hello Mr., else write Hello Ms. existing links addressbook en Existing links export addressbook en export diff --git a/addressbook/setup/etemplates.inc.php b/addressbook/setup/etemplates.inc.php index 95916fbb80..09134ed171 100755 --- a/addressbook/setup/etemplates.inc.php +++ b/addressbook/setup/etemplates.inc.php @@ -2,7 +2,7 @@ /** * eGroupWare - eTemplates for Application addressbook * http://www.egroupware.org - * generated by soetemplate::dump4setup() 2008-04-23 10:45 + * generated by soetemplate::dump4setup() 2008-04-25 21:36 * * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License * @package addressbook @@ -42,7 +42,7 @@ $templ_data[] = array('name' => 'addressbook.edit','template' => '','lang' => '' $templ_data[] = array('name' => 'addressbook.edit','template' => '','lang' => '','group' => '0','version' => '1.5.002','data' => 'a:1:{i:0;a:6:{s:4:"type";s:4:"grid";s:4:"data";a:5:{i:0;a:5:{s:1:"A";s:3:"450";s:2:"h1";s:6:",!@msg";s:2:"c3";s:4:",top";s:1:"B";s:3:"350";s:2:"h4";s:13:",@hidebuttons";}i:1;a:2:{s:1:"A";a:4:{s:4:"type";s:5:"label";s:4:"span";s:13:"all,redItalic";s:4:"name";s:3:"msg";s:7:"no_lang";s:1:"1";}s:1:"B";a:1:{s:4:"type";s:5:"label";}}i:2;a:2:{s:1:"A";a:9:{s:4:"type";s:6:"select";s:4:"data";a:2:{i:0;a:2:{s:1:"A";s:11:",!@org_name";s:1:"B";s:11:",!@org_name";}i:1;a:3:{s:1:"A";a:4:{s:4:"type";s:4:"text";s:4:"name";s:8:"org_name";s:8:"readonly";s:1:"1";s:7:"no_lang";s:1:"1";}s:1:"B";a:2:{s:4:"type";s:5:"label";s:5:"label";s:1:":";}s:1:"C";a:4:{s:4:"type";s:4:"text";s:4:"name";s:4:"n_fn";s:7:"no_lang";s:1:"1";s:8:"readonly";s:1:"1";}}}s:4:"rows";i:1;s:4:"cols";i:3;s:4:"span";s:7:",fileas";s:4:"name";s:11:"fileas_type";s:7:"no_lang";s:1:"1";s:4:"blur";s:4:"Name";s:4:"help";s:11:"own sorting";}s:1:"B";a:6:{s:4:"type";s:4:"grid";s:5:"align";s:5:"right";s:4:"data";a:2:{i:0;a:1:{s:2:"h1";s:8:",@no_tid";}i:1;a:2:{s:1:"A";a:6:{s:4:"type";s:6:"select";s:7:"no_lang";s:1:"1";s:4:"name";s:3:"tid";s:8:"onchange";i:1;s:5:"label";s:4:"Type";s:4:"span";s:9:",leftPad5";}s:1:"B";a:7:{s:4:"type";s:4:"html";s:4:"span";s:6:",space";s:6:"needed";s:1:"1";s:5:"label";s:1:" ";s:7:"no_lang";s:1:"1";s:4:"name";s:7:"typegfx";s:8:"readonly";s:1:"1";}}}s:4:"rows";i:1;s:4:"cols";i:2;s:7:"options";a:0:{}}}i:3;a:2:{s:1:"A";a:4:{s:4:"type";s:3:"tab";s:5:"label";s:60:"General|Categories|Private|Details|Links|Extra|Extra private";s:4:"name";s:53:"general|cats|home|details|links|custom|custom_private";s:4:"help";s:117:"Name, Address|Categories|Home address, Birthday, ...|Categories, Notes, ...|Links|Custom fields|Private custom fields";}s:1:"B";a:5:{s:4:"type";s:4:"vbox";s:4:"size";s:1:"3";i:1;a:2:{s:4:"type";s:8:"template";s:4:"name";s:22:"addressbook.editphones";}i:2;a:5:{s:4:"type";s:8:"groupbox";s:4:"size";s:1:"1";s:5:"label";s:13:"Phone Numbers";i:1;a:4:{s:4:"type";s:4:"grid";s:4:"data";a:6:{i:0;a:2:{s:1:"B";s:3:"120";s:1:"A";s:2:"20";}i:1;a:4:{s:1:"A";a:2:{s:4:"type";s:5:"image";s:4:"name";s:5:"phone";}s:1:"B";a:3:{s:4:"type";s:5:"label";s:5:"label";s:8:"business";s:4:"size";s:11:",,,tel_work";}s:1:"C";a:4:{s:4:"type";s:4:"text";s:4:"name";s:8:"tel_work";s:4:"size";s:5:"24,40";s:4:"span";s:11:",telNumbers";}s:1:"D";a:4:{s:4:"type";s:5:"radio";s:4:"size";s:17:"tel_work,♥";s:4:"name";s:10:"tel_prefer";s:4:"help";s:46:"select phone number as prefered way of contact";}}i:2;a:4:{s:1:"A";a:1:{s:4:"type";s:5:"label";}s:1:"B";a:3:{s:4:"type";s:5:"label";s:5:"label";s:12:"mobile phone";s:4:"size";s:11:",,,tel_cell";}s:1:"C";a:4:{s:4:"type";s:4:"text";s:4:"name";s:8:"tel_cell";s:4:"size";s:5:"24,40";s:4:"span";s:11:",telNumbers";}s:1:"D";a:4:{s:4:"type";s:5:"radio";s:4:"size";s:17:"tel_cell,♥";s:4:"name";s:10:"tel_prefer";s:4:"help";s:46:"select phone number as prefered way of contact";}}i:3;a:4:{s:1:"A";a:1:{s:4:"type";s:5:"label";}s:1:"B";a:3:{s:4:"type";s:5:"label";s:5:"label";s:7:"Private";s:4:"size";s:11:",,,tel_home";}s:1:"C";a:4:{s:4:"type";s:4:"text";s:4:"name";s:8:"tel_home";s:4:"size";s:5:"24,40";s:4:"span";s:11:",telNumbers";}s:1:"D";a:4:{s:4:"type";s:5:"radio";s:4:"size";s:17:"tel_home,♥";s:4:"name";s:10:"tel_prefer";s:4:"help";s:46:"select phone number as prefered way of contact";}}i:4;a:4:{s:1:"A";a:1:{s:4:"type";s:5:"label";}s:1:"B";a:2:{s:4:"type";s:5:"label";s:5:"label";s:3:"Fax";}s:1:"C";a:4:{s:4:"type";s:4:"text";s:4:"name";s:7:"tel_fax";s:4:"size";s:5:"24,40";s:4:"span";s:11:",telNumbers";}s:1:"D";a:4:{s:4:"type";s:5:"radio";s:4:"size";s:16:"tel_fax,♥";s:4:"name";s:10:"tel_prefer";s:4:"help";s:46:"select phone number as prefered way of contact";}}i:5;a:4:{s:1:"A";a:1:{s:4:"type";s:5:"label";}s:1:"B";a:1:{s:4:"type";s:5:"label";}s:1:"C";a:4:{s:4:"type";s:6:"button";s:5:"label";s:8:"More ...";s:7:"onclick";s:120:"set_style_by_class(\'table\',\'editphones\',\'display\',\'inline\'); if (window.showphones) showphones(this.form); return false;";s:9:"accesskey";s:1:"m";}s:1:"D";a:1:{s:4:"type";s:5:"label";}}}s:4:"rows";i:5;s:4:"cols";i:4;}s:4:"span";s:11:",phoneGroup";}i:3;a:5:{s:4:"type";s:8:"groupbox";s:4:"size";s:1:"1";s:5:"label";s:16:"Email & Internet";i:1;a:5:{s:4:"type";s:4:"grid";s:4:"data";a:5:{i:0;a:2:{s:1:"A";s:2:"20";s:1:"B";s:3:"120";}i:1;a:3:{s:1:"A";a:2:{s:4:"type";s:5:"image";s:4:"name";s:8:"internet";}s:1:"B";a:3:{s:4:"type";s:5:"label";s:5:"label";s:3:"url";s:4:"size";s:6:",,,url";}s:1:"C";a:3:{s:4:"type";s:4:"text";s:4:"name";s:3:"url";s:4:"size";s:6:"28,128";}}i:2;a:3:{s:1:"A";a:1:{s:4:"type";s:5:"label";}s:1:"B";a:3:{s:4:"type";s:5:"label";s:4:"size";s:11:",,,url_home";s:5:"label";s:7:"Private";}s:1:"C";a:3:{s:4:"type";s:4:"text";s:4:"name";s:8:"url_home";s:4:"size";s:6:"28,128";}}i:3;a:3:{s:1:"A";a:2:{s:4:"type";s:5:"image";s:4:"name";s:9:"email.png";}s:1:"B";a:3:{s:4:"type";s:5:"label";s:5:"label";s:5:"email";s:4:"size";s:8:",,,email";}s:1:"C";a:3:{s:4:"type";s:4:"text";s:4:"name";s:5:"email";s:4:"size";s:5:"28,64";}}i:4;a:3:{s:1:"A";a:1:{s:4:"type";s:5:"label";}s:1:"B";a:3:{s:4:"type";s:5:"label";s:5:"label";s:7:"Private";s:4:"size";s:13:",,,email_home";}s:1:"C";a:3:{s:4:"type";s:4:"text";s:4:"name";s:10:"email_home";s:4:"size";s:5:"28,64";}}}s:4:"rows";i:4;s:4:"cols";i:3;s:7:"options";a:0:{}}s:4:"span";s:11:",emailGroup";}}}i:4;a:2:{s:1:"A";a:8:{s:4:"type";s:4:"hbox";s:4:"size";s:1:"6";i:1;a:4:{s:4:"type";s:6:"button";s:5:"label";s:4:"Edit";s:4:"name";s:12:"button[edit]";s:7:"onclick";s:185:"window.open(egw::link(\'/index.php\',\'menuaction=addressbook.uicontacts.edit&contact_id=$cont[id]\'),\'_blank\',\'dependent=yes,width=850,height=440,scrollbars=yes,status=yes\'); return false;";}i:2;a:4:{s:4:"type";s:6:"button";s:5:"label";s:4:"Copy";s:4:"name";s:12:"button[copy]";s:7:"onclick";s:194:"window.open(egw::link(\'/index.php\',\'menuaction=addressbook.uicontacts.edit&contact_id=$cont[id]&makecp=1\'),\'_blank\',\'dependent=yes,width=850,height=440,scrollbars=yes,status=yes\'); return false;";}i:3;a:4:{s:4:"type";s:6:"button";s:5:"label";s:5:"vCard";s:4:"name";s:13:"button[vcard]";s:4:"help";s:35:"download this contact as vCard file";}i:4;a:4:{s:4:"type";s:6:"button";s:5:"label";s:4:"Save";s:4:"name";s:12:"button[save]";s:9:"accesskey";s:1:"s";}i:5;a:3:{s:4:"type";s:6:"button";s:5:"label";s:5:"Apply";s:4:"name";s:13:"button[apply]";}i:6;a:4:{s:4:"type";s:6:"button";s:5:"label";s:6:"Cancel";s:4:"name";s:14:"button[cancel]";s:7:"onclick";s:57:"if($cont[view]0) return true; self.close(); return false;";}}s:1:"B";a:6:{s:4:"type";s:6:"button";s:5:"label";s:6:"Delete";s:4:"name";s:14:"button[delete]";s:7:"onclick";s:65:"return confirm(\'Are you shure you want to delete this contact?\');";s:5:"align";s:5:"right";s:8:"tabindex";i:25;}}}s:4:"rows";i:4;s:4:"cols";i:2;s:5:"align";s:6:"center";s:7:"options";a:0:{}}}','size' => '','style' => '','modified' => '1200547119',); -$templ_data[] = array('name' => 'addressbook.edit','template' => '','lang' => '','group' => '0','version' => '1.5.003','data' => 'a:1:{i:0;a:6:{s:4:"type";s:4:"grid";s:4:"data";a:5:{i:0;a:5:{s:1:"A";s:3:"450";s:2:"h1";s:6:",!@msg";s:2:"c3";s:4:",top";s:1:"B";s:3:"350";s:2:"h4";s:13:",@hidebuttons";}i:1;a:2:{s:1:"A";a:4:{s:4:"type";s:5:"label";s:4:"span";s:13:"all,redItalic";s:4:"name";s:3:"msg";s:7:"no_lang";s:1:"1";}s:1:"B";a:1:{s:4:"type";s:5:"label";}}i:2;a:2:{s:1:"A";a:9:{s:4:"type";s:6:"select";s:4:"data";a:2:{i:0;a:2:{s:1:"A";s:11:",!@org_name";s:1:"B";s:11:",!@org_name";}i:1;a:3:{s:1:"A";a:4:{s:4:"type";s:4:"text";s:4:"name";s:8:"org_name";s:8:"readonly";s:1:"1";s:7:"no_lang";s:1:"1";}s:1:"B";a:2:{s:4:"type";s:5:"label";s:5:"label";s:1:":";}s:1:"C";a:4:{s:4:"type";s:4:"text";s:4:"name";s:4:"n_fn";s:7:"no_lang";s:1:"1";s:8:"readonly";s:1:"1";}}}s:4:"rows";i:1;s:4:"cols";i:3;s:4:"span";s:7:",fileas";s:4:"name";s:11:"fileas_type";s:7:"no_lang";s:1:"1";s:4:"blur";s:4:"Name";s:4:"help";s:11:"own sorting";}s:1:"B";a:6:{s:4:"type";s:4:"grid";s:5:"align";s:5:"right";s:4:"data";a:2:{i:0;a:1:{s:2:"h1";s:8:",@no_tid";}i:1;a:2:{s:1:"A";a:6:{s:4:"type";s:6:"select";s:7:"no_lang";s:1:"1";s:4:"name";s:3:"tid";s:8:"onchange";i:1;s:5:"label";s:4:"Type";s:4:"span";s:9:",leftPad5";}s:1:"B";a:7:{s:4:"type";s:4:"html";s:4:"span";s:6:",space";s:6:"needed";s:1:"1";s:5:"label";s:1:" ";s:7:"no_lang";s:1:"1";s:4:"name";s:7:"typegfx";s:8:"readonly";s:1:"1";}}}s:4:"rows";i:1;s:4:"cols";i:2;s:7:"options";a:0:{}}}i:3;a:2:{s:1:"A";a:4:{s:4:"type";s:3:"tab";s:5:"label";s:79:"General|Categories|Private|Details|Links|Distribution lists|Extra|Extra private";s:4:"name";s:71:"general|cats|home|details|links|distribution_list|custom|custom_private";s:4:"help";s:141:"Name, Address|Categories|Home address, Birthday, ...|Categories, Notes, ...|Links|Distribution lists, ...|Custom fields|Private custom fields";}s:1:"B";a:5:{s:4:"type";s:4:"vbox";s:4:"size";s:1:"3";i:1;a:2:{s:4:"type";s:8:"template";s:4:"name";s:22:"addressbook.editphones";}i:2;a:5:{s:4:"type";s:8:"groupbox";s:4:"size";s:1:"1";s:5:"label";s:13:"Phone Numbers";i:1;a:4:{s:4:"type";s:4:"grid";s:4:"data";a:6:{i:0;a:2:{s:1:"B";s:3:"120";s:1:"A";s:2:"20";}i:1;a:4:{s:1:"A";a:2:{s:4:"type";s:5:"image";s:4:"name";s:5:"phone";}s:1:"B";a:3:{s:4:"type";s:5:"label";s:5:"label";s:8:"business";s:4:"size";s:11:",,,tel_work";}s:1:"C";a:4:{s:4:"type";s:4:"text";s:4:"name";s:8:"tel_work";s:4:"size";s:5:"24,40";s:4:"span";s:11:",telNumbers";}s:1:"D";a:4:{s:4:"type";s:5:"radio";s:4:"size";s:17:"tel_work,♥";s:4:"name";s:10:"tel_prefer";s:4:"help";s:46:"select phone number as prefered way of contact";}}i:2;a:4:{s:1:"A";a:1:{s:4:"type";s:5:"label";}s:1:"B";a:3:{s:4:"type";s:5:"label";s:5:"label";s:12:"mobile phone";s:4:"size";s:11:",,,tel_cell";}s:1:"C";a:4:{s:4:"type";s:4:"text";s:4:"name";s:8:"tel_cell";s:4:"size";s:5:"24,40";s:4:"span";s:11:",telNumbers";}s:1:"D";a:4:{s:4:"type";s:5:"radio";s:4:"size";s:17:"tel_cell,♥";s:4:"name";s:10:"tel_prefer";s:4:"help";s:46:"select phone number as prefered way of contact";}}i:3;a:4:{s:1:"A";a:1:{s:4:"type";s:5:"label";}s:1:"B";a:3:{s:4:"type";s:5:"label";s:5:"label";s:7:"Private";s:4:"size";s:11:",,,tel_home";}s:1:"C";a:4:{s:4:"type";s:4:"text";s:4:"name";s:8:"tel_home";s:4:"size";s:5:"24,40";s:4:"span";s:11:",telNumbers";}s:1:"D";a:4:{s:4:"type";s:5:"radio";s:4:"size";s:17:"tel_home,♥";s:4:"name";s:10:"tel_prefer";s:4:"help";s:46:"select phone number as prefered way of contact";}}i:4;a:4:{s:1:"A";a:1:{s:4:"type";s:5:"label";}s:1:"B";a:2:{s:4:"type";s:5:"label";s:5:"label";s:3:"Fax";}s:1:"C";a:4:{s:4:"type";s:4:"text";s:4:"name";s:7:"tel_fax";s:4:"size";s:5:"24,40";s:4:"span";s:11:",telNumbers";}s:1:"D";a:4:{s:4:"type";s:5:"radio";s:4:"size";s:16:"tel_fax,♥";s:4:"name";s:10:"tel_prefer";s:4:"help";s:46:"select phone number as prefered way of contact";}}i:5;a:4:{s:1:"A";a:1:{s:4:"type";s:5:"label";}s:1:"B";a:1:{s:4:"type";s:5:"label";}s:1:"C";a:4:{s:4:"type";s:6:"button";s:5:"label";s:8:"More ...";s:7:"onclick";s:120:"set_style_by_class(\'table\',\'editphones\',\'display\',\'inline\'); if (window.showphones) showphones(this.form); return false;";s:9:"accesskey";s:1:"m";}s:1:"D";a:1:{s:4:"type";s:5:"label";}}}s:4:"rows";i:5;s:4:"cols";i:4;}s:4:"span";s:11:",phoneGroup";}i:3;a:5:{s:4:"type";s:8:"groupbox";s:4:"size";s:1:"1";s:5:"label";s:16:"Email & Internet";i:1;a:5:{s:4:"type";s:4:"grid";s:4:"data";a:5:{i:0;a:2:{s:1:"A";s:2:"20";s:1:"B";s:3:"120";}i:1;a:3:{s:1:"A";a:2:{s:4:"type";s:5:"image";s:4:"name";s:8:"internet";}s:1:"B";a:3:{s:4:"type";s:5:"label";s:5:"label";s:3:"url";s:4:"size";s:6:",,,url";}s:1:"C";a:3:{s:4:"type";s:4:"text";s:4:"name";s:3:"url";s:4:"size";s:6:"28,128";}}i:2;a:3:{s:1:"A";a:1:{s:4:"type";s:5:"label";}s:1:"B";a:3:{s:4:"type";s:5:"label";s:4:"size";s:11:",,,url_home";s:5:"label";s:7:"Private";}s:1:"C";a:3:{s:4:"type";s:4:"text";s:4:"name";s:8:"url_home";s:4:"size";s:6:"28,128";}}i:3;a:3:{s:1:"A";a:2:{s:4:"type";s:5:"image";s:4:"name";s:9:"email.png";}s:1:"B";a:3:{s:4:"type";s:5:"label";s:5:"label";s:5:"email";s:4:"size";s:8:",,,email";}s:1:"C";a:3:{s:4:"type";s:4:"text";s:4:"name";s:5:"email";s:4:"size";s:6:"28,128";}}i:4;a:3:{s:1:"A";a:1:{s:4:"type";s:5:"label";}s:1:"B";a:3:{s:4:"type";s:5:"label";s:5:"label";s:7:"Private";s:4:"size";s:13:",,,email_home";}s:1:"C";a:3:{s:4:"type";s:4:"text";s:4:"name";s:10:"email_home";s:4:"size";s:6:"28,128";}}}s:4:"rows";i:4;s:4:"cols";i:3;s:7:"options";a:0:{}}s:4:"span";s:11:",emailGroup";}}}i:4;a:2:{s:1:"A";a:8:{s:4:"type";s:4:"hbox";s:4:"size";s:1:"6";i:1;a:4:{s:4:"type";s:6:"button";s:5:"label";s:4:"Edit";s:4:"name";s:12:"button[edit]";s:7:"onclick";s:185:"window.open(egw::link(\'/index.php\',\'menuaction=addressbook.uicontacts.edit&contact_id=$cont[id]\'),\'_blank\',\'dependent=yes,width=850,height=440,scrollbars=yes,status=yes\'); return false;";}i:2;a:4:{s:4:"type";s:6:"button";s:5:"label";s:4:"Copy";s:4:"name";s:12:"button[copy]";s:7:"onclick";s:194:"window.open(egw::link(\'/index.php\',\'menuaction=addressbook.uicontacts.edit&contact_id=$cont[id]&makecp=1\'),\'_blank\',\'dependent=yes,width=850,height=440,scrollbars=yes,status=yes\'); return false;";}i:3;a:4:{s:4:"type";s:6:"button";s:5:"label";s:5:"vCard";s:4:"name";s:13:"button[vcard]";s:4:"help";s:35:"download this contact as vCard file";}i:4;a:4:{s:4:"type";s:6:"button";s:5:"label";s:4:"Save";s:4:"name";s:12:"button[save]";s:9:"accesskey";s:1:"s";}i:5;a:3:{s:4:"type";s:6:"button";s:5:"label";s:5:"Apply";s:4:"name";s:13:"button[apply]";}i:6;a:4:{s:4:"type";s:6:"button";s:5:"label";s:6:"Cancel";s:4:"name";s:14:"button[cancel]";s:7:"onclick";s:57:"if($cont[view]0) return true; self.close(); return false;";}}s:1:"B";a:6:{s:4:"type";s:6:"button";s:5:"label";s:6:"Delete";s:4:"name";s:14:"button[delete]";s:7:"onclick";s:65:"return confirm(\'Are you shure you want to delete this contact?\');";s:5:"align";s:5:"right";s:8:"tabindex";i:25;}}}s:4:"rows";i:4;s:4:"cols";i:2;s:5:"align";s:6:"center";s:7:"options";a:0:{}}}','size' => '','style' => '','modified' => '1201775611',); +$templ_data[] = array('name' => 'addressbook.edit','template' => '','lang' => '','group' => '0','version' => '1.5.003','data' => 'a:1:{i:0;a:6:{s:4:"type";s:4:"grid";s:4:"data";a:5:{i:0;a:5:{s:1:"A";s:3:"450";s:2:"h1";s:6:",!@msg";s:2:"c3";s:4:",top";s:1:"B";s:3:"350";s:2:"h4";s:13:",@hidebuttons";}i:1;a:2:{s:1:"A";a:5:{s:4:"type";s:8:"htmlarea";s:4:"span";s:13:"all,redItalic";s:4:"name";s:3:"msg";s:7:"no_lang";s:1:"1";s:8:"readonly";s:1:"1";}s:1:"B";a:1:{s:4:"type";s:5:"label";}}i:2;a:2:{s:1:"A";a:9:{s:4:"type";s:6:"select";s:4:"data";a:2:{i:0;a:2:{s:1:"A";s:11:",!@org_name";s:1:"B";s:11:",!@org_name";}i:1;a:3:{s:1:"A";a:4:{s:4:"type";s:4:"text";s:4:"name";s:8:"org_name";s:8:"readonly";s:1:"1";s:7:"no_lang";s:1:"1";}s:1:"B";a:2:{s:4:"type";s:5:"label";s:5:"label";s:1:":";}s:1:"C";a:4:{s:4:"type";s:4:"text";s:4:"name";s:4:"n_fn";s:7:"no_lang";s:1:"1";s:8:"readonly";s:1:"1";}}}s:4:"rows";i:1;s:4:"cols";i:3;s:4:"span";s:7:",fileas";s:4:"name";s:11:"fileas_type";s:7:"no_lang";s:1:"1";s:4:"blur";s:4:"Name";s:4:"help";s:11:"own sorting";}s:1:"B";a:6:{s:4:"type";s:4:"grid";s:5:"align";s:5:"right";s:4:"data";a:2:{i:0;a:1:{s:2:"h1";s:8:",@no_tid";}i:1;a:2:{s:1:"A";a:6:{s:4:"type";s:6:"select";s:7:"no_lang";s:1:"1";s:4:"name";s:3:"tid";s:8:"onchange";i:1;s:5:"label";s:4:"Type";s:4:"span";s:9:",leftPad5";}s:1:"B";a:7:{s:4:"type";s:4:"html";s:4:"span";s:6:",space";s:6:"needed";s:1:"1";s:5:"label";s:1:" ";s:7:"no_lang";s:1:"1";s:4:"name";s:7:"typegfx";s:8:"readonly";s:1:"1";}}}s:4:"rows";i:1;s:4:"cols";i:2;s:7:"options";a:0:{}}}i:3;a:2:{s:1:"A";a:4:{s:4:"type";s:3:"tab";s:5:"label";s:79:"General|Categories|Private|Details|Links|Distribution lists|Extra|Extra private";s:4:"name";s:71:"general|cats|home|details|links|distribution_list|custom|custom_private";s:4:"help";s:141:"Name, Address|Categories|Home address, Birthday, ...|Categories, Notes, ...|Links|Distribution lists, ...|Custom fields|Private custom fields";}s:1:"B";a:5:{s:4:"type";s:4:"vbox";s:4:"size";s:1:"3";i:1;a:2:{s:4:"type";s:8:"template";s:4:"name";s:22:"addressbook.editphones";}i:2;a:5:{s:4:"type";s:8:"groupbox";s:4:"size";s:1:"1";s:5:"label";s:13:"Phone Numbers";i:1;a:4:{s:4:"type";s:4:"grid";s:4:"data";a:6:{i:0;a:2:{s:1:"B";s:3:"120";s:1:"A";s:2:"20";}i:1;a:4:{s:1:"A";a:2:{s:4:"type";s:5:"image";s:4:"name";s:5:"phone";}s:1:"B";a:3:{s:4:"type";s:5:"label";s:5:"label";s:8:"business";s:4:"size";s:11:",,,tel_work";}s:1:"C";a:4:{s:4:"type";s:4:"text";s:4:"name";s:8:"tel_work";s:4:"size";s:5:"24,40";s:4:"span";s:11:",telNumbers";}s:1:"D";a:4:{s:4:"type";s:5:"radio";s:4:"size";s:17:"tel_work,♥";s:4:"name";s:10:"tel_prefer";s:4:"help";s:46:"select phone number as prefered way of contact";}}i:2;a:4:{s:1:"A";a:1:{s:4:"type";s:5:"label";}s:1:"B";a:3:{s:4:"type";s:5:"label";s:5:"label";s:12:"mobile phone";s:4:"size";s:11:",,,tel_cell";}s:1:"C";a:4:{s:4:"type";s:4:"text";s:4:"name";s:8:"tel_cell";s:4:"size";s:5:"24,40";s:4:"span";s:11:",telNumbers";}s:1:"D";a:4:{s:4:"type";s:5:"radio";s:4:"size";s:17:"tel_cell,♥";s:4:"name";s:10:"tel_prefer";s:4:"help";s:46:"select phone number as prefered way of contact";}}i:3;a:4:{s:1:"A";a:1:{s:4:"type";s:5:"label";}s:1:"B";a:3:{s:4:"type";s:5:"label";s:5:"label";s:7:"Private";s:4:"size";s:11:",,,tel_home";}s:1:"C";a:4:{s:4:"type";s:4:"text";s:4:"name";s:8:"tel_home";s:4:"size";s:5:"24,40";s:4:"span";s:11:",telNumbers";}s:1:"D";a:4:{s:4:"type";s:5:"radio";s:4:"size";s:17:"tel_home,♥";s:4:"name";s:10:"tel_prefer";s:4:"help";s:46:"select phone number as prefered way of contact";}}i:4;a:4:{s:1:"A";a:1:{s:4:"type";s:5:"label";}s:1:"B";a:2:{s:4:"type";s:5:"label";s:5:"label";s:3:"Fax";}s:1:"C";a:4:{s:4:"type";s:4:"text";s:4:"name";s:7:"tel_fax";s:4:"size";s:5:"24,40";s:4:"span";s:11:",telNumbers";}s:1:"D";a:4:{s:4:"type";s:5:"radio";s:4:"size";s:16:"tel_fax,♥";s:4:"name";s:10:"tel_prefer";s:4:"help";s:46:"select phone number as prefered way of contact";}}i:5;a:4:{s:1:"A";a:1:{s:4:"type";s:5:"label";}s:1:"B";a:1:{s:4:"type";s:5:"label";}s:1:"C";a:4:{s:4:"type";s:6:"button";s:5:"label";s:8:"More ...";s:7:"onclick";s:120:"set_style_by_class(\'table\',\'editphones\',\'display\',\'inline\'); if (window.showphones) showphones(this.form); return false;";s:9:"accesskey";s:1:"m";}s:1:"D";a:1:{s:4:"type";s:5:"label";}}}s:4:"rows";i:5;s:4:"cols";i:4;}s:4:"span";s:11:",phoneGroup";}i:3;a:5:{s:4:"type";s:8:"groupbox";s:4:"size";s:1:"1";s:5:"label";s:16:"Email & Internet";i:1;a:5:{s:4:"type";s:4:"grid";s:4:"data";a:5:{i:0;a:2:{s:1:"A";s:2:"20";s:1:"B";s:3:"120";}i:1;a:3:{s:1:"A";a:2:{s:4:"type";s:5:"image";s:4:"name";s:8:"internet";}s:1:"B";a:3:{s:4:"type";s:5:"label";s:5:"label";s:3:"url";s:4:"size";s:6:",,,url";}s:1:"C";a:3:{s:4:"type";s:4:"text";s:4:"name";s:3:"url";s:4:"size";s:6:"28,128";}}i:2;a:3:{s:1:"A";a:1:{s:4:"type";s:5:"label";}s:1:"B";a:3:{s:4:"type";s:5:"label";s:4:"size";s:11:",,,url_home";s:5:"label";s:7:"Private";}s:1:"C";a:3:{s:4:"type";s:4:"text";s:4:"name";s:8:"url_home";s:4:"size";s:6:"28,128";}}i:3;a:3:{s:1:"A";a:2:{s:4:"type";s:5:"image";s:4:"name";s:9:"email.png";}s:1:"B";a:3:{s:4:"type";s:5:"label";s:5:"label";s:5:"email";s:4:"size";s:8:",,,email";}s:1:"C";a:3:{s:4:"type";s:4:"text";s:4:"name";s:5:"email";s:4:"size";s:6:"28,128";}}i:4;a:3:{s:1:"A";a:1:{s:4:"type";s:5:"label";}s:1:"B";a:3:{s:4:"type";s:5:"label";s:5:"label";s:7:"Private";s:4:"size";s:13:",,,email_home";}s:1:"C";a:3:{s:4:"type";s:4:"text";s:4:"name";s:10:"email_home";s:4:"size";s:6:"28,128";}}}s:4:"rows";i:4;s:4:"cols";i:3;s:7:"options";a:0:{}}s:4:"span";s:11:",emailGroup";}}}i:4;a:2:{s:1:"A";a:8:{s:4:"type";s:4:"hbox";s:4:"size";s:1:"6";i:1;a:4:{s:4:"type";s:6:"button";s:5:"label";s:4:"Edit";s:4:"name";s:12:"button[edit]";s:7:"onclick";s:185:"window.open(egw::link(\'/index.php\',\'menuaction=addressbook.uicontacts.edit&contact_id=$cont[id]\'),\'_blank\',\'dependent=yes,width=850,height=440,scrollbars=yes,status=yes\'); return false;";}i:2;a:4:{s:4:"type";s:6:"button";s:5:"label";s:4:"Copy";s:4:"name";s:12:"button[copy]";s:7:"onclick";s:194:"window.open(egw::link(\'/index.php\',\'menuaction=addressbook.uicontacts.edit&contact_id=$cont[id]&makecp=1\'),\'_blank\',\'dependent=yes,width=850,height=440,scrollbars=yes,status=yes\'); return false;";}i:3;a:4:{s:4:"type";s:6:"button";s:5:"label";s:5:"vCard";s:4:"name";s:13:"button[vcard]";s:4:"help";s:35:"download this contact as vCard file";}i:4;a:4:{s:4:"type";s:6:"button";s:5:"label";s:4:"Save";s:4:"name";s:12:"button[save]";s:9:"accesskey";s:1:"s";}i:5;a:3:{s:4:"type";s:6:"button";s:5:"label";s:5:"Apply";s:4:"name";s:13:"button[apply]";}i:6;a:4:{s:4:"type";s:6:"button";s:5:"label";s:6:"Cancel";s:4:"name";s:14:"button[cancel]";s:7:"onclick";s:57:"if($cont[view]0) return true; self.close(); return false;";}}s:1:"B";a:6:{s:4:"type";s:6:"button";s:5:"label";s:6:"Delete";s:4:"name";s:14:"button[delete]";s:7:"onclick";s:65:"return confirm(\'Are you shure you want to delete this contact?\');";s:5:"align";s:5:"right";s:8:"tabindex";i:25;}}}s:4:"rows";i:4;s:4:"cols";i:2;s:5:"align";s:6:"center";s:7:"options";a:0:{}}}','size' => '','style' => '','modified' => '1201775611',); $templ_data[] = array('name' => 'addressbook.edit.access','template' => '','lang' => '','group' => '0','version' => '','data' => 'a:1:{i:0;a:6:{s:4:"type";s:4:"grid";s:4:"data";a:3:{i:0;a:1:{s:2:"c2";s:4:",top";}i:1;a:2:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:5:"label";s:20:"Publish into groups:";}s:1:"B";a:3:{s:4:"type";s:6:"manual";s:7:"onclick";s:13:"return false;";s:4:"name";s:30:"ManualAddressbookPublishgroups";}}i:2;a:2:{s:1:"A";a:5:{s:4:"type";s:6:"select";s:4:"size";s:1:"5";s:4:"name";s:16:"published_groups";s:4:"span";s:3:"all";s:7:"no_lang";s:1:"1";}s:1:"B";a:1:{s:4:"type";s:5:"label";}}}s:4:"rows";i:2;s:4:"cols";i:2;s:4:"size";s:4:",250";s:7:"options";a:1:{i:1;s:3:"250";}}}','size' => ',250','style' => '','modified' => '1140005589',); diff --git a/addressbook/templates/default/edit.xet b/addressbook/templates/default/edit.xet index e136a38126..d4d71e246c 100644 --- a/addressbook/templates/default/edit.xet +++ b/addressbook/templates/default/edit.xet @@ -53,7 +53,7 @@ -