first version / step to the new 1.4 addressbook:
- User accounts are an own addressbook now - every user and group (can) have an own addressbook - for groups the accessrights no longer depend on the creator - new acl for adding into an addressbook - all addressbooks can be displayed together (eg. accounts mixed with personal and group AB's) - some useful new fields (photo, private cellphone, ...) and some obscure ones have been removed - db update puts all contacts in the owners personal addressbook (further manual migration tools will follow), thought the UI already allows to mass-move them into a group-addressbook - group addressbooks in SQL are created by making a group-grant for addressbook (like filemanger) - Warning: all import/export/xmlrpc/syncml stuff and other apps accessing the addressbook is broken until the contacts class in the API gets fixed! - it depends on further updates of etemplate, phpgwapi, admin! ==> it's pretty cool (specialy the foto's), but NOT ready for a production server !!!
@ -3,7 +3,8 @@
|
||||
* eGroupWare - Adressbook - General business object *
|
||||
* http://www.egroupware.org *
|
||||
* Written and (c) 2005 by Cornelius_weiss <egw@von-und-zu-weiss.de> *
|
||||
* -------------------------------------------- *
|
||||
* and Ralf Becker <RalfBecker-AT-outdoor-training.de> *
|
||||
* ------------------------------------------------------------------------ *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU General Public License as published by the *
|
||||
* Free Software Foundation; either version 2 of the License, or (at your *
|
||||
@ -15,25 +16,16 @@
|
||||
require_once(EGW_INCLUDE_ROOT.'/addressbook/inc/class.socontacts.inc.php');
|
||||
|
||||
/**
|
||||
* General business object of the adressbook
|
||||
*
|
||||
* @package addressbook
|
||||
* @author Cornelius Weiss <egw@von-und-zu-weiss.de>
|
||||
* @copyright (c) 2005 by Cornelius Weiss <egw@von-und-zu-weiss.de>
|
||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||
*/
|
||||
* General business object of the adressbook
|
||||
*
|
||||
* @package addressbook
|
||||
* @author Cornelius Weiss <egw@von-und-zu-weiss.de>
|
||||
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||
* @copyright (c) 2005/6 by Cornelius Weiss <egw@von-und-zu-weiss.de> and Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||
*/
|
||||
class bocontacts extends socontacts
|
||||
{
|
||||
/**
|
||||
* @var $grants array with grants
|
||||
*/
|
||||
var $grants;
|
||||
|
||||
/**
|
||||
* @var $user userid of current user
|
||||
*/
|
||||
var $user;
|
||||
|
||||
/**
|
||||
* @var int $tz_offset_s offset in secconds between user and server-time,
|
||||
* it need to be add to a server-time to get the user-time or substracted from a user-time to get the server-time
|
||||
@ -48,13 +40,33 @@ class bocontacts extends socontacts
|
||||
/**
|
||||
* @var array $timestamps timestamps
|
||||
*/
|
||||
var $timestamps = array('last_mod');
|
||||
var $timestamps = array('modified','created');
|
||||
|
||||
/**
|
||||
* @var array $fileas_types
|
||||
*/
|
||||
var $fileas_types = array(
|
||||
'org_name: n_family, n_given',
|
||||
'org_name: n_family, n_prefix',
|
||||
'org_name: n_given n_family',
|
||||
'org_name: n_fn',
|
||||
'n_family, n_given: org_name',
|
||||
'n_family, n_prefix: org_name',
|
||||
'n_given n_family: org_name',
|
||||
'n_prefix n_family: org_name',
|
||||
'n_fn: org_name',
|
||||
'org_name',
|
||||
'n_given n_family',
|
||||
'n_prefix n_family',
|
||||
'n_family, n_given',
|
||||
'n_family, n_prefix',
|
||||
'n_fn',
|
||||
);
|
||||
|
||||
function bocontacts($contact_app='addressbook')
|
||||
{
|
||||
$this->socontacts($contact_app);
|
||||
$this->grants = $GLOBALS['egw']->acl->get_grants($contact_app);
|
||||
$this->user = $GLOBALS['egw_info']['user']['account_id'];
|
||||
|
||||
$this->tz_offset_s = 3600 * $GLOBALS['egw_info']['user']['preferences']['common']['tz_offset'];
|
||||
$this->now_su = time() + $this->tz_offset_s;
|
||||
|
||||
@ -72,7 +84,92 @@ class bocontacts extends socontacts
|
||||
}*/
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* calculate the file_as string from the contact and the file_as type
|
||||
*
|
||||
* @param array $contact
|
||||
* @param string $type=null file_as type, default null to read it from the contact, unknown/not set type default to the first one
|
||||
* @return string
|
||||
*/
|
||||
function fileas($contact,$type=null)
|
||||
{
|
||||
if (is_null($type)) $type = $contact['fileas_type'];
|
||||
if (!$type || !in_array($type,$this->fileas_types)) $type = $this->fileas_types[0];
|
||||
|
||||
if (strstr($type,'n_fn')) $contact['n_fn'] = $this->fullname($contact);
|
||||
|
||||
return str_replace(array_keys($contact),array_values($contact),$type);
|
||||
}
|
||||
|
||||
/**
|
||||
* determine the file_as type from the file_as string and the contact
|
||||
*
|
||||
* @param array $contact
|
||||
* @param string $type=null file_as type, default null to read it from the contact, unknown/not set type default to the first one
|
||||
* @return string
|
||||
*/
|
||||
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)
|
||||
{
|
||||
if ($this->fileas($contact,$type) == $file_as)
|
||||
{
|
||||
return $type;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $this->fileas_types[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* get selectbox options for the fileas types with translated labels, or real content
|
||||
*
|
||||
* @param array $contact=null real content to use, default none
|
||||
* @return array with options: fileas type => label pairs
|
||||
*/
|
||||
function fileas_options($contact=null)
|
||||
{
|
||||
$labels = array(
|
||||
'n_prefix' => lang('prefix'),
|
||||
'n_given' => lang('first name'),
|
||||
'n_middle' => lang('middle name'),
|
||||
'n_family' => lang('last name'),
|
||||
'n_suffix' => lang('suffix'),
|
||||
'n_fn' => lang('full name'),
|
||||
'org_name' => lang('company name'),
|
||||
);
|
||||
foreach($labels as $name => $label)
|
||||
{
|
||||
if ($contact[$name]) $labels[$name] = $contact[$name];
|
||||
}
|
||||
foreach($this->fileas_types as $fileas_type)
|
||||
{
|
||||
$options[$fileas_type] = $this->fileas($labels,$fileas_type);
|
||||
}
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* get full name from the name-parts
|
||||
*
|
||||
* @param array $contact
|
||||
* @return string full name
|
||||
*/
|
||||
function fullname($contact)
|
||||
{
|
||||
$parts = array();
|
||||
foreach(array('n_prefix','n_given','n_middle','n_family','n_suffix') as $n)
|
||||
{
|
||||
if ($contact[$n]) $parts[] = $contact[$n];
|
||||
}
|
||||
return implode(' ',$parts);
|
||||
}
|
||||
|
||||
/**
|
||||
* changes the data from the db-format to your work-format
|
||||
*
|
||||
@ -91,8 +188,25 @@ class bocontacts extends socontacts
|
||||
$data[$name] += $this->tz_offset_s;
|
||||
}
|
||||
}
|
||||
$data['photo'] = $this->photo_src($data['id'],$data['jpegphoto']);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* src for photo: returns array with linkparams if jpeg exists or the $default image-name if not
|
||||
* @param int $id contact_id
|
||||
* @param boolean $jpeg=false jpeg exists or not
|
||||
* @param string $default='' image-name to use if !$jpeg, eg. 'template'
|
||||
* @return string/array
|
||||
*/
|
||||
function photo_src($id,$jpeg,$default='')
|
||||
{
|
||||
return $jpeg ? array(
|
||||
'menuaction' => 'addressbook.uicontacts.photo',
|
||||
'contact_id' => $id,
|
||||
) : $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* changes the data from your work-format to the db-format
|
||||
@ -118,114 +232,78 @@ class bocontacts extends socontacts
|
||||
/**
|
||||
* deletes contact in db
|
||||
*
|
||||
* @param mixed &contact contact array from etemplate::exec or id
|
||||
* @return bool false if all went right
|
||||
* @param mixed &$contact contact array with key id or (array of) id(s)
|
||||
* @return boolean true on success or false on failiure
|
||||
*/
|
||||
function delete(&$contact)
|
||||
function delete($contact)
|
||||
{
|
||||
// multiple delete from advanced search
|
||||
if(isset($contact[0]))
|
||||
if (is_array($contact) && isset($contact['id']))
|
||||
{
|
||||
foreach($contact as $single)
|
||||
{
|
||||
if($this->check_perms(EGW_ACL_DELETE,$single['id']))
|
||||
{
|
||||
if(parent::delete($single))
|
||||
{
|
||||
$msg .= lang('Something went wrong by deleting %1', $single['n_given'].$single['n_family']);
|
||||
}
|
||||
else
|
||||
{
|
||||
$GLOBALS['egw']->contenthistory->updateTimeStamp('contacts', $single['id'], 'delete', time());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$msg .= lang('You are not permitted to delete contact %1', $single['n_given'].$single['n_family']);
|
||||
}
|
||||
}
|
||||
return $msg;
|
||||
$contact = array($contact);
|
||||
}
|
||||
if((isset($contact['id']) && !$this->check_perms(EGW_ACL_DELETE,$contact['id'])) ||
|
||||
(is_numeric($contact) && !$this->check_perms(EGW_ACL_DELETE,$contact)))
|
||||
elseif (!is_array($contact))
|
||||
{
|
||||
$contact['msg'] = lang('You are not permittet to delete this contact');
|
||||
return 1;
|
||||
$contact = array($contact);
|
||||
}
|
||||
if(is_numeric($contact)) $contact = array('id' => $contact);
|
||||
if(parent::delete($contact))
|
||||
foreach($contact as $c)
|
||||
{
|
||||
$contact['msg'] = lang('Something went wrong by deleting this contact');
|
||||
return 1;
|
||||
}
|
||||
$GLOBALS['egw']->contenthistory->updateTimeStamp('contacts', $contact['id'], 'delete', time());
|
||||
$id = is_array($c) ? $c['id'] : $c;
|
||||
|
||||
return;
|
||||
if ($this->check_perms(EGW_ACL_DELETE,$c) && parent::delete($id))
|
||||
{
|
||||
$GLOBALS['egw']->contenthistory->updateTimeStamp('contacts', $id, 'delete', time());
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* saves contact to db
|
||||
*
|
||||
* @param array &contact contact array from etemplate::exec
|
||||
* @return array $contact
|
||||
* @return boolean true on success, false on failure, an error-message is in $contact['msg']
|
||||
* TODO make fullname format choosable at best with selectbox and javascript in edit dialoge
|
||||
*/
|
||||
function save(&$contact)
|
||||
{
|
||||
// stores if we add or update a entry
|
||||
$isUpdate = true;
|
||||
|
||||
if($contact['id'] && !$this->check_perms(EGW_ACL_EDIT,$contact['id']))
|
||||
if (!($isUpdate = $contact['id']))
|
||||
{
|
||||
if (!isset($contact['owner'])) $contact['owner'] = $this->user; // write to users personal addressbook
|
||||
$contact['creator'] = $this->user;
|
||||
$contact['created'] = $this->now_su;
|
||||
}
|
||||
if($contact['id'] && !$this->check_perms(EGW_ACL_EDIT,$contact))
|
||||
{
|
||||
$contact['msg'] = lang('You are not permittet to edit this contact');
|
||||
return $contact;
|
||||
return false;
|
||||
}
|
||||
|
||||
// new contact
|
||||
if($contact['id'] == 0)
|
||||
{
|
||||
$contact['owner'] = $this->user;
|
||||
$isUpdate = false;
|
||||
}
|
||||
|
||||
// convert categories
|
||||
$contact['cat_id'] = $contact['cat_id'] ? implode(',',$contact['cat_id']) : '';
|
||||
$contact['cat_id'] = is_array($contact['cat_id']) ? implode(',',$contact['cat_id']) : $contact['cat_id'];
|
||||
// last modified
|
||||
$contact['last_mod'] = $this->now_su;
|
||||
// only owner can set access status
|
||||
$contact['access'] = $contact['owner'] == $this->user ? ($contact['private'] ? 'private': 'public') : $contact['access'];
|
||||
// create fullname
|
||||
$contact['fn'] = $contact['prefix'].
|
||||
($contact['n_given'] ? ' '.$contact['n_given'] : '').
|
||||
($contact['n_middle'] ? ' '.$contact['n_middle'] : '').
|
||||
($contact['n_family'] ? ' '.$contact['n_family'] : '').
|
||||
($contact['n_suffix'] ? ' '.$contact['n_suffix'] : '');
|
||||
// for some bad historical reasons we mainfileds saved in cf :-(((
|
||||
$contact['#ophone'] = $contact['ophone']; unset($contact['ophone']);
|
||||
$contact['#address2'] = $contact['address2']; unset($contact['address2']);
|
||||
$contact['#address3'] = $contact['address3']; unset($contact['address3']);
|
||||
|
||||
$contact['modifier'] = $this->user;
|
||||
$contact['modified'] = $this->now_su;
|
||||
// set access if not set or bogus
|
||||
if ($contact['access'] != 'private') $contact['access'] = 'public';
|
||||
// set full name and fileas from the content
|
||||
$contact['n_fn'] = $this->fullname($contact);
|
||||
$contact['n_fileas'] = $this->fileas($contact);
|
||||
|
||||
$error_nr = parent::save($contact);
|
||||
|
||||
if(!$error_nr)
|
||||
{
|
||||
if($isUpdate) {
|
||||
$GLOBALS['egw']->contenthistory->updateTimeStamp('contacts', $contact['id'], 'modify', time());
|
||||
} else {
|
||||
$GLOBALS['egw']->contenthistory->updateTimeStamp('contacts', $contact['id'], 'add', time());
|
||||
}
|
||||
$GLOBALS['egw']->contenthistory->updateTimeStamp('contacts', $contact['id'],$isUpdate ? 'modify' : 'add', time());
|
||||
}
|
||||
|
||||
// for some bad historical reasons we mainfileds saved in cf :-(((
|
||||
$contact['ophone'] = $contact['#ophone']; unset($contact['#ophone']);
|
||||
$contact['address2'] = $contact['#address2']; unset($contact['#address2']);
|
||||
$contact['address3'] = $contact['#address3']; unset($contact['#address3']);
|
||||
|
||||
$contact['msg'] = $error_nr ?
|
||||
lang('Something went wrong by saving this contact. Errorcode %1',$error_nr) :
|
||||
lang('Contact saved');
|
||||
|
||||
return $contact;
|
||||
return !$error_nr;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -234,80 +312,125 @@ class bocontacts extends socontacts
|
||||
* @param array $keys array with keys in form internalName => value, may be a scalar value if only one key
|
||||
* @param string/array $extra_cols string or array of strings to be added to the SELECT, eg. "count(*) as num"
|
||||
* @param string $join='' sql to do a join, added as is after the table-name, eg. ", table2 WHERE x=y" or
|
||||
* @return array with data or errormessage
|
||||
* @return array/boolean contact data or false on error
|
||||
*/
|
||||
function read($keys,$extra_cols='',$join='')
|
||||
{
|
||||
$data = parent::read($keys,$extra_cols,$join);
|
||||
if (!$data)
|
||||
if (!$data || !$this->check_perms(EGW_ACL_READ,$data))
|
||||
{
|
||||
return lang('something went wrong by reading this contact');
|
||||
return false;
|
||||
}
|
||||
if(!$this->check_perms(EGW_ACL_READ,$data))
|
||||
{
|
||||
return lang('you are not permittet to view this contact');
|
||||
}
|
||||
|
||||
// convert access into private for historical reasons
|
||||
$data['private'] = $data['access'] == 'private' ? 1 : 0;
|
||||
// for some bad historical reasons we mainfileds saved in cf :-(((
|
||||
$data['ophone'] = $data['#ophone']; unset($data['#ophone']);
|
||||
$data['address2'] = $data['#address2']; unset($data['#address2']);
|
||||
$data['address3'] = $data['#address3']; unset($data['#address3']);
|
||||
// determine the file-as type
|
||||
$data['fileas_type'] = $this->fileas_type($data);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* searches contacts for rows matching searchcriteria
|
||||
*
|
||||
* @param array/string $criteria array of key and data cols, OR a SQL query (content for WHERE), fully quoted (!)
|
||||
* @param boolean/string $only_keys=true True returns only keys, False returns all cols. comma seperated list of keys 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"
|
||||
* @param string $wildcard='' appended befor and after each criteria
|
||||
* @param boolean $empty=false False=empty criteria are ignored in query, True=empty have to be empty in row
|
||||
* @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)
|
||||
* @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
|
||||
* "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 array of matching rows (the row is an array of the cols) or False
|
||||
*/
|
||||
function search($criteria,$only_keys=True,$order_by='',$extra_cols='',$wildcard='',$empty=False,$op='AND',$start=false,$filter=null,$join='',$need_full_no_count=false)
|
||||
{
|
||||
$filter = array(
|
||||
'owner' => array_keys($this->grants),
|
||||
);
|
||||
return parent::search($criteria,$only_keys,$order_by,$extra_cols,$wildcard,$empty,$op,$start,$filter,$join,$need_full_no_count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the current user has the necessary ACL rights
|
||||
*
|
||||
* If the access of a contact is set to private, one need a private grant for a personal addressbook
|
||||
* or the group membership for a group-addressbook
|
||||
*
|
||||
* @param int $needed necessary ACL right: EGW_ACL_{READ|EDIT|DELETE}
|
||||
* @param mixed $contact contact as array or the contact-id
|
||||
* @return boolean true permission granted or false for permission denied
|
||||
*/
|
||||
function check_perms($needed,&$contact)
|
||||
{
|
||||
if (is_array($contact))
|
||||
if (!is_array($contact) && !($contact = parent::read($contact)))
|
||||
{
|
||||
$owner = $contact['owner'];
|
||||
$access = $contact['access'];
|
||||
return false;
|
||||
}
|
||||
elseif (is_numeric($contact))
|
||||
{
|
||||
$read_contact = parent::read($contact);
|
||||
$owner = $read_contact['owner'];
|
||||
$access = $read_contact['access'];
|
||||
}
|
||||
if($owner == $this->user)
|
||||
$owner = $contact['owner'];
|
||||
|
||||
if (!$owner && $needed == EGW_ACL_EDIT && $contact['account_id'] == $this->user)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
$access = $access ? $access : 'public';
|
||||
return $access == 'private' ? false : $this->grants[$owner] & $needed;
|
||||
return ($this->grants[$owner] & $needed) &&
|
||||
(!$contact['private'] || ($this->grants[$owner] & EGW_ACL_PRIVATE) || in_array($owner,$this->memberships));
|
||||
}
|
||||
|
||||
/**
|
||||
* get title for a contact identified by $contact
|
||||
*
|
||||
* Is called as hook to participate in the linking
|
||||
*
|
||||
* @param int/string/array $contact int/string id or array with contact
|
||||
* @param string the title
|
||||
*/
|
||||
function link_title($contact)
|
||||
{
|
||||
if (!is_array($contact) && $contact)
|
||||
{
|
||||
$contact = $this->read($contact);
|
||||
}
|
||||
if (!is_array($contact))
|
||||
{
|
||||
return False;
|
||||
}
|
||||
return $contact['n_fileas'];
|
||||
}
|
||||
|
||||
/**
|
||||
* query addressbook for contacts matching $pattern
|
||||
*
|
||||
* Is called as hook to participate in the linking
|
||||
*
|
||||
* @param string $pattern pattern to search
|
||||
* @return array with id - title pairs of the matching entries
|
||||
*/
|
||||
function link_query($pattern)
|
||||
{
|
||||
$result = $criteria = array();
|
||||
if ($pattern)
|
||||
{
|
||||
foreach($this->columns_to_search as $col)
|
||||
{
|
||||
$criteria[$col] = $pattern;
|
||||
}
|
||||
}
|
||||
foreach((array) $this->regular_search($criteria,false,'org_name,n_family,n_given','','%',false,'OR') as $contact)
|
||||
{
|
||||
$result[$contact['id']] = $this->link_title($contact);
|
||||
}
|
||||
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',
|
||||
'view' => array(
|
||||
'menuaction' => 'addressbook.uicontacts.view'
|
||||
),
|
||||
'view_id' => 'contact_id',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by delete-account hook if an account gets deleted
|
||||
*
|
||||
* @param array $data
|
||||
*/
|
||||
function deleteaccount($data)
|
||||
{
|
||||
// delete/move personal addressbook
|
||||
parent::deleteaccount($data);
|
||||
|
||||
// delete contact linked to account
|
||||
if (($contact_id = $GLOBALS['egw']->accounts->id2name($data['account_id'],'person_id')))
|
||||
{
|
||||
$this->delete($contact_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
177
addressbook/inc/class.contacts_admin_prefs.inc.php
Normal file
@ -0,0 +1,177 @@
|
||||
<?php
|
||||
/**************************************************************************\
|
||||
* eGroupWare - Addressbook Admin-, Preferences- and SideboxMenu-Hooks *
|
||||
* http://www.eGroupWare.org *
|
||||
* Written and (c) 2006 by Ralf Becker <RalfBecker@outdoor-training.de> *
|
||||
* ------------------------------------------------------------------------ *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU General Public License as published by the *
|
||||
* Free Software Foundation; either version 2 of the License, or (at your *
|
||||
* option) any later version. *
|
||||
\**************************************************************************/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
/**
|
||||
* Class containing admin, preferences and sidebox-menus (used as hooks)
|
||||
*
|
||||
* @package addressbook
|
||||
* @author Ralf Becker <RalfBecker@outdoor-training.de>
|
||||
* @copyright (c) 2006 by Ralf Becker <RalfBecker@outdoor-training.de>
|
||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||
*/
|
||||
class contacts_admin_prefs
|
||||
{
|
||||
var $contacts_repository = 'sql';
|
||||
|
||||
/**
|
||||
* constructor
|
||||
*/
|
||||
function contacts_admin_prefs()
|
||||
{
|
||||
if($GLOBALS['egw_info']['server']['contact_repository'] == 'ldap') $this->contacts_repository = 'ldap';
|
||||
}
|
||||
|
||||
/**
|
||||
* hooks to build projectmanager's sidebox-menu plus the admin and preferences sections
|
||||
*
|
||||
* @param string/array $args hook args
|
||||
*/
|
||||
function all_hooks($args)
|
||||
{
|
||||
$appname = 'addressbook';
|
||||
$location = is_array($args) ? $args['location'] : $args;
|
||||
//echo "<p>contacts_admin_prefs::all_hooks(".print_r($args,True).") appname='$appname', location='$location'</p>\n";
|
||||
|
||||
if ($location == 'sidebox_menu')
|
||||
{
|
||||
$file = array(
|
||||
array(
|
||||
'text' => '<a class="textSidebox" href="'.$GLOBALS['egw']->link('/index.php',array('menuaction' => 'addressbook.uicontacts.edit')).
|
||||
'" onclick="window.open(this.href,\'_blank\',\'dependent=yes,width=850,height=440,scrollbars=yes,status=yes\');
|
||||
return false;">'.lang('Add').'</a>',
|
||||
'no_lang' => true,
|
||||
'link' => false
|
||||
),
|
||||
// Disabled til they are working again
|
||||
// 'Advanced search'=>$GLOBALS['egw']->link('/index.php','menuaction=addressbook.uicontacts.search'),
|
||||
// 'import contacts' => $GLOBALS['egw']->link('/index.php','menuaction=addressbook.uiXport.import'),
|
||||
// 'export contacts' => $GLOBALS['egw']->link('/index.php','menuaction=addressbook.uiXport.export')
|
||||
// 'CSV-Import' => $GLOBALS['egw']->link('/addressbook/csv_import.php')
|
||||
);
|
||||
display_sidebox($appname,lang('Addressbook menu'),$file);
|
||||
}
|
||||
|
||||
if ($GLOBALS['egw_info']['user']['apps']['preferences'] && $location != 'admin')
|
||||
{
|
||||
$file = array(
|
||||
'Preferences' => $GLOBALS['egw']->link('/index.php','menuaction=preferences.uisettings.index&appname='.$appname),
|
||||
'Grant Access' => $GLOBALS['egw']->link('/index.php','menuaction=preferences.uiaclprefs.index&acl_app='.$appname),
|
||||
'Edit Categories' => $GLOBALS['egw']->link('/index.php','menuaction=preferences.uicategories.index&cats_app=' . $appname . '&cats_level=True&global_cats=True')
|
||||
);
|
||||
if ($this->contacts_repository == 'ldap' || $GLOBALS['egw_info']['server']['deny_user_grants_access'])
|
||||
{
|
||||
unset($file['Grant Access']);
|
||||
}
|
||||
if ($location == 'preferences')
|
||||
{
|
||||
display_section($appname,$file);
|
||||
}
|
||||
else
|
||||
{
|
||||
display_sidebox($appname,lang('Preferences'),$file);
|
||||
}
|
||||
}
|
||||
|
||||
if ($GLOBALS['egw_info']['user']['apps']['admin'] && $location != 'preferences')
|
||||
{
|
||||
$file = Array(
|
||||
'Site configuration' => $GLOBALS['egw']->link('/index.php',array(
|
||||
'menuaction' => 'admin.uiconfig.index',
|
||||
'appname' => $appname,
|
||||
)),
|
||||
'Global Categories' => $GLOBALS['egw']->link('/index.php',array(
|
||||
'menuaction' => 'admin.uicategories.index',
|
||||
'appname' => $appname,
|
||||
'global_cats'=> True)),
|
||||
'Custom fields' => $GLOBALS['egw']->link('/index.php',array(
|
||||
'menuaction' => 'admin.customfields.edit',
|
||||
'appname' => $appname,
|
||||
)),
|
||||
);
|
||||
if ($location == 'admin')
|
||||
{
|
||||
display_section($appname,$file);
|
||||
}
|
||||
else
|
||||
{
|
||||
display_sidebox($appname,lang('Admin'),$file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* populates $GLOBALS['settings'] for the preferences
|
||||
*/
|
||||
function settings()
|
||||
{
|
||||
$GLOBALS['settings']['mainscreen_showbirthdays'] = array(
|
||||
'type' => 'check',
|
||||
'label' => 'Show birthday reminders on main screen',
|
||||
'name' => 'mainscreen_showbirthdays',
|
||||
'help' => 'Displays a remider for birthdays happening today or tomorrow on the startpage (page you get when you enter eGroupWare or click on the homepage icon).',
|
||||
'xmlrpc' => True,
|
||||
'admin' => False,
|
||||
);
|
||||
$column_display_options = array(
|
||||
'' => lang('only if there is content'),
|
||||
'always' => lang('always'),
|
||||
'never' => lang('never'),
|
||||
);
|
||||
foreach(array(
|
||||
'photo_column' => lang('Photo'),
|
||||
'home_column' => lang('Home address'),
|
||||
'custom_colum' => lang('custom fields'),
|
||||
) as $name => $label)
|
||||
{
|
||||
$GLOBALS['settings'][$name] = array(
|
||||
'type' => 'select',
|
||||
'label' => lang('Show a column for %1',$label),
|
||||
'run_lang' => -1,
|
||||
'name' => $name,
|
||||
'values' => $column_display_options,
|
||||
'help' => 'When should the contacts list display that colum. "Only if there is content" hides the column, unless there is some content in the view.',
|
||||
'xmlrpc' => True,
|
||||
'admin' => false,
|
||||
);
|
||||
}
|
||||
if ($this->contacts_repository == 'sql')
|
||||
{
|
||||
$GLOBALS['settings']['private_addressbook'] = array(
|
||||
'type' => 'check',
|
||||
'label' => 'Enable an extra private addressbook',
|
||||
'name' => 'private_addressbook',
|
||||
'help' => 'Do you want a private addressbook, which can not be viewed by users, you grant access to your personal addressbook?',
|
||||
'xmlrpc' => True,
|
||||
'admin' => False,
|
||||
);
|
||||
}
|
||||
return true; // otherwise prefs say it cant find the file ;-)
|
||||
}
|
||||
|
||||
/**
|
||||
* add an Addressbook tab to Admin >> Edit user
|
||||
*/
|
||||
function edit_user()
|
||||
{
|
||||
global $menuData;
|
||||
|
||||
$menuData[] = array(
|
||||
'description' => 'Addressbook',
|
||||
'url' => '/index.php',
|
||||
'extradata' => 'menuaction=addressbook.uicontacts.edit',
|
||||
'options' => "onclick=\"window.open(this,'_blank','dependent=yes,width=850,height=440,scrollbars=yes,status=yes'); return false;\"".
|
||||
' title="'.htmlspecialchars(lang('Edit extra account-data in the addressbook')).'"',
|
||||
);
|
||||
}
|
||||
}
|
@ -3,7 +3,8 @@
|
||||
* eGroupWare - Adressbook - General storage object *
|
||||
* http://www.egroupware.org *
|
||||
* Written and (c) 2005 by Cornelius_weiss <egw@von-und-zu-weiss.de> *
|
||||
* -------------------------------------------- *
|
||||
* and Ralf Becker <RalfBecker-AT-outdoor-training.de> *
|
||||
* ------------------------------------------------------------------------ *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU General Public License as published by the *
|
||||
* Free Software Foundation; either version 2 of the License, or (at your *
|
||||
@ -17,7 +18,8 @@
|
||||
*
|
||||
* @package addressbook
|
||||
* @author Cornelius Weiss <egw@von-und-zu-weiss.de>
|
||||
* @copyright (c) 2005 by Cornelius Weiss <egw@von-und-zu-weiss.de>
|
||||
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||
* @copyright (c) 2005/6 by Cornelius Weiss <egw@von-und-zu-weiss.de> and Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||
*/
|
||||
|
||||
@ -53,19 +55,93 @@ class socontacts
|
||||
*/
|
||||
var $extra_value = 'contact_value';
|
||||
|
||||
/**
|
||||
* @var string $contacts_repository 'sql' or 'ldap'
|
||||
*/
|
||||
var $contacts_repository = 'sql';
|
||||
|
||||
/**
|
||||
* @var array $grants account_id => rights pairs
|
||||
*/
|
||||
var $grants;
|
||||
|
||||
/**
|
||||
* @var int $user userid of current user
|
||||
*/
|
||||
var $user;
|
||||
|
||||
/**
|
||||
* @var array $memberships of the current user
|
||||
*/
|
||||
var $memberships;
|
||||
|
||||
/**
|
||||
* @var array $columns_to_search when we search for a single pattern
|
||||
*/
|
||||
var $columns_to_search = array();
|
||||
/**
|
||||
* @var array $account_extra_search extra columns to search if accounts are included, eg. account_lid
|
||||
*/
|
||||
var $account_extra_search = array();
|
||||
|
||||
/**
|
||||
* @var array $customfields name => array(...) pairs
|
||||
*/
|
||||
var $customfields = array();
|
||||
/**
|
||||
* @var array $content_types name => array(...) pairs
|
||||
*/
|
||||
var $content_types = array();
|
||||
|
||||
function socontacts($contact_app='addressbook')
|
||||
{
|
||||
if($GLOBALS['egw_info']['server']['contact_repository'] == 'sql' || !isset($GLOBALS['egw_info']['server']['contact_repository']))
|
||||
$this->user = $GLOBALS['egw_info']['user']['account_id'];
|
||||
foreach($GLOBALS['egw']->accounts->membership($this->user) as $group)
|
||||
{
|
||||
$this->somain =& CreateObject('etemplate.so_sql','phpgwapi','egw_addressbook');
|
||||
$this->memberships[] = $group['account_id'];
|
||||
}
|
||||
|
||||
if($GLOBALS['egw_info']['server']['contact_repository'] == 'ldap')
|
||||
{
|
||||
$this->contact_repository = 'ldap';
|
||||
$this->somain =& CreateObject('addressbook.so_'.$this->contact_repository);
|
||||
|
||||
// static grants from ldap: all rights for the own personal addressbook and the group ones of the meberships
|
||||
$this->grants = array($this->user => ~0);
|
||||
foreach($this->memberships as $gid)
|
||||
{
|
||||
$this->grants[$gid] = ~0;
|
||||
}
|
||||
// LDAP uses a limited set for performance reasons, you NEED an index for that columns, ToDo: make it configurable
|
||||
// minimum: $this->columns_to_search = array('n_family','n_given','org_name');
|
||||
$this->columns_to_search = array('n_family','n_middle','n_given','org_name','org_unit','adr_one_location','adr_two_location','note');
|
||||
$this->account_extra_search = array('uid');
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->somain =& CreateObject('addressbook.so_'.$GLOBALS['egw_info']['server']['contact_repository']);
|
||||
$this->somain =& CreateObject('addressbook.socontacts_sql','addressbook','egw_addressbook',null,'contact_');
|
||||
// group grants are now grants for the group addressbook and NOT grants for all its members, therefor the param false!
|
||||
$this->grants = $GLOBALS['egw']->acl->get_grants($contact_app,false);
|
||||
|
||||
// remove some columns, absolutly not necessary to search in sql
|
||||
$this->columns_to_search = array_diff(array_values($this->somain->db_cols),array('jpegphoto','owner','tid','private','id','cat_id','modified','modifier','creator','created'));
|
||||
$this->account_extra_search = array('account_firstname','account_lastname','account_email','account_lid');
|
||||
}
|
||||
// add grants for accounts: admin --> everything, everyone --> read
|
||||
$this->grants[0] = EGW_ACL_READ; // everyone read access
|
||||
if (isset($GLOBALS['egw_info']['user']['apps']['admin'])) // admin rights can be limited by ACL!
|
||||
{
|
||||
if (!$GLOBALS['egw']->acl->check('account_access',16,'admin')) $this->grants[0] |= EGW_ACL_EDIT;
|
||||
// no add at the moment if (!$GLOBALS['egw']->acl->check('account_access',4,'admin')) $this->grants[0] |= EGW_ACL_ADD;
|
||||
if (!$GLOBALS['egw']->acl->check('account_access',32,'admin')) $this->grants[0] |= EGW_ACL_DELETE;
|
||||
}
|
||||
// ToDo: it should be the other way arround, the backend should set the grants it uses
|
||||
$this->somain->grants =& $this->grants;
|
||||
|
||||
$this->total =& $this->somain->total;
|
||||
$this->somain->contacts_id = 'id';
|
||||
$this->soextra =& CreateObject('etemplate.so_sql');
|
||||
$this->soextra->so_sql('phpgwapi',$this->extra_table);
|
||||
$this->soextra->so_sql('addressbook',$this->extra_table);
|
||||
|
||||
$custom =& CreateObject('admin.customfields',$contact_app);
|
||||
$this->customfields = $custom->get_customfields();
|
||||
@ -75,6 +151,22 @@ class socontacts
|
||||
if ($this->content_types && !is_array($this->content_types)) $this->content_types = unserialize($this->content_types);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read all customfields of the given id's
|
||||
*
|
||||
* @param int/array $ids
|
||||
* @return array id => name => value
|
||||
*/
|
||||
function read_customfields($ids)
|
||||
{
|
||||
$fields = array();
|
||||
foreach((array)$this->soextra->search(array($this->extra_id => $ids),false) as $data)
|
||||
{
|
||||
if ($data) $fields[$data[$this->extra_id]][$data[$this->extra_key]] = $data[$this->extra_value];
|
||||
}
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* changes the data from the db-format to your work-format
|
||||
*
|
||||
@ -108,20 +200,22 @@ class socontacts
|
||||
/**
|
||||
* deletes contact entry including custom fields
|
||||
*
|
||||
* @param array &$contact contact data from etemplate::exec
|
||||
* @return bool false if all went right
|
||||
* @param mixed $contact array with key id or just the id
|
||||
* @return boolean true on success or false on failiure
|
||||
*/
|
||||
function delete($contact)
|
||||
{
|
||||
if (is_array($contact)) $contact = $contact['id'];
|
||||
|
||||
// delete mainfields
|
||||
if ($this->somain->delete(array('id' => $contact['id'])))
|
||||
if ($this->somain->delete($contact))
|
||||
{
|
||||
// delete customfields, can return 0 if there are no customfields
|
||||
$this->soextra->delete(array($this->extra_id => $contact['id']));
|
||||
$this->soextra->delete(array($this->extra_id => $contact));
|
||||
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -139,27 +233,33 @@ class socontacts
|
||||
if($error_nr) return $error_nr;
|
||||
|
||||
// save customfields
|
||||
foreach ((array)$this->customfields + array('ophone' => '', 'address2' => '' , 'address3' => '') as $field => $options)
|
||||
foreach ((array)$this->customfields as $field => $options)
|
||||
{
|
||||
if(!array_key_exists('#'.$field,$contact)) continue;
|
||||
$value = $contact['#'.$field];
|
||||
if (!isset($contact['#'.$field])) continue;
|
||||
|
||||
$data = array(
|
||||
$this->extra_id => $contact['id'],
|
||||
$this->extra_id => $contact['id'],
|
||||
$this->extra_owner => $contact['owner'],
|
||||
$this->extra_key => $field,
|
||||
$this->extra_value => $value,
|
||||
$this->extra_key => $field,
|
||||
);
|
||||
$this->soextra->data = $data;
|
||||
$error_nr = $this->soextra->save();
|
||||
if($error_nr) return $error_nr;
|
||||
if((string) $contact['#'.$field] === '') // dont write empty values
|
||||
{
|
||||
$this->soextra->delete($data); // just delete them, in case they were previously set
|
||||
continue;
|
||||
}
|
||||
$data[$this->extra_value] = $contact['#'.$field];
|
||||
if (($error_nr = $this->soextra->save($data)))
|
||||
{
|
||||
return $error_nr;
|
||||
}
|
||||
}
|
||||
return;
|
||||
return false; // no error
|
||||
}
|
||||
|
||||
/**
|
||||
* reads contact data including custom fields
|
||||
*
|
||||
* @param interger $contact_id contact_id
|
||||
* @param interger/string $contact_id contact_id or 'a'.account_id
|
||||
* @return array/boolean data if row could be retrived else False
|
||||
*/
|
||||
function read($contact_id)
|
||||
@ -169,8 +269,7 @@ class socontacts
|
||||
{
|
||||
return $contact;
|
||||
}
|
||||
|
||||
// read customfilds
|
||||
// read customfields
|
||||
$keys = array(
|
||||
$this->extra_id => $contact['id'],
|
||||
$this->extra_owner => $contact['owner'],
|
||||
@ -319,7 +418,7 @@ class socontacts
|
||||
{
|
||||
$criteria[$this->main_id] = $resultextra;
|
||||
}
|
||||
if (count($criteria) >= 1)
|
||||
if (count($criteria) >= 0) // RB-CHANGED was 1
|
||||
{
|
||||
// We do have to apply wildcard by hand, as the result-ids of extrasearch are included in this search
|
||||
if($wildcard)
|
||||
@ -381,9 +480,57 @@ class socontacts
|
||||
}
|
||||
|
||||
/**
|
||||
* searches db for rows matching searchcriteria
|
||||
*
|
||||
* '*' and '?' are replaced with sql-wildcards '%' and '_'
|
||||
*
|
||||
* @param array/string $criteria array of key and data cols, OR a SQL query (content for WHERE), fully quoted (!)
|
||||
* @param boolean/string $only_keys=true True returns only keys, False returns all cols. comma seperated list of keys 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"
|
||||
* @param string $wildcard='' appended befor and after each criteria
|
||||
* @param boolean $empty=false False=empty criteria are ignored in query, True=empty have to be empty in row
|
||||
* @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)
|
||||
* @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
|
||||
* "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 array of matching rows (the row is an array of the cols) or False
|
||||
*/
|
||||
function ®ular_search($criteria,$only_keys=True,$order_by='',$extra_cols='',$wildcard='',$empty=False,$op='AND',$start=false,$filter=null,$join='',$need_full_no_count=false)
|
||||
{
|
||||
//echo "<p>socontacts::search(".print_r($criteria,true).",'$only_keys','$order_by','$extra_cols','$wildcard','$empty','$op','$start',".print_r($filter,true).",'$join')</p>\n";
|
||||
|
||||
if (is_array($criteria) && count($criteria))
|
||||
{
|
||||
$criteria = $this->data2db($criteria);
|
||||
}
|
||||
if (is_array($filter) && count($filter))
|
||||
{
|
||||
$filter = $this->data2db($filter);
|
||||
}
|
||||
else
|
||||
{
|
||||
$filter = $filter ? array($filter) : array();
|
||||
}
|
||||
$rows =& $this->somain->search($criteria,$only_keys,$order_by,$extra_cols,$wildcard,$empty,$op,$start,$filter,$join,$need_full_no_count);
|
||||
|
||||
if ($rows)
|
||||
{
|
||||
foreach($rows as $n => $row)
|
||||
{
|
||||
$rows[$n] = $this->db2data($row);
|
||||
}
|
||||
}
|
||||
// ToDo: read custom-fields, if displayed in the index page
|
||||
return $rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* gets all contact fields from database
|
||||
*/
|
||||
function get_contact_conlumns()
|
||||
function get_contact_columns()
|
||||
{
|
||||
$fields = $this->somain->db_data_cols;
|
||||
foreach ((array)$this->customfields as $cfield => $coptions)
|
||||
@ -392,4 +539,32 @@ class socontacts
|
||||
}
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* delete / move all contacts of an addressbook
|
||||
*
|
||||
* @param array $data
|
||||
* @param int $data['account_id'] owner to change
|
||||
* @param int $data['new_owner'] new owner or 0 for delete
|
||||
*/
|
||||
function deleteaccount($data)
|
||||
{
|
||||
$account_id = $data['account_id'];
|
||||
$new_owner = $data['new_owner'];
|
||||
|
||||
if (!$new_owner)
|
||||
{
|
||||
$this->somain->delete(array('owner' => $account_id));
|
||||
$this->soextra->delete(array($this->extra_owner => $account_id));
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->somain->change_owner($account_id,$new_owner);
|
||||
$this->soextra->db->update($this->soextra->table_name,array(
|
||||
$this->extra_owner => $new_owner
|
||||
),array(
|
||||
$this->extra_owner => $account_id
|
||||
),__LINE__,__FILE__);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
262
addressbook/inc/class.socontacts_sql.inc.php
Normal file
@ -0,0 +1,262 @@
|
||||
<?php
|
||||
/**************************************************************************\
|
||||
* eGroupWare - Adressbook - SQL storage object *
|
||||
* http://www.egroupware.org *
|
||||
* Written and (c) 2006 by Ralf Becker <RalfBecker-AT-outdoor-training.de> *
|
||||
* ------------------------------------------------------------------------ *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU General Public License as published by the *
|
||||
* Free Software Foundation; either version 2 of the License, or (at your *
|
||||
* option) any later version. *
|
||||
\**************************************************************************/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
include_once(EGW_INCLUDE_ROOT.'/etemplate/inc/class.so_sql.inc.php');
|
||||
|
||||
/**
|
||||
* SQL storage object of the adressbook
|
||||
*
|
||||
* @package addressbook
|
||||
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||
* @copyright (c) 2006 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||
*/
|
||||
|
||||
class socontacts_sql extends so_sql
|
||||
{
|
||||
var $accounts_join = "JOIN egw_accounts ON person_id=contact_id";
|
||||
|
||||
/**
|
||||
* searches db for rows matching searchcriteria
|
||||
*
|
||||
* '*' and '?' are replaced with sql-wildcards '%' and '_'
|
||||
*
|
||||
* 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 $only_keys=true True returns only keys, False returns all cols. comma seperated list of keys 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"
|
||||
* @param string $wildcard='' appended befor and after each criteria
|
||||
* @param boolean $empty=false False=empty criteria are ignored in query, True=empty have to be empty in row
|
||||
* @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
|
||||
* "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
|
||||
*/
|
||||
function &search($criteria,$only_keys=True,$order_by='',$extra_cols='',$wildcard='',$empty=False,$op='AND',$start=false,$filter=null,$join='',$need_full_no_count=false)
|
||||
{
|
||||
if ((int) $this->debug >= 4) echo "<p>socontacts_sql::search(".print_r($criteria,true).",'$only_keys','$order_by','$extra_cols','$wildcard','$empty','$op','$start',".print_r($filter,true).",'$join')</p>\n";
|
||||
|
||||
$owner = isset($filter['owner']) ? $filter['owner'] : (isset($criteria['owner']) ? $criteria['owner'] : null);
|
||||
|
||||
// add filter for read ACL in sql, if user is NOT the owner of the addressbook
|
||||
if (!(isset($filter['owner']) && $filter['owner'] == $GLOBALS['egw_info']['user']['account_id']))
|
||||
{
|
||||
// we have no private grants in addressbook at the moment, they have then to be added here too
|
||||
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
|
||||
{
|
||||
$filter[] = '(contact_owner='.(int)$GLOBALS['egw_info']['user']['account_id'].' OR contact_private=0 AND contact_owner IN ('.
|
||||
implode(',',array_keys($this->grants)).') OR contact_owner IS NULL)';
|
||||
}
|
||||
}
|
||||
if (!$owner) // owner not set (=all) or 0 --> include accounts
|
||||
{
|
||||
if (!is_array($extra_cols)) $extra_cols = $extra_cols ? explode(',',$extra_cols) : array();
|
||||
$accounts2contacts = array(
|
||||
'contact_id' => 'CASE WHEN contact_id IS NULL THEN '.$this->db->concat("'account:'",'account_id').' ELSE contact_id END AS contact_id',
|
||||
'contact_owner' => 'CASE WHEN contact_owner IS NULL THEN 0 ELSE contact_owner END AS contact_owner',
|
||||
'contact_tid' => 'CASE WHEN contact_tid IS NULL THEN \'n\' ELSE contact_tid END AS contact_tid',
|
||||
'n_family' => 'CASE WHEN n_family IS NULL THEN account_lastname ELSE n_family END AS n_family',
|
||||
'n_given' => 'CASE WHEN n_given IS NULL THEN account_firstname ELSE n_given END AS n_given',
|
||||
'contact_email' => 'CASE WHEN contact_email IS NULL THEN account_email ELSE contact_email END AS contact_email',
|
||||
);
|
||||
$extra_cols = $extra_cols ? array_merge(is_array($extra_cols) ? $extra_cols : implode(',',$extra_cols),array_values($accounts2contacts)) :
|
||||
array_values($accounts2contacts);
|
||||
|
||||
if (!$only_keys)
|
||||
{
|
||||
$account_table = $this->db->get_table_definitions('phpgwapi','egw_accounts');
|
||||
// all addressbook columns, but the ones given with CASE ... AS above plus the account-columns
|
||||
$only_keys = implode(',',array_merge(array_diff(array_keys($this->db_cols),array_keys($accounts2contacts)),
|
||||
array_keys($account_table['fd'])));
|
||||
}
|
||||
foreach($filter as $col => $value)
|
||||
{
|
||||
if (!is_int($col))
|
||||
{
|
||||
if (($db_col = array_search($col,$this->db_cols)) !== false && isset($accounts2contacts[$db_col]))
|
||||
{
|
||||
unset($filter[$col]);
|
||||
$filter[] = str_replace(' AS '.$db_col,'',$accounts2contacts[$db_col]).'='.$this->db->quote($value,$this->table_def['fd'][$db_col]['type']);
|
||||
}
|
||||
}
|
||||
elseif (preg_match("/^([a-z0-9_]+) *(=|!=|LIKE|NOT LIKE) *'(.*)'\$/i",$value,$matches))
|
||||
{
|
||||
if (($db_col = array_search($matches[1],$this->db_cols)) !== false && isset($accounts2contacts[$db_col]))
|
||||
{
|
||||
$filter[$col] = str_replace(' AS '.$db_col,'',$accounts2contacts[$db_col]).' '.$matches[2].' \''.$matches[3].'\'';
|
||||
}
|
||||
}
|
||||
}
|
||||
// dont list groups
|
||||
$filter[] = "(account_type!='g' OR account_type IS NULL)";
|
||||
}
|
||||
if (is_null($owner)) // search for accounts AND contacts of all addressbooks
|
||||
{
|
||||
if ($this->db->capabilities['outer_join'])
|
||||
{
|
||||
$join = 'OUTER '.$this->accounts_join;
|
||||
}
|
||||
else // simulate the outer join with a union
|
||||
{
|
||||
parent::search($criteria,$only_keys,$order_by,$extra_cols,$wildcard,$empty,$op,'UNION',$filter,
|
||||
'LEFT '.$this->accounts_join,$need_full_no_count);
|
||||
$filter[] = 'person_id=0';
|
||||
parent::search($criteria,$only_keys,$order_by,$extra_cols,$wildcard,$empty,$op,'UNION',$filter,
|
||||
'RIGHT '.$this->accounts_join,$need_full_no_count);
|
||||
}
|
||||
}
|
||||
elseif (!$owner) // search for accounts only
|
||||
{
|
||||
$join = 'RIGHT '.$this->accounts_join;
|
||||
$filter[] = "account_type='u'"; // no groups
|
||||
}
|
||||
return parent::search($criteria,$only_keys,$order_by,$extra_cols,$wildcard,$empty,$op,$start,$filter,$join,$need_full_no_count);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* reads contact data including custom fields
|
||||
*
|
||||
* reimplemented to read/convert accounts and return the account_id for them
|
||||
*
|
||||
* @param integer/string $contact_id contact_id or 'account:'.account_id
|
||||
* @return array/boolean data if row could be retrived else False
|
||||
*/
|
||||
function read($contact_id)
|
||||
{
|
||||
//echo "<p>socontacts_sql::read($contact_id)</p>\n";
|
||||
if (substr($contact_id,0,8) == 'account:')
|
||||
{
|
||||
$account_id = (int) substr($contact_id,8);
|
||||
|
||||
if (!$GLOBALS['egw']->accounts->exists($account_id)) return false; // account does not exist
|
||||
|
||||
// check if the account is already linked with a contact, if not create one with the content of the account
|
||||
if (!($contact_id = $GLOBALS['egw']->accounts->id2name($account_id,'person_id')) &&
|
||||
!($matching_contact_id = $this->_find_unique_contact(
|
||||
$GLOBALS['egw']->accounts->id2name($account_id,'account_firstname'),
|
||||
$GLOBALS['egw']->accounts->id2name($account_id,'account_lastname'))))
|
||||
{
|
||||
// as the account object has no function to just read a record and NOT override it's internal data,
|
||||
// we have to instanciate a new object and can NOT use $GLOBALS['egw']->accounts !!!
|
||||
$account =& new accounts($account_id,'u');
|
||||
$account->read();
|
||||
|
||||
if (!$account->data['account_id']) return false; // account not found
|
||||
|
||||
$this->init();
|
||||
$this->save(array(
|
||||
'n_family' => $account->data['lastname'],
|
||||
'n_given' => $account->data['firstname'],
|
||||
'n_fn' => $account->data['firstname'].' '.$account->data['lastname'],
|
||||
'n_fileas' => $account->data['lastname'].', '.$account->data['firstname'],
|
||||
'email' => $account->data['email'],
|
||||
'owner' => 0,
|
||||
'tid' => 'n',
|
||||
),$account_id);
|
||||
|
||||
return $this->data+array('account_id' => $account_id);
|
||||
}
|
||||
elseif ($matching_contact_id)
|
||||
{
|
||||
//echo "<p>socontacts_sql($contact_id) account_id=$account_id, matching_contact_id=$matching_contact_id</p>\n";
|
||||
$contact = parent::read($matching_contact_id);
|
||||
$contact['owner'] = 0;
|
||||
$this->save($contact,$account_id);
|
||||
|
||||
return $this->data+array('account_id' => $account_id);
|
||||
}
|
||||
//echo "<p>socontacts_sql::read() account_id='$account_id', contact_id='$contact_id'</p>\n"; exit;
|
||||
}
|
||||
if (($contact = parent::read($contact_id)) && !$contact['owner']) // return account_id for accounts
|
||||
{
|
||||
$contact['account_id'] = $GLOBALS['egw']->accounts->name2id($contact_id,'person_id');
|
||||
}
|
||||
return $contact;
|
||||
}
|
||||
|
||||
function _find_unique_contact($firstname,$lastname)
|
||||
{
|
||||
$contacts =& $this->search(array(
|
||||
'contact_owner != 0',
|
||||
'n_given' => $firstname,
|
||||
'n_family' => $lastname,
|
||||
'private' => 0,
|
||||
));
|
||||
//echo "<p>soccontacts_sql::_find_unique_contacts($firstname,$lastname)</p>\n"; _debug_array($contacts);
|
||||
|
||||
return $contacts && count($contacts) == 1 ? $contacts[0]['id'] : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* saves the content of data to the db
|
||||
*
|
||||
* reimplemented to write for accounts some of the data to the account too and link it with the contact
|
||||
*
|
||||
* @param array $keys if given $keys are copied to data before saveing => allows a save as
|
||||
* @param int $account_id if called by read account_id of account to save/link with contact (we dont overwrite the account-data in that case),
|
||||
* otherwise we try getting it by accounts::name2id('person_id',$contact_id)
|
||||
* @return int 0 on success and errno != 0 else
|
||||
*/
|
||||
function save($data=null,$account_id=0)
|
||||
{
|
||||
$this->data_merge($data);
|
||||
|
||||
// if called by read's automatic conversation --> dont change the email of the account (if set)
|
||||
if (!$this->data['owner'] && $account_id &&
|
||||
($email = $GLOBALS['egw']->accounts->id2name($account_id,'account_email')) && $data['email'] != $email)
|
||||
{
|
||||
if (!$data['email_home']) $data['email_home'] = $data['email'];
|
||||
$data['email'] = $email;
|
||||
}
|
||||
if (!($error = parent::save()) && !$this->data['owner']) // successfully saved an account --> sync our data in the account-table
|
||||
{
|
||||
if (!$account_id && !($account_id = $GLOBALS['egw']->accounts->name2id($this->data['id'],'person_id')) &&
|
||||
// try find a matching account for migration
|
||||
!($account_id = $GLOBALS['egw']->accounts->name2id($this->data['n_given'].' '.$this->data['n_family'],'account_fullname')))
|
||||
{
|
||||
// ToDo create new account
|
||||
}
|
||||
// as the account object has no function to just read a record and NOT override it's internal data,
|
||||
// we have to instanciate a new object and can NOT use $GLOBALS['egw']->accounts !!!
|
||||
$account =& new accounts($account_id,'u');
|
||||
$account->read_repository();
|
||||
|
||||
if (!$account->data['account_id']) return false; // account not found
|
||||
|
||||
foreach(array(
|
||||
'n_family' => 'lastname',
|
||||
'n_given' => 'firstname',
|
||||
'email' => 'email',
|
||||
'id' => 'person_id',
|
||||
) as $c_name => $a_name)
|
||||
{
|
||||
$account->data[$a_name] = $this->data[$c_name];
|
||||
}
|
||||
$account->save_repository();
|
||||
}
|
||||
return $error;
|
||||
}
|
||||
}
|
@ -2,8 +2,9 @@
|
||||
/**************************************************************************\
|
||||
* eGroupWare - Adressbook - General user interface object *
|
||||
* http://www.egroupware.org *
|
||||
* Written and (c) 2005 by Cornelius_weiss <egw@von-und-zu-weiss.de> *
|
||||
* -------------------------------------------- *
|
||||
* Written and (c) 2005/6 by Cornelius Weiss <egw@von-und-zu-weiss.de> *
|
||||
* and Ralf Becker <RalfBecker-AT-outdoor-training.de> *
|
||||
* ------------------------------------------------------------------------ *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU General Public License as published by the *
|
||||
* Free Software Foundation; either version 2 of the License, or (at your *
|
||||
@ -19,7 +20,8 @@ require_once(EGW_INCLUDE_ROOT.'/addressbook/inc/class.bocontacts.inc.php');
|
||||
*
|
||||
* @package addressbook
|
||||
* @author Cornelius Weiss <egw@von-und-zu-weiss.de>
|
||||
* @copyright (c) 2005 by Cornelius Weiss <egw@von-und-zu-weiss.de>
|
||||
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||
* @copyright (c) 2005/6 by Cornelius Weiss <egw@von-und-zu-weiss.de> and Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||
*/
|
||||
class uicontacts extends bocontacts
|
||||
@ -28,11 +30,19 @@ class uicontacts extends bocontacts
|
||||
'search' => True,
|
||||
'edit' => True,
|
||||
'view' => True,
|
||||
'index' => True,
|
||||
'photo' => True,
|
||||
);
|
||||
var $prefs;
|
||||
/**
|
||||
* var boolean $private_addressbook use a separate private addressbook (former private flag), for contacts not shareable via regular read acl
|
||||
*/
|
||||
var $private_addressbook = false;
|
||||
|
||||
function uicontacts($contact_app='addressbook')
|
||||
{
|
||||
$this->bocontacts($contact_app);
|
||||
|
||||
foreach(array(
|
||||
'tmpl' => 'etemplate.etemplate',
|
||||
) as $my => $app_class)
|
||||
@ -45,12 +55,483 @@ class uicontacts extends bocontacts
|
||||
}
|
||||
$this->$my = &$GLOBALS['egw']->$class;
|
||||
}
|
||||
$this->prefs =& $GLOBALS['egw_info']['user']['preferences']['addressbook'];
|
||||
$this->private_addressbook = $this->contacts_repository == 'sql' && $this->prefs['private_addressbook'];
|
||||
|
||||
// our javascript
|
||||
// to be moved in a seperate file if rewrite is over
|
||||
$GLOBALS['egw_info']['flags']['java_script'] .= $this->js();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* List contacts of an addressbook
|
||||
*
|
||||
* @param array $content=null submitted content
|
||||
* @param string $msg=null message to show
|
||||
*/
|
||||
function index($content=null,$msg=null)
|
||||
{
|
||||
if (is_array($content))
|
||||
{
|
||||
$msg = $content['msg'];
|
||||
|
||||
if (isset($content['nm']['rows']['delete'])) // handle a single delete like delete with the checkboxes
|
||||
{
|
||||
list($id) = @each($content['nm']['rows']['delete']);
|
||||
$content['action'] = 'delete';
|
||||
$content['nm']['rows']['checked'] = array($id);
|
||||
}
|
||||
if ($content['action'] !== '')
|
||||
{
|
||||
if (!count($content['nm']['rows']['checked']) && !$content['use_all'])
|
||||
{
|
||||
$msg = lang('You need to select some contacts first');
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($this->action($content['action'],$content['nm']['rows']['checked'],$content['use_all'],$success,$failed,$action_msg))
|
||||
{
|
||||
$msg .= lang('%1 contact(s) %2',$success,$action_msg);
|
||||
}
|
||||
else
|
||||
{
|
||||
$msg .= lang('%1 contact(s) %2, %3 failed because of insufficent rights !!!',$success,$action_msg,$failed);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$content = array(
|
||||
'msg' => $msg ? $msg : $_GET['msg'],
|
||||
);
|
||||
$content['nm'] = $GLOBALS['egw']->session->appsession('index','addressbook');
|
||||
// if (!is_array($content['nm']))
|
||||
{
|
||||
$content['nm'] = array(
|
||||
'get_rows' => 'addressbook.uicontacts.get_rows', // I method/callback to request the data for the rows eg. 'notes.bo.get_rows'
|
||||
'header_right' => 'addressbook.index.right', // I template to show right of the range-value, right-aligned (optional)
|
||||
'bottom_too' => false, // I show the nextmatch-line (arrows, filters, search, ...) again after the rows
|
||||
'never_hide' => True, // I never hide the nextmatch-line if less then maxmatch entrie
|
||||
'start' => 0, // IO position in list
|
||||
'cat_id' => 0, // IO category, if not 'no_cat' => True
|
||||
'search' => '', // IO search pattern
|
||||
'order' => 'n_family', // IO name of the column to sort after (optional for the sortheaders)
|
||||
'sort' => 'ASC', // IO direction of the sort: 'ASC' or 'DESC'
|
||||
'col_filter' => array(), // IO array of column-name value pairs (optional for the filterheaders)
|
||||
'filter_label' => 'Addressbook', // I label for filter (optional)
|
||||
// filter needs to be type string as as int it matches the private addressbook too!
|
||||
'filter' => (string) $GLOBALS['egw_info']['user']['account_id'], // IO filter, if not 'no_filter' => True
|
||||
'filter_no_lang' => True, // I set no_lang for filter (=dont translate the options)
|
||||
'no_filter2' => True, // I disable the 2. filter (params are the same as for filter)
|
||||
'filter2' => '', // IO filter2, if not 'no_filter2' => True
|
||||
'filter2_no_lang'=> True, // I set no_lang for filter2 (=dont translate the options)
|
||||
'lettersearch' => true,
|
||||
);
|
||||
// use the state of the last session stored in the user prefs
|
||||
if (($state = @unserialize($this->prefs['index_state'])))
|
||||
{
|
||||
$content['nm'] = array_merge($content['nm'],$state);
|
||||
}
|
||||
}
|
||||
$sel_options = array(
|
||||
'filter' => $this->get_addressbooks(EGW_ACL_READ,lang('All')),
|
||||
);
|
||||
$sel_options['action'] = array(
|
||||
'delete' => lang('Delete'),
|
||||
'vcard' => lang('Export as VCard'),
|
||||
)+$this->get_addressbooks(EGW_ACL_ADD);
|
||||
foreach($this->content_types as $tid => $data)
|
||||
{
|
||||
$sel_options['col_filter[tid]'][$tid] = $data['name'];
|
||||
}
|
||||
$this->tmpl->read('addressbook.index');
|
||||
return $this->tmpl->exec('addressbook.uicontacts.index',$content,$sel_options,$readonlys,$preserv);
|
||||
}
|
||||
|
||||
/**
|
||||
* apply an action to multiple contacts
|
||||
*
|
||||
* @param string/int $action 'delete', 'vcard', 'csv' or nummerical account_id to move contacts to that addessbook
|
||||
* @param array $checked contact id's to use if !$use_all
|
||||
* @param boolean $use_all if true use all contacts of the current selection (in the session)
|
||||
* @param int &$success number of succeded actions
|
||||
* @param int &$failed number of failed actions (not enought permissions)
|
||||
* @param string &$action_msg translated verb for the actions, to be used in a message like %1 contacts 'deleted'
|
||||
* @return boolean true if all actions succeded, false otherwise
|
||||
*/
|
||||
function action($action,$checked,$use_all,&$success,&$failed,&$action_msg)
|
||||
{
|
||||
//echo "<p>uicontacts::action('$action',".print_r($checked,true).','.(int)$use_all.",...)</p>\n";
|
||||
$success = $failed = 0;
|
||||
|
||||
if ($use_all)
|
||||
{
|
||||
// get the whole selection
|
||||
$query = $GLOBALS['egw']->session->appsession('index','addressbook');
|
||||
$query['num_rows'] = -1; // all
|
||||
$this->get_rows($query,$checked,$readonlys,true); // true = only return the id's
|
||||
}
|
||||
foreach($checked as $id)
|
||||
{
|
||||
switch($action)
|
||||
{
|
||||
case 'delete':
|
||||
$action_msg = lang('deleted');
|
||||
if (($Ok = ($contact = $this->read($id)) && $this->check_perms(EGW_ACL_DELETE,$contact)))
|
||||
{
|
||||
if ($contact['owner']) // regular contact
|
||||
{
|
||||
$Ok = $this->delete($id);
|
||||
}
|
||||
elseif (count($checked) == 1) // delete single account --> redirect to admin
|
||||
{
|
||||
$GLOBALS['egw']->redirect_link('/index.php',array(
|
||||
'menuaction' => 'admin.uiaccounts.delete_user',
|
||||
'account_id' => $contact['account_id'],
|
||||
));
|
||||
// this does NOT return!
|
||||
}
|
||||
else // no mass delete of accounts
|
||||
{
|
||||
$Ok = false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'vcard':
|
||||
$action_msg = lang('exported');
|
||||
$Ok = false; // todo
|
||||
break;
|
||||
|
||||
case 'csv':
|
||||
$action_msg = lang('exported');
|
||||
$Ok = false; // todo
|
||||
break;
|
||||
|
||||
default: // move to an other addressbook
|
||||
if (!is_numeric($action) || !($this->grants[(int) $action] & EGW_ACL_EDIT)) // might be ADD in the future
|
||||
{
|
||||
return false;
|
||||
}
|
||||
$action_msg = lang('moved');
|
||||
if (($OK = ($contact = $this->read($id)) && $this->check_perms(EGW_ACL_DELETE,$contact)))
|
||||
{
|
||||
if (!$contact['owner']) // no mass-change of accounts
|
||||
{
|
||||
$Ok = false;
|
||||
}
|
||||
elseif ($contact['owner'] != $action) // no need to change
|
||||
{
|
||||
$contact['owner'] = (int) $action;
|
||||
$contact['private'] = 0;
|
||||
$Ok = $this->save($contact);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
if ($Ok)
|
||||
{
|
||||
++$success;
|
||||
}
|
||||
else
|
||||
{
|
||||
++$failed;
|
||||
}
|
||||
}
|
||||
return !$failed;
|
||||
}
|
||||
|
||||
/**
|
||||
* rows callback for index nextmatch
|
||||
*
|
||||
* @internal
|
||||
* @param array &$query
|
||||
* @param array &$rows returned rows/cups
|
||||
* @param array &$readonlys eg. to disable buttons based on acl
|
||||
* @param boolena $id_only=false if true only return (via $rows) an array of contact-ids, dont save state to session
|
||||
* @return int total number of contacts matching the selection
|
||||
*/
|
||||
function get_rows(&$query,&$rows,&$readonlys,$id_only=false)
|
||||
{
|
||||
//echo "<p>uicontacts::get_rows(".print_r($query,true).")</p>\n";
|
||||
if (!$id_only)
|
||||
{
|
||||
$GLOBALS['egw']->session->appsession('index','addressbook',$query);
|
||||
// save the state of the index in the user prefs
|
||||
$state = serialize(array(
|
||||
'filter' => $query['filter'],
|
||||
'cat_id' => $query['cat_id'],
|
||||
'order' => $query['order'],
|
||||
'sort' => $query['sort'],
|
||||
));
|
||||
if ($state != $this->prefs['index_state'])
|
||||
{
|
||||
$GLOBALS['egw']->preferences->add('addressbook','index_state',$state);
|
||||
$GLOBALS['egw']->preferences->save_repository();
|
||||
}
|
||||
}
|
||||
if (isset($query['col_filter']['cat_id'])) unset($query['col_filter']['cat_id']);
|
||||
if ($query['cat_id'])
|
||||
{
|
||||
if (!is_object($GLOBALS['egw']->categories))
|
||||
{
|
||||
$GLOBALS['egw']->categories =& CreateObject('phpgwapi.categories');
|
||||
}
|
||||
$cats = $GLOBALS['egw']->categories->return_all_children((int)$query['cat_id']);
|
||||
$query['col_filter']['cat_id'] = count($cats) > 1 ? $cats : $query['cat_id'];
|
||||
}
|
||||
if ($query['filter'] !== '') // not all addressbooks
|
||||
{
|
||||
$query['col_filter']['owner'] = (string) (int) $query['filter'];
|
||||
|
||||
if ($this->private_addressbook)
|
||||
{
|
||||
$query['col_filter']['private'] = substr($query['filter'],-1) == 'p' ? 1 : 0;
|
||||
}
|
||||
}
|
||||
// translate the select order to the realy used over all 3 columns
|
||||
$sort = $query['sort'];
|
||||
switch($query['order'])
|
||||
{
|
||||
case 'org_name':
|
||||
$order = "org_name $sort,n_family $sort,n_given $sort";
|
||||
break;
|
||||
default:
|
||||
$query['order'] = 'n_family';
|
||||
case 'n_family':
|
||||
$order = "n_family $sort,n_given $sort,org_name $sort";
|
||||
break;
|
||||
case 'n_given':
|
||||
$order = "n_given $sort,n_family $sort,org_name $sort";
|
||||
break;
|
||||
case 'n_fileas':
|
||||
$order = 'n_fileas '.$sort;
|
||||
break;
|
||||
}
|
||||
$criteria = array();
|
||||
if ($query['search'])
|
||||
{
|
||||
$cols = $this->columns_to_search;
|
||||
if (!$query['filter']) // extra columns for search if accounts are included, eg. account_lid
|
||||
{
|
||||
$cols = array_merge($cols,$this->account_extra_search);
|
||||
}
|
||||
foreach($cols as $col)
|
||||
{
|
||||
$criteria[$col] = $query['search'];
|
||||
}
|
||||
}
|
||||
if ($query['searchletter']) // only show contacts which ordercriteria starts with the given letter
|
||||
{
|
||||
$query['col_filter'][] = $query['order'].' LIKE '.$GLOBALS['egw']->db->quote($query['searchletter'].'%');
|
||||
}
|
||||
else // dont show contacts with empty order criteria
|
||||
{
|
||||
$query['col_filter'][] = $query['order']."!=''";
|
||||
}
|
||||
$rows = (array) $this->regular_search($criteria,$id_only,$order,'','%',false,'OR',array((int)$query['start'],(int) $query['num_rows']),$query['col_filter']);
|
||||
|
||||
if ($id_only) return $this->total; // no need to set other fields or $readonlys
|
||||
|
||||
if ($this->prefs['custom_colum'] != 'never' && $rows) // do we need the custom fields
|
||||
{
|
||||
foreach($rows as $n => $val)
|
||||
{
|
||||
$ids[] = $val['id'];
|
||||
}
|
||||
$customfields = $this->read_customfields($ids);
|
||||
}
|
||||
$order = $query['order'];
|
||||
|
||||
if (!$rows) $rows = array();
|
||||
|
||||
$readonlys = array();
|
||||
$photos = $homeaddress = false;
|
||||
foreach($rows as $n => $val)
|
||||
{
|
||||
$row =& $rows[$n];
|
||||
|
||||
$given = $row['n_given'] ? $row['n_given'] : ($row['n_prefix'] ? $row['n_prefix'] : '');
|
||||
|
||||
switch($order)
|
||||
{
|
||||
case 'org_name':
|
||||
$row['first_org'] = $row['n_family'].($given ? ', '.$given : '');
|
||||
break;
|
||||
default:
|
||||
$order = 'n_family';
|
||||
case 'n_family':
|
||||
$row['first_family'] = $row['n_family'].($given ? ', '.$given : '');
|
||||
break;
|
||||
case 'n_given':
|
||||
$row['first_given'] = $given.' '.$row['n_family'];
|
||||
break;
|
||||
}
|
||||
$this->type_icon($row['owner'],$row['private'],$row['tid'],$row['type'],$row['type_label']);
|
||||
|
||||
static $tel2show = array('tel_work','tel_cell','tel_home');
|
||||
foreach($tel2show as $name)
|
||||
{
|
||||
|
||||
$row[$name] .= ' '.($row['tel_prefer'] == $name ? '♥' : ''); // .' ' to NOT remove the field
|
||||
}
|
||||
// allways show the prefered phone, if not already shown
|
||||
if (!in_array($row['tel_prefer'],$tel2show) && $row[$row['tel_prefer']])
|
||||
{
|
||||
$row['tel_prefered'] = $row[$row['tel_prefer']].' ♥';
|
||||
}
|
||||
foreach(array('email','email_home') as $name)
|
||||
{
|
||||
if ($row[$name])
|
||||
{
|
||||
$row[$name.'_link'] = $this->email2link($row[$name]);
|
||||
if ($GLOBALS['egw_info']['user']['apps']['felamimail'])
|
||||
{
|
||||
$row[$name.'_popup'] = '700x750';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$row[$name] = ' '; // to NOT remove the field
|
||||
}
|
||||
}
|
||||
$readonlys["delete[$row[id]]"] = !$this->check_perms(EGW_ACL_DELETE,$row);
|
||||
$readonlys["edit[$row[id]]"] = !$this->check_perms(EGW_ACL_EDIT,$row);
|
||||
|
||||
if ($row['photo']) $photos = true;
|
||||
|
||||
if (isset($customfields[$row['id']]))
|
||||
{
|
||||
foreach($this->customfields as $name => $data)
|
||||
{
|
||||
$row['customfields'][] = $customfields[$row['id']][$name];
|
||||
}
|
||||
}
|
||||
if ($this->prefs['home_column'] != 'never' && !$homeaddress)
|
||||
{
|
||||
foreach(array('adr_two_countryname','adr_two_locality','adr_two_postalcode','adr_two_street','adr_two_street2') as $name)
|
||||
{
|
||||
if ($row[$name]) $homeaddress = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
// disable photo column, if view contains no photo(s)
|
||||
if (!$photos || $this->prefs['photo_column'] == 'never') $rows['no_photo'] = '1';
|
||||
// disable customfields column, if we have no customefield(s)
|
||||
if (!$customfields || $this->prefs['custom_column'] == 'never') $rows['no_customfields'] = '1';
|
||||
// disable homeaddress column, if we have no homeaddress(es)
|
||||
if ($homeaddress && !$this->prefs['home_column'] || $this->prefs['home_column'] == 'always') $rows['show_home'] = '1';
|
||||
|
||||
$rows['order'] = $order;
|
||||
|
||||
$rows['customfields'] = array_values($this->customfields);
|
||||
|
||||
// full app-header with all search criteria for specially for the print
|
||||
$GLOBALS['egw_info']['flags']['app_header'] = lang('addressbook');
|
||||
if ($query['filter'] !== '')
|
||||
{
|
||||
$GLOBALS['egw_info']['flags']['app_header'] .= ': '.($query['filter'] == '0' ? lang('accounts') :
|
||||
($GLOBALS['egw']->accounts->get_type($query['filter']) == 'g' ?
|
||||
lang('Group %1',$GLOBALS['egw']->accounts->id2name($query['filter'])) :
|
||||
$GLOBALS['egw']->common->grab_owner_name((int)$query['filter']).
|
||||
(substr($query['filter'],-1) == 'p' ? ' ('.lang('private').')' : '')));
|
||||
}
|
||||
if ($query['cat_id'])
|
||||
{
|
||||
$GLOBALS['egw_info']['flags']['app_header'] .= ': '.lang('Category').' '.$GLOBALS['egw']->categories->id2name($query['cat_id']);
|
||||
}
|
||||
if ($query['searchletter'])
|
||||
{
|
||||
$order = $order == 'org_name' ? lang('company name') : ($order == 'n_given' ? lang('first name') : lang('last name'));
|
||||
$GLOBALS['egw_info']['flags']['app_header'] .= ' - '.lang("%1 starts with '%2'",$order,$query['searchletter']);
|
||||
}
|
||||
if ($query['search'])
|
||||
{
|
||||
$GLOBALS['egw_info']['flags']['app_header'] .= ' - '.lang("Search for '%1'",$query['search']);
|
||||
}
|
||||
return $this->total;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get addressbook type icon from owner, private and tid
|
||||
*
|
||||
* @param int $owner user- or group-id or 0 for accounts
|
||||
* @param boolean $private
|
||||
* @param string $tid 'n' for regular addressbook
|
||||
* @param string &$icon icon-name
|
||||
* @param string &$label translated label
|
||||
*/
|
||||
function type_icon($owner,$private,$tid,&$icon,&$label)
|
||||
{
|
||||
if (!$owner)
|
||||
{
|
||||
$icon = 'accounts';
|
||||
$label = lang('accounts');
|
||||
}
|
||||
elseif ($row['private'])
|
||||
{
|
||||
$icon = 'private';
|
||||
$label = lang('private');
|
||||
}
|
||||
elseif ($tid != 'n')
|
||||
{
|
||||
// ToDo Conny: tid-icons
|
||||
$icon = '';
|
||||
$label = $tid;
|
||||
}
|
||||
elseif ($GLOBALS['egw']->accounts->get_type($owner) == 'g')
|
||||
{
|
||||
$icon = 'group';
|
||||
$label = lang('group %1',$GLOBALS['egw']->accounts->id2name($owner));
|
||||
}
|
||||
else
|
||||
{
|
||||
$icon = 'personal';
|
||||
$label = $owner == $this->user ? lang('personal') : $GLOBALS['egw']->common->grab_owner_name($owner);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the availible addressbooks of the user
|
||||
*
|
||||
* @param int $required=EGW_ACL_READ required rights on the addressbook
|
||||
* @param string $extra_label first label if given (already translated)
|
||||
* @return array with owner => label pairs
|
||||
*/
|
||||
function get_addressbooks($required=EGW_ACL_READ,$extra_label=null)
|
||||
{
|
||||
//echo "uicontacts::get_addressbooks($required,$include_all) grants="; _debug_array($this->grants);
|
||||
|
||||
$addressbooks = array();
|
||||
if ($extra_label) $addressbooks[''] = $extra_label;
|
||||
$addressbooks[$this->user] = lang('Personal');
|
||||
// add all group addressbooks the user has the necessary rights too
|
||||
foreach($this->grants as $uid => $rights)
|
||||
{
|
||||
if (($rights & $required) && $GLOBALS['egw']->accounts->get_type($uid) == 'g')
|
||||
{
|
||||
$addressbooks[$uid] = lang('Group %1',$GLOBALS['egw']->accounts->id2name($uid));
|
||||
}
|
||||
}
|
||||
if ($this->grants[0] & $required)
|
||||
{
|
||||
$addressbooks[0] = lang('Accounts');
|
||||
}
|
||||
// add all other user addressbooks the user has the necessary rights too
|
||||
foreach($this->grants as $uid => $rights)
|
||||
{
|
||||
if ($uid != $this->user && ($rights & $required) && $GLOBALS['egw']->accounts->get_type($uid) == 'u')
|
||||
{
|
||||
$addressbooks[$uid] = $GLOBALS['egw']->common->grab_owner_name($uid);
|
||||
}
|
||||
}
|
||||
if ($this->private_addressbook)
|
||||
{
|
||||
$addressbooks[$this->user.'p'] = lang('Private');
|
||||
}
|
||||
//_debug_array($addressbooks);
|
||||
return $addressbooks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit a contact
|
||||
*
|
||||
@ -71,16 +552,26 @@ class uicontacts extends bocontacts
|
||||
if (is_array($content))
|
||||
{
|
||||
list($button) = @each($content['button']);
|
||||
unset($content['button']);
|
||||
$content['private'] = (int) ($content['owner'] && substr($content['owner'],-1) == 'p');
|
||||
$content['owner'] = (string) (int) $content['owner'];
|
||||
|
||||
switch($button)
|
||||
{
|
||||
case 'save':
|
||||
case 'apply':
|
||||
if ($content['delete_photo']) unset($content['jpegphoto']);
|
||||
if (is_array($content['upload_photo']) && !empty($content['upload_photo']['tmp_name']) &&
|
||||
$content['upload_photo']['tmp_name'] != 'none')
|
||||
{
|
||||
$content['jpegphoto'] = $this->resize_photo($content['upload_photo']);
|
||||
}
|
||||
$links = false;
|
||||
if (!$content['id'] && is_array($content['link_to']['to_id']))
|
||||
{
|
||||
$links = $content['link_to']['to_id'];
|
||||
}
|
||||
$content = $this->save($content);
|
||||
$this->save($content);
|
||||
// writing links for new entry, existing ones are handled by the widget itself
|
||||
if ($links && $content['id'])
|
||||
{
|
||||
@ -88,19 +579,21 @@ class uicontacts extends bocontacts
|
||||
}
|
||||
if ($button == 'save')
|
||||
{
|
||||
echo "<html><body><script>var referer = opener.location;opener.location.href = referer;window.close();</script></body></html>\n";
|
||||
echo "<html><body><script>var referer = opener.location;opener.location.href = referer+(referer.search?'&':'?')+'msg=".
|
||||
addslashes(urlencode(lang('Contact saved')))."'; window.close();</script></body></html>\n";
|
||||
$GLOBALS['egw']->common->egw_exit();
|
||||
}
|
||||
$content['link_to']['to_id'] = $content['id'];
|
||||
$GLOBALS['egw_info']['flags']['java_script'] .= "<script LANGUAGE=\"JavaScript\">
|
||||
var referer = opener.location;
|
||||
opener.location.href = referer;</script>";
|
||||
opener.location.href = referer+(referer.search?'&':'?')+'msg=".addslashes(urlencode(lang('Contact saved')))."';</script>";
|
||||
break;
|
||||
|
||||
case 'delete':
|
||||
if(!$this->delete($content));
|
||||
if($this->delete($content));
|
||||
{
|
||||
echo "<html><body><script>var referer = opener.location;opener.location.href = referer;window.close();</script></body></html>\n";
|
||||
echo "<html><body><script>var referer = opener.location; opener.location.href = referer+(referer.search?'&':'?')+'msg=".
|
||||
addslashes(urlencode(lang('Contact deleted !!!')))."';window.close();</script></body></html>\n";
|
||||
$GLOBALS['egw']->common->egw_exit();
|
||||
}
|
||||
break;
|
||||
@ -110,21 +603,38 @@ class uicontacts extends bocontacts
|
||||
else
|
||||
{
|
||||
$content = array();
|
||||
$contact_id = $_GET['contact_id'] ? $_GET['contact_id'] : 0;
|
||||
$contact_id = $_GET['contact_id'] ? $_GET['contact_id'] : ((int)$_GET['account_id'] ? 'account:'.(int)$_GET['account_id'] : 0);
|
||||
$view = $_GET['view'];
|
||||
|
||||
if ($contact_id)
|
||||
// new contact --> set some defaults
|
||||
if ($contact_id && is_array($content = $this->read($contact_id)))
|
||||
{
|
||||
$content = $this->read($contact_id);
|
||||
$contact_id = $content['id']; // it could have been: "account:$account_id"
|
||||
}
|
||||
else // look if we have presets for a new contact
|
||||
else // not found
|
||||
{
|
||||
if (isset($_GET['owner']) && $_GET['owner'] !== '')
|
||||
{
|
||||
$content['owner'] = $_GET['owner'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$state = $GLOBALS['egw']->session->appsession('index','addressbook');
|
||||
$content['owner'] = $state['filter'];
|
||||
unset($state);
|
||||
}
|
||||
$content['private'] = (int) ($content['owner'] && substr($content['owner'],-1) == 'p');
|
||||
if (!($this->grants[$content['owner'] = (string) (int) $content['owner']] & EGW_ACL_ADD))
|
||||
{
|
||||
$content['owner'] = (string) $this->user;
|
||||
}
|
||||
$new_type = array_keys($this->content_types);
|
||||
$content['tid'] = $_GET['typeid'] ? $_GET['typeid'] : $new_type[0];
|
||||
foreach($this->get_contact_conlumns() as $field => $data)
|
||||
foreach($this->get_contact_columns() as $field => $data)
|
||||
{
|
||||
if ($_GET['presets'][$field]) $content[$field] = $_GET['presets'][$field];
|
||||
}
|
||||
$content['creator'] = $this->user;
|
||||
$content['created'] = $this->now_su;
|
||||
}
|
||||
|
||||
if($content && $_GET['makecp']) // copy the contact
|
||||
@ -135,30 +645,34 @@ class uicontacts extends bocontacts
|
||||
$GLOBALS['egw_info']['user']['account_firstname'],$GLOBALS['egw_info']['user']['account_lastname']),
|
||||
$content['id']));
|
||||
unset($content['id']);
|
||||
$content['creator'] = $this->user;
|
||||
$content['created'] = $this->now_su;
|
||||
}
|
||||
else
|
||||
{
|
||||
$content['link_to']['to_id'] = (int) $contact_id;
|
||||
$content['link_to']['to_id'] = $contact_id;
|
||||
}
|
||||
}
|
||||
|
||||
//_debug_array($content);
|
||||
$readonlys['button[delete]'] = !$this->check_perms(EGW_ACL_DELETE,$content);
|
||||
$readonlys['button[copy]'] = $readonlys['button[edit]'] = $readonlys['button[vcard]'] = true;
|
||||
|
||||
$preserv = array(
|
||||
'id' => $content['id'],
|
||||
'lid' => $content['lid'],
|
||||
'owner' => $content['owner'],
|
||||
'fn' => $content['fn'],
|
||||
'geo' => $content['geo'],
|
||||
'access' => $content['access'],
|
||||
);
|
||||
|
||||
$sel_options['fileas_type'] = $this->fileas_options($content);
|
||||
$sel_options['owner'] = $this->get_addressbooks(EGW_ACL_ADD);
|
||||
if ((string) $content['owner'] !== '')
|
||||
{
|
||||
if (!isset($sel_options['owner'][(int)$content['owner']]))
|
||||
{
|
||||
$sel_options['owner'][(int)$content['owner']] = $GLOBALS['egw']->common->grab_owner_name($content['owner']);
|
||||
}
|
||||
$readonlys['owner'] = !$content['owner'] || // dont allow to move accounts, as this mean deleting the user incl. all content he owns
|
||||
!$this->check_perms(EGW_ACL_DELETE,$content); // you need delete rights to move a contact into an other addressbook
|
||||
}
|
||||
for($i = -23; $i<=23; $i++) $tz[$i] = ($i > 0 ? '+' : '').$i;
|
||||
$sel_options['tz'] = $tz;
|
||||
$content['tz'] = $content['tz'] ? $content['tz'] : 0;
|
||||
foreach($this->content_types as $type => $data) $sel_options['tid'][$type] = $data['name'];
|
||||
|
||||
foreach($GLOBALS['egw']->acl->get_all_location_rights($GLOBALS['egw']->acl->account_id,'addressbook',true) as $id => $right)
|
||||
{
|
||||
if($id < 0) $sel_options['published_groups'][$id] = $GLOBALS['egw']->accounts->id2name($id);
|
||||
@ -168,10 +682,76 @@ class uicontacts extends bocontacts
|
||||
'to_app' => 'addressbook',
|
||||
'to_id' => $content['link_to']['to_id'],
|
||||
);
|
||||
$content['photo'] = $this->photo_src($content['id'],$content['jpegphoto'],'template');
|
||||
|
||||
if ($content['private']) $content['owner'] .= 'p';
|
||||
|
||||
$GLOBALS['egw_info']['flags']['include_xajax'] = true;
|
||||
|
||||
$this->tmpl->read($this->content_types[$content['tid']]['options']['template']);
|
||||
return $this->tmpl->exec('addressbook.uicontacts.edit',$content,$sel_options,$readonlys,$preserv, 2);
|
||||
return $this->tmpl->exec('addressbook.uicontacts.edit',$content,$sel_options,$readonlys,$content, 2);
|
||||
}
|
||||
|
||||
function ajax_setFileasOptions($n_prefix,$n_given,$n_middle,$n_family,$n_suffix,$org_name)
|
||||
{
|
||||
$names = array(
|
||||
'n_prefix' => $n_prefix,
|
||||
'n_given' => $n_given,
|
||||
'n_middle' => $n_middle,
|
||||
'n_family' => $n_family,
|
||||
'n_suffix' => $n_suffix,
|
||||
'org_name' => $org_name,
|
||||
);
|
||||
$response =& new xajaxResponse();
|
||||
$response->addScript("setOptions('".addslashes(implode("\b",$this->fileas_options($names)))."');");
|
||||
|
||||
return $response->getXML();
|
||||
}
|
||||
|
||||
/**
|
||||
* resizes the uploaded photo to 60*80 pixel and returns it
|
||||
*
|
||||
* @param array $file info uploaded file
|
||||
* @return string with resized jpeg photo
|
||||
*/
|
||||
function resize_photo($file)
|
||||
{
|
||||
switch($file['type'])
|
||||
{
|
||||
case 'image/gif':
|
||||
$upload = imagecreatefromgif($file['tmp_name']);
|
||||
break;
|
||||
case 'image/jpeg':
|
||||
case 'image/pjpeg':
|
||||
$upload = imagecreatefromjpeg($file['tmp_name']);
|
||||
break;
|
||||
case 'image/png':
|
||||
case 'image/x-png':
|
||||
$upload = imagecreatefrompng($file['tmp_name']);
|
||||
break;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
if (!$upload) return null;
|
||||
|
||||
list($src_w,$src_h) = getimagesize($file['tmp_name']);
|
||||
|
||||
// scale the image to a width of 60 and a height according to the proportion of the source image
|
||||
$photo = imagecreatetruecolor($dst_w = 60,$dst_h = round($src_h * 60 / $src_w));
|
||||
imagecopyresized($photo,$upload,0,0,0,0,$dst_w,$dst_h,$src_w,$src_h);
|
||||
//echo "<p>imagecopyresized(\$photo,\$upload,0,0,0,0,$dst_w,$dst_h,$src_w,$src_h);</p>\n";
|
||||
|
||||
ob_start();
|
||||
imagejpeg($photo,'',90);
|
||||
$jpeg = ob_get_contents();
|
||||
ob_end_clean();
|
||||
|
||||
imagedestroy($photo);
|
||||
imagedestroy($upload);
|
||||
|
||||
return $jpeg;
|
||||
}
|
||||
|
||||
function view($content=null)
|
||||
{
|
||||
if(is_array($content))
|
||||
@ -183,21 +763,21 @@ class uicontacts extends bocontacts
|
||||
$GLOBALS['egw']->redirect_link('/index.php','menuaction=addressbook.uivcard.out&ab_id=' .$content['id']);
|
||||
|
||||
case 'cancel':
|
||||
$GLOBALS['egw']->redirect_link('/index.php','menuaction=addressbook.uiaddressbook.index');
|
||||
$GLOBALS['egw']->redirect_link('/index.php','menuaction=addressbook.uicontacts.index');
|
||||
|
||||
case 'delete':
|
||||
$GLOBALS['egw']->redirect_link('/index.php',array(
|
||||
'menuaction' => 'addressbook.uiaddressbook.index',
|
||||
'menuaction' => 'addressbook.uicontacts.index',
|
||||
'msg' => $this->delete($content) ? lang('Something went wrong by deleting this contact') : lang('Contact deleted !!!'),
|
||||
));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!(int)$_GET['contact_id'] || !is_array($content = $this->read((int) $_GET['contact_id'])))
|
||||
if(!$_GET['contact_id'] || !is_array($content = $this->read($_GET['contact_id'])))
|
||||
{
|
||||
$GLOBALS['egw']->redirect_link('/index.php',array(
|
||||
'menuaction' => 'addressbook.uiaddressbook.index',
|
||||
'menuaction' => 'addressbook.uicontacts.index',
|
||||
'msg' => $content,
|
||||
));
|
||||
}
|
||||
@ -217,14 +797,12 @@ class uicontacts extends bocontacts
|
||||
'to_id' => $content['id'],
|
||||
);
|
||||
$readonlys['link_to'] = $readonlys['customfields'] = true;
|
||||
$readonlys['button[save]'] = $readonlys['button[apply]'] = true;
|
||||
$readonlys['button[save]'] = $readonlys['button[apply]'] = $readonlys['change_photo'] = true;
|
||||
$readonlys['button[delete]'] = !$this->check_perms(EGW_ACL_DELETE,$content);
|
||||
$readonlys['button[edit]'] = !$this->check_perms(EGW_ACL_EDIT,$content);
|
||||
|
||||
for($i = -23; $i<=23; $i++) $tz[$i] = ($i > 0 ? '+' : '').$i;
|
||||
$sel_options['tz'] = $tz;
|
||||
$content['tz'] = $content['tz'] ? $content['tz'] : 0;
|
||||
|
||||
$sel_options['fileas_type'][$content['fileas_type']] = $this->fileas($content);
|
||||
$sel_options['owner'] = $this->get_addressbooks();
|
||||
for($i = -23; $i<=23; $i++) $tz[$i] = ($i > 0 ? '+' : '').$i;
|
||||
$sel_options['tz'] = $tz;
|
||||
$content['tz'] = $content['tz'] ? $content['tz'] : 0;
|
||||
@ -247,7 +825,8 @@ class uicontacts extends bocontacts
|
||||
elseif ($url)
|
||||
{
|
||||
$content[$name.'_link'] = $url;
|
||||
$this->tmpl->set_cell_attribute($name,'size','b,@'.$name.'_link,,,_blank');
|
||||
$this->tmpl->set_cell_attribute($name,'size','b,@'.$name.'_link,,,_blank'.
|
||||
($GLOBALS['egw_info']['user']['apps']['felamimail']?',700x750':''));
|
||||
}
|
||||
$this->tmpl->set_cell_attribute($name,'type','label');
|
||||
$this->tmpl->set_cell_attribute($name,'no_lang',true);
|
||||
@ -375,6 +954,29 @@ class uicontacts extends bocontacts
|
||||
return $this->tmpl->exec('addressbook.uicontacts.search',$content,$sel_options,$readonlys,$preserv);
|
||||
}
|
||||
|
||||
function photo()
|
||||
{
|
||||
ob_start();
|
||||
$contact_id = isset($_GET['contact_id']) ? $_GET['contact_id'] :
|
||||
(isset($_GET['account_id']) ? 'account:'.$_GET['account_id'] : 0);
|
||||
|
||||
if (substr($contact_id,0,8) == 'account:')
|
||||
{
|
||||
$contact_id = $GLOBALS['egw']->accounts->id2name(substr($contact_id,8),'person_id');
|
||||
}
|
||||
if (!($contact = $this->read($contact_id)) || !$contact['jpegphoto'])
|
||||
{
|
||||
$GLOBALS['egw']->redirect($GLOBALS['egw']->common->image('addressbook','photo'));
|
||||
}
|
||||
if (!ob_get_contents())
|
||||
{
|
||||
header('Content-type: image/jpeg');
|
||||
header('Content-length: '.(extension_loaded(mbstring) ? mb_strlen($contact['jpeg_photo'],'ascii') : strlen($contact['jpeg_photo'])));
|
||||
echo $contact['jpegphoto'];
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
function js()
|
||||
{
|
||||
return '<script LANGUAGE="JavaScript">
|
||||
@ -418,6 +1020,29 @@ class uicontacts extends bocontacts
|
||||
}
|
||||
}
|
||||
|
||||
function setFileasOptions(input)
|
||||
{
|
||||
var prefix = document.getElementById("exec[n_prefix]").value;
|
||||
var given = document.getElementById("exec[n_given]").value;
|
||||
var middle = document.getElementById("exec[n_middle]").value;
|
||||
var family = document.getElementById("exec[n_family]").value;
|
||||
var suffix = document.getElementById("exec[n_suffix]").value;
|
||||
var org = document.getElementById("exec[org_name]").value;
|
||||
|
||||
xajax_doXMLHTTP("addressbook.uicontacts.ajax_setFileasOptions",prefix,given,middle,family,suffix,org);
|
||||
}
|
||||
|
||||
function setOptions(options_str)
|
||||
{
|
||||
var options = options_str.split("\\\\b");
|
||||
var selbox = document.getElementById("exec[fileas_type]");
|
||||
var i;
|
||||
for (i=0; i < options.length; i++)
|
||||
{
|
||||
selbox.options[i].text = options[i];
|
||||
}
|
||||
}
|
||||
|
||||
</script>';
|
||||
}
|
||||
}
|
||||
|
@ -1,19 +0,0 @@
|
||||
<?php
|
||||
/**************************************************************************\
|
||||
* eGroupWare *
|
||||
* http://www.egroupware.org *
|
||||
* Written by Joseph Engo <jengo@phpgroupware.org> *
|
||||
* -------------------------------------------- *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU General Public License as published by the *
|
||||
* Free Software Foundation; either version 2 of the License, or (at your *
|
||||
* option) any later version. *
|
||||
\**************************************************************************/
|
||||
|
||||
// $Id$
|
||||
|
||||
$GLOBALS['pref']->change('addressbook','company','addressbook_True');
|
||||
$GLOBALS['pref']->change('addressbook','lastname','addressbook_True');
|
||||
$GLOBALS['pref']->change('addressbook','firstname','addressbook_True');
|
||||
$GLOBALS['pref']->change('addressbook','default_category','');
|
||||
?>
|
@ -1,7 +0,0 @@
|
||||
<?php
|
||||
global $acl,$account_id;
|
||||
// Add default acl to allow the new user to access their
|
||||
// addressbook
|
||||
// This file is not really needed or used at this time
|
||||
$acl->add('addressbook','u_'.$account_id,1);
|
||||
?>
|
@ -1,25 +0,0 @@
|
||||
<?php
|
||||
/**************************************************************************\
|
||||
* eGroupWare *
|
||||
* http://www.egroupware.org *
|
||||
* Written by Joseph Engo <jengo@phpgroupware.org> *
|
||||
* -------------------------------------------- *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU General Public License as published by the *
|
||||
* Free Software Foundation; either version 2 of the License, or (at your *
|
||||
* option) any later version. *
|
||||
\**************************************************************************/
|
||||
|
||||
// $Id$
|
||||
// $Source$
|
||||
|
||||
// Only Modify the $file and $title variables.....
|
||||
$title = $appname;
|
||||
$file = Array(
|
||||
'Site Configuration' => $GLOBALS['egw']->link('/index.php','menuaction=admin.uiconfig.index&appname=' . $appname),
|
||||
'Edit custom fields' => $GLOBALS['egw']->link('/index.php','menuaction=admin.customfields.edit&appname='. $appname),
|
||||
'Global Categories' => $GLOBALS['egw']->link('/index.php','menuaction=admin.uicategories.index&appname=addressbook')
|
||||
);
|
||||
//Do not modify below this line
|
||||
display_section($appname,$title,$file);
|
||||
?>
|
@ -1,28 +0,0 @@
|
||||
<?php
|
||||
/**************************************************************************\
|
||||
* eGroupWare *
|
||||
* http://www.egroupware.org *
|
||||
* Written by Joseph Engo <jengo@phpgroupware.org> *
|
||||
* -------------------------------------------- *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU General Public License as published by the *
|
||||
* Free Software Foundation; either version 2 of the License, or (at your *
|
||||
* option) any later version. *
|
||||
\**************************************************************************/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
if((int)$GLOBALS['hook_values']['account_id'] > 0)
|
||||
{
|
||||
$contacts = CreateObject('phpgwapi.contacts');
|
||||
|
||||
if((int)$_POST['new_owner'] == 0)
|
||||
{
|
||||
$contacts->delete_all((int)$GLOBALS['hook_values']['account_id']);
|
||||
}
|
||||
else
|
||||
{
|
||||
$contacts->change_owner((int)$GLOBALS['hook_values']['account_id'],(int)$_POST['new_owner']);
|
||||
}
|
||||
}
|
||||
?>
|
@ -1,26 +0,0 @@
|
||||
<?php
|
||||
/**************************************************************************\
|
||||
* eGroupWare *
|
||||
* http://www.egroupware.org *
|
||||
* Written by Joseph Engo <jengo@phpgroupware.org> *
|
||||
* -------------------------------------------- *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU General Public License as published by the *
|
||||
* Free Software Foundation; either version 2 of the License, or (at your *
|
||||
* option) any later version. *
|
||||
\**************************************************************************/
|
||||
|
||||
/* $Id$ */
|
||||
{
|
||||
// Only Modify the $file and $title variables.....
|
||||
$title = $appname;
|
||||
$file = array();
|
||||
$file['Preferences'] = $GLOBALS['egw']->link('/index.php','menuaction=addressbook.uiaddressbook.preferences');
|
||||
if(!$GLOBALS['egw_info']['server']['deny_user_grants_access'])
|
||||
$file['Grant Access'] = $GLOBALS['egw']->link('/index.php','menuaction=preferences.uiaclprefs.index&acl_app='.$appname);
|
||||
$file['Edit Categories'] = $GLOBALS['egw']->link('/index.php','menuaction=preferences.uicategories.index&cats_app='.$appname . '&cats_level=True&global_cats=True');
|
||||
|
||||
//Do not modify below this line
|
||||
display_section($appname,$title,$file);
|
||||
}
|
||||
?>
|
@ -1,67 +0,0 @@
|
||||
<?php
|
||||
/**************************************************************************\
|
||||
* eGroupWare - Calendar's Sidebox-Menu for idots-template *
|
||||
* http://www.egroupware.org *
|
||||
* Written by Pim Snel <pim@lingewoud.nl> *
|
||||
* -------------------------------------------- *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU General Public License as published by the *
|
||||
* Free Software Foundation; either version 2 of the License, or (at your *
|
||||
* option) any later version. *
|
||||
\**************************************************************************/
|
||||
|
||||
/* $Id$ */
|
||||
{
|
||||
|
||||
/*
|
||||
This hookfile is for generating an app-specific side menu used in the idots
|
||||
template set.
|
||||
|
||||
$menu_title speaks for itself
|
||||
$file is the array with link to app functions
|
||||
|
||||
display_sidebox can be called as much as you like
|
||||
*/
|
||||
|
||||
$menu_title = $GLOBALS['egw_info']['apps'][$appname]['title'];
|
||||
|
||||
$file = Array(
|
||||
array(
|
||||
'text' => '<a class="textSidebox" href="'.$GLOBALS['egw']->link('/index.php',array('menuaction' => 'addressbook.uicontacts.edit')).
|
||||
'" onclick="window.open(this.href,\'_blank\',\'dependent=yes,width=850,height=440,scrollbars=yes,status=yes\');
|
||||
return false;">'.lang('Add').'</a>',
|
||||
'no_lang' => true,
|
||||
'link' => false
|
||||
),
|
||||
// 'Add'=>$GLOBALS['egw']->link('/index.php','menuaction=addressbook.uiaddressbook.add'),
|
||||
'Advanced search'=>$GLOBALS['egw']->link('/index.php','menuaction=addressbook.uicontacts.search'),
|
||||
'_NewLine_', // give a newline
|
||||
'import contacts' => $GLOBALS['egw']->link('/index.php','menuaction=addressbook.uiXport.import'),
|
||||
'export contacts' => $GLOBALS['egw']->link('/index.php','menuaction=addressbook.uiXport.export')
|
||||
);
|
||||
display_sidebox($appname,$menu_title,$file);
|
||||
|
||||
if($GLOBALS['egw_info']['user']['apps']['preferences'])
|
||||
{
|
||||
$menu_title = lang('Preferences');
|
||||
$file = array();
|
||||
$file['Addressbook preferences'] = $GLOBALS['egw']->link('/index.php','menuaction=addressbook.uiaddressbook.preferences');
|
||||
if(!$GLOBALS['egw_info']['server']['deny_user_grants_access'])
|
||||
$file['Grant Access'] = $GLOBALS['egw']->link('/index.php','menuaction=preferences.uiaclprefs.index&acl_app=addressbook');
|
||||
$file['Edit Categories'] = $GLOBALS['egw']->link('/index.php','menuaction=preferences.uicategories.index&cats_app=addressbook&cats_level=True&global_cats=True');
|
||||
|
||||
display_sidebox($appname,$menu_title,$file);
|
||||
}
|
||||
|
||||
if ($GLOBALS['egw_info']['user']['apps']['admin'])
|
||||
{
|
||||
$menu_title = lang('Administration');
|
||||
$file = Array(
|
||||
'Configuration'=>$GLOBALS['egw']->link('/index.php','menuaction=admin.uiconfig.index&appname=addressbook'),
|
||||
'Custom Fields'=>$GLOBALS['egw']->link('/index.php','menuaction=admin.customfields.edit&appname=addressbook'),
|
||||
'Global Categories' =>$GLOBALS['egw']->link('/index.php','menuaction=admin.uicategories.index&appname=addressbook')
|
||||
);
|
||||
display_sidebox($appname,$menu_title,$file);
|
||||
}
|
||||
}
|
||||
?>
|
@ -11,16 +11,14 @@
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
$GLOBALS['egw_info'] = array();
|
||||
$GLOBALS['egw_info']['flags'] = array(
|
||||
'currentapp' => 'addressbook',
|
||||
'noheader' => True,
|
||||
'nonavbar' => True
|
||||
);
|
||||
$GLOBALS['egw_info'] = array(
|
||||
'flags' => array(
|
||||
'currentapp' => 'addressbook',
|
||||
'noheader' => True,
|
||||
'nonavbar' => True
|
||||
));
|
||||
include('../header.inc.php');
|
||||
|
||||
$obj = CreateObject('addressbook.uiaddressbook');
|
||||
$obj->index();
|
||||
ExecMethod('addressbook.uicontacts.index');
|
||||
|
||||
$GLOBALS['phpgw']->common->phpgw_footer();
|
||||
?>
|
||||
$GLOBALS['egw']->common->egw_footer();
|
||||
|
@ -1,35 +1,40 @@
|
||||
%1 contact(s) %2 addressbook de %1 Kontakt(e) %2
|
||||
%1 contact(s) %2, %3 failed because of insufficent rights !!! addressbook de %1 Kontakt(e) %2, %3 nicht wegen fehlender Rechte !!!
|
||||
%1 records imported addressbook de %1 Datensätze importiert
|
||||
%1 records read (not yet imported, you may go %2back%3 and uncheck test import) addressbook de %1 Datensätze gelesen (noch nicht importiert, sie können %2zurück%3 gehen und Test-Import auschalten)
|
||||
%1 starts with '%2' addressbook de %1 beginnt mit '%2'
|
||||
(e.g. 1969) addressbook de (z.B. 1966)
|
||||
<b>no conversion type <none> could be located.</b> please choose a conversion type from the list addressbook de <b>Kein Übersetzungstyp <none> konnte gefunden werden.</b> Bitte wählen Sie einen Übersetzungstyp aus der Liste
|
||||
@-eval() is only availible to admins!!! addressbook de @-eval() ist nur verfügbar für Administratoren!!!
|
||||
actions addressbook de Befehle
|
||||
add a new contact addressbook de Neuen Kontakt anlegen
|
||||
add a single entry by passing the fields. addressbook de Hinzufügen eines einzelnen Eintrags durch Übergeben der Felder.
|
||||
add custom field addressbook de Benutzerdefiniertes Feld hinzufügen
|
||||
address book common de Adressbuch
|
||||
address book - vcard in addressbook de Adressbuch - VCard in
|
||||
address book - view addressbook de Adressbuch - Anzeigen
|
||||
address line 2 addressbook de Adresszeile 2
|
||||
address line 3 addressbook de Adresszeile 3
|
||||
address type addressbook de Adresstyp
|
||||
addressbook common de Adressbuch
|
||||
addressbook preferences addressbook de Adressbuch Einstellungen
|
||||
addressbook the contact should be saved to addressbook de Adressbuch in das der Kontakt gespeichert werden soll
|
||||
addressbook-fieldname addressbook de Adressbuch Feldname
|
||||
addvcard addressbook de VCard hinzufügen
|
||||
advanced search addressbook de Erweiterte Suche
|
||||
alt. csv import addressbook de Alt. CSV Import
|
||||
always addressbook de immer
|
||||
apply the action on the whole selection, not only the shown contacts!!! addressbook de Wendet den Befehl auf die gesamte Selektion an, NICHT nur auf die angezeigten Kontakte!!!
|
||||
are you shure you want to delete this contact? addressbook de Diesen Kontakt löschen?
|
||||
are you sure you want to delete this field? addressbook de Sind Sie sicher, dass Sie dieses Feld löschen wollen?
|
||||
bbs phone addressbook de BBS
|
||||
assistent addressbook de Assistent
|
||||
birthday common de Geburtstag
|
||||
birthdays common de Geburtstage
|
||||
blank addressbook de Leer
|
||||
business common de Geschäftlich
|
||||
business address type addressbook de Typ der geschäftl. Adresse
|
||||
business address addressbook de Geschäftsadresse
|
||||
business city addressbook de Stadt geschäftl.
|
||||
business country addressbook de Land geschäftl.
|
||||
business email addressbook de E-Mail geschäftl.
|
||||
business email type addressbook de Typ der geschäftl. E-Mail
|
||||
business fax addressbook de Fax geschäftl.
|
||||
business phone addressbook de Tel. geschäftl.
|
||||
business state addressbook de Bundesland geschäftl.
|
||||
@ -38,11 +43,11 @@ business zip code addressbook de PLZ gesch
|
||||
car phone addressbook de Autotelefon
|
||||
cell phone addressbook de Mobiltelefon
|
||||
charset of file addressbook de Zeichensatz der Datei
|
||||
choose an icon for this contact type addressbook de Wählen Sie ein Icon für diesen Adresstyp
|
||||
chosse an etemplate for this contact type addressbook de Wählen Sie ein eTemplate für diesen Addresstyp
|
||||
check all addressbook de Alle auswählen
|
||||
choose an icon for this contact type admin de Wählen Sie ein Icon für diesen Kontakt Typ
|
||||
chosse an etemplate for this contact type admin de Wählen Sie ein eTemplate für diesen Kontakt Typ
|
||||
city common de Stadt
|
||||
company common de Firma
|
||||
company name common de Firmenname
|
||||
configuration common de Konfiguration
|
||||
contact common de Kontakt
|
||||
contact application admin de Kontakt Anwendung
|
||||
@ -51,6 +56,7 @@ contact settings admin de Kontakt Einstellungen
|
||||
copied by %1, from record #%2. addressbook de Kopiert von %1, vom Datensatz Nr. %2.
|
||||
country common de Land
|
||||
create new links addressbook de Neue Verknüpfung erstellen
|
||||
created addressbook de Angelegt von
|
||||
credit addressbook de Darlehen
|
||||
csv-fieldname addressbook de CSV-Feldname
|
||||
csv-filename addressbook de CSV-Dateiname
|
||||
@ -59,7 +65,12 @@ custom fields addressbook de Benutzerdefinierte Felder
|
||||
debug output in browser addressbook de Debugausgaben in Browser
|
||||
default filter addressbook de Standardfilter
|
||||
delete a single entry by passing the id. addressbook de Löscht einen einzelnen Eintrag durch Übergabe seiner ID.
|
||||
delete this contact addressbook de Diesen Kontakt löschen
|
||||
deleted addressbook de gelöscht
|
||||
deletes the photo addressbook de Löscht das Foto
|
||||
department common de Abteilung
|
||||
displays a remider for birthdays happening today or tomorrow on the startpage (page you get when you enter egroupware or click on the homepage icon). addressbook de Zeigt auf der Startseite eine Geburtstags Erinnerung an, falls heute oder morgen jemand Geburtstag hat. Die Startseite ist die Seite die Sie sehen, wenn Sie eGroupWare betreten oder auf das Startseiten Icon (Haus) klicken.
|
||||
do you want a private addressbook, which can not be viewed by users, you grant access to your personal addressbook? addressbook de Wollen Sie ein privates Adressbuch, dass nicht von Benutzern einsehbar ist, denen Sie Zugriff auf Ihr persönliches Adressbuch gegeben haben?
|
||||
do your really want to delete this contact? addressbook de Wollen sie diesen Kontakt wirklich löschen?
|
||||
doesn't matter addressbook de egal
|
||||
domestic addressbook de Wohnung
|
||||
@ -71,12 +82,15 @@ edit custom fields admin de Benutzerdefinierte Felder bearbeiten
|
||||
edit phonenumbers - addressbook de Telefonnummern bearbeiten
|
||||
email & internet addressbook de Email & Internet
|
||||
empty for all addressbook de leer für alle
|
||||
enable an extra private addressbook addressbook de Privates Adressbuch einschalten
|
||||
enter the path to the exported file here addressbook de Bitte geben Sie den Pfad für die exportierte Datei an
|
||||
existing links addressbook de Bestehende Verknüpfungen
|
||||
export addressbook de Export
|
||||
export as vcard addressbook de VCard exportieren
|
||||
export contacts addressbook de Kontakte exportieren
|
||||
export file name addressbook de Dateiname zum Exportieren
|
||||
export from addressbook addressbook de Export vom Adressbuch
|
||||
exported addressbook de exportiert
|
||||
extra addressbook de Extra
|
||||
fax addressbook de Telefax
|
||||
fax number common de Telefaxnummer
|
||||
@ -89,11 +103,11 @@ full name addressbook de vollst
|
||||
geo addressbook de GEO
|
||||
global categories addressbook de Globale Kategorien
|
||||
grant addressbook access common de Berechtigungen
|
||||
home address type addressbook de Typ der Privatadresse
|
||||
group %1 addressbook de Gruppe %1
|
||||
home address addressbook de Privatadresse
|
||||
home city addressbook de Stadt privat
|
||||
home country addressbook de Land privat
|
||||
home email addressbook de E-Mail privat
|
||||
home email type addressbook de Typ der privaten E-Mail
|
||||
home phone addressbook de Tel. privat
|
||||
home state addressbook de Bundesland privat
|
||||
home street addressbook de Straße privat
|
||||
@ -111,7 +125,6 @@ import next set addressbook de N
|
||||
import_instructions addressbook de In Netscape, öffnen Sie das Adressbuch und wählen Sie <b>Exportieren</b> aus dem Datei Menü aus. Die Dateien werden im LDIF Formaz exportiert.<p> In Outlook wählen Sie den Ordner Kontakte aus, wählen Sie <b>Importieren und Exportieren...</p> aus dem <b>Datei</b> Menü aus und Exportieren Sie die Kontakte als eine CSV Datei.<p> In Palm Desktop 4.0 oder größer, öffnen Sie Ihr Adressbuch und wählen Sie <b>Export</b> aus dem Datei-Menü aus. Die Datei wird im VCard-Format exportiert.
|
||||
income addressbook de Einkommen
|
||||
international addressbook de International
|
||||
isdn phone addressbook de ISDN-Tel.
|
||||
label addressbook de Adressetikett
|
||||
last modified addressbook de Letzte Änderung
|
||||
ldap context for contacts admin de LDAP-Kontext für Kontakte
|
||||
@ -131,11 +144,13 @@ mobile addressbook de Mobil
|
||||
mobile phone addressbook de Mobiltelefon
|
||||
modem phone addressbook de Modem
|
||||
more ... addressbook de Mehr ...
|
||||
moved addressbook de verschoben
|
||||
multiple vcard addressbook de Mehrere VCards
|
||||
no vcard addressbook de Keine VCard
|
||||
number addressbook de Nummer
|
||||
number of records to read (%1) addressbook de Anzahl der einzulesenden Datensätze (%1)
|
||||
options for type addressbook de Optionen für Typ
|
||||
only if there is content addressbook de nur wenn etwas angezeigt wird
|
||||
options for type admin de Optionen für Typ
|
||||
organisation addressbook de Organisation
|
||||
other number addressbook de andere Nr.
|
||||
other phone addressbook de anderes Telefon
|
||||
@ -143,7 +158,9 @@ pager common de Pager
|
||||
parcel addressbook de Lieferadresse
|
||||
phone number common de Telefonnummer
|
||||
phone numbers common de Telefonnummern
|
||||
photo addressbook de Foto
|
||||
please enter a name for that field ! addressbook de Bitte geben sie einen Namen für das Feld an!
|
||||
please select only one category addressbook de Bitte nur eine Kategorie auswählen
|
||||
postal common de Postanschrift
|
||||
pref addressbook de präf
|
||||
prefix addressbook de Anrede
|
||||
@ -154,12 +171,18 @@ read a list of entries. addressbook de Liest eine Liste von Eintr
|
||||
read a single entry by passing the id and fieldlist. addressbook de Liest einen einzelnen Eintrag über seine ID und Feldliste.
|
||||
record access addressbook de Zugriffsrechte
|
||||
record owner addressbook de Datensatzeigentümer
|
||||
retrieve contacts admin de Kontakte laden
|
||||
role addressbook de Funktion
|
||||
room addressbook de Raum
|
||||
search for '%1' addressbook de Suche nach '%1'
|
||||
select a portrait format jpeg photo. it will be resized to 60 pixel width. addressbook de Wählen Sie ein hochformatiges jpeg Foto. Es wird 60 Pixel breit skaliert.
|
||||
select addressbook type addressbook de Typ des Adressbuchs auswählen
|
||||
select all addressbook de Alles auswählen
|
||||
select an action or addressbook to move to addressbook de Befehl oder Adressbuch zum Verschieben auswählen
|
||||
select the type of conversion addressbook de Typ der Umwandlung auswählen
|
||||
select the type of conversion: addressbook de Typ der Umwandlung auswählen:
|
||||
select where you want to store admin de Auswählen wo Sie speichern wollen
|
||||
select where you want to store / retrieve contacts admin de Auswählen wo Sie Adressen speichern wollen
|
||||
show addressbook de Anzeigen
|
||||
show a column for %1 addressbook de Zeige eine %1 Spalte
|
||||
show birthday reminders on main screen addressbook de Geburtstagserinnerungen auf der Startseite anzeigen
|
||||
something went wrong by deleting %1 addressbook de Beim Löschen von %1 trat ein Fehler auf
|
||||
something went wrong by deleting this contact addressbook de Beim Löschen dieses Kontaktes trat ein Fehler auf
|
||||
@ -175,25 +198,29 @@ test import (show importable records <u>only</u> in browser) addressbook de Test
|
||||
that field name has been used already ! addressbook de Dieser Feldname wird bereits benutzt!
|
||||
this person's first name was not in the address book. addressbook de Der Vorname dieser Person ist nicht im Adressbuch.
|
||||
this person's last name was not in the address book. addressbook de Der Nachname dieser Person ist nicht im Adressbuch.
|
||||
timezone addressbook de Zeitzone
|
||||
to many might exceed your execution-time-limit addressbook de zu viel können ihre Laufzeitbeschränkung überschreiten
|
||||
today is %1's birthday! common de Heute ist der Geburtstag von %1!
|
||||
tomorrow is %1's birthday. common de Morgen ist der Geburtstag von %1.
|
||||
translation addressbook de Übersetzung
|
||||
update a single entry by passing the fields. addressbook de Aktualisiert einen einzelnen Eintrag durch Übergabe seiner Felder.
|
||||
upload or delete the photo addressbook de Foto hochladen oder löschen
|
||||
use country list addressbook de Länderliste benutzen
|
||||
vcard common de VCard
|
||||
vcards require a first name entry. addressbook de VCards benötigen einen Vornamen.
|
||||
vcards require a last name entry. addressbook de VCards benötigen einen Nachnamen.
|
||||
video phone addressbook de Bildtelefon
|
||||
voice phone addressbook de Telefon
|
||||
warning!! ldap is valid only if you are not using contacts for accounts storage! admin de WARNUNG!! LDAP darf nur verwendet werden, wenn sie die Benutzerkonten nicht im Adressbuch speichern!
|
||||
warning: all contacts found will be deleted! addressbook de WARNUNG: Alle gefundenen Kontakte werden gelöscht!
|
||||
when should the contacts list display that colum. "only if there is content" hides the column, unless there is some content in the view. addressbook de Wann soll die Adressliste diese Spalte anzeigen. "Nur wenn etwas angezeigt wird" blendet die Spalte aus, wenn Sie in dieser Anzeige leer wäre.
|
||||
whole selection addressbook de gesamte Selektion
|
||||
work phone addressbook de Tel dienstl.
|
||||
write (update or add) a single entry by passing the fields. addressbook de Schreibt (aktualiseren oder zufügen) eines einzelnen Eintrags durch Übergabe der Felder
|
||||
you are not permitted to delete contact %1 addressbook de Sie haben nicht die Berechtigungen um den Kontakt %1 zu löschen
|
||||
you are not permittet to delete this contact addressbook de Sie haben nicht die Berechtigung diesen Kontakt zu löschen
|
||||
you are not permittet to edit this contact addressbook de Sie haben nicht die Berechtigung diesen Kontakt zu bearbeiten
|
||||
you are not permittet to view this contact addressbook de Sie haben nicht die Berechtigung diesen Kontakt zu betrachen
|
||||
you must select a vcard. (*.vcf) addressbook de Sie müssen eine VCard auswählen (*.vcf)
|
||||
you must select at least 1 column to display addressbook de Sie müssen mindestens eine Spalte zum Anzeigen auswählen
|
||||
you need to select some contacts first addressbook de Sie müssen zuerst Kontakte auswählen
|
||||
zip code common de PLZ
|
||||
zip_note addressbook de <p><b>Notiz:</b>Die Datei kann ein zip Archiv sein, bestehend aus .csv, .vcf oder .ldif Dateien. Sie dürfen die Dateitypen pro Import nicht mischen!
|
||||
|
@ -1,35 +1,40 @@
|
||||
%1 contact(s) %2 addressbook en %1 contact(s) %2
|
||||
%1 contact(s) %2, %3 failed because of insufficent rights !!! addressbook en %1 contact(s) %2, %3 failed because of insufficent rights !!!
|
||||
%1 records imported addressbook en %1 records imported
|
||||
%1 records read (not yet imported, you may go %2back%3 and uncheck test import) addressbook en %1 records read (not yet imported, you may go %2back%3 and uncheck Test Import)
|
||||
%1 starts with '%2' addressbook en %1 starts with '%2'
|
||||
(e.g. 1969) addressbook en (e.g. 1969)
|
||||
<b>no conversion type <none> could be located.</b> please choose a conversion type from the list addressbook en <b>No conversion type <none> could be located.</b> Please choose a conversion type from the list
|
||||
@-eval() is only availible to admins!!! addressbook en @-eval() is only availible to admins!!!
|
||||
actions addressbook en Actions
|
||||
add a new contact addressbook en Add a new contact
|
||||
add a single entry by passing the fields. addressbook en Add a single entry by passing the fields.
|
||||
add custom field addressbook en Add Custom Field
|
||||
address book common en Address Book
|
||||
address book - vcard in addressbook en Address book - VCard in
|
||||
address book - view addressbook en Address book - view
|
||||
address line 2 addressbook en Address Line 2
|
||||
address line 3 addressbook en Address Line 3
|
||||
address type addressbook en Address Type
|
||||
addressbook common en Addressbook
|
||||
addressbook preferences addressbook en Addressbook preferences
|
||||
addressbook the contact should be saved to addressbook en Addressbook the contact should be saved to
|
||||
addressbook-fieldname addressbook en Addressbook-Fieldname
|
||||
addvcard addressbook en Add VCard
|
||||
advanced search addressbook en Advanced search
|
||||
alt. csv import addressbook en Alt. CSV Import
|
||||
always addressbook en always
|
||||
apply the action on the whole selection, not only the shown contacts!!! addressbook en Apply the action on the whole selection, NOT only the shown contacts!!!
|
||||
are you shure you want to delete this contact? addressbook en Are you shure you want to delete this contact?
|
||||
are you sure you want to delete this field? addressbook en Are you sure you want to delete this field?
|
||||
bbs phone addressbook en BBS Phone
|
||||
assistent addressbook en Assistent
|
||||
birthday common en Birthday
|
||||
birthdays common en Birthdays
|
||||
blank addressbook en Blank
|
||||
business common en Business
|
||||
business address type addressbook en Business Address Type
|
||||
business address addressbook en Business address
|
||||
business city addressbook en Business City
|
||||
business country addressbook en Business Country
|
||||
business email addressbook en Business EMail
|
||||
business email type addressbook en Business EMail Type
|
||||
business fax addressbook en Business Fax
|
||||
business phone addressbook en Business Phone
|
||||
business state addressbook en Business State
|
||||
@ -38,11 +43,11 @@ business zip code addressbook en Business Postal Code
|
||||
car phone addressbook en Car Phone
|
||||
cell phone addressbook en Mobile phone
|
||||
charset of file addressbook en Charset of file
|
||||
choose an icon for this contact type addressbook en Choose an icon for this contact type
|
||||
chosse an etemplate for this contact type addressbook en Chosse an eTemplate for this contact type
|
||||
check all addressbook en Check all
|
||||
choose an icon for this contact type admin en Choose an icon for this contact type
|
||||
chosse an etemplate for this contact type admin en Chosse an eTemplate for this contact type
|
||||
city common en City
|
||||
company common en Company
|
||||
company name common en Company Name
|
||||
configuration common en Configuration
|
||||
contact common en Contact
|
||||
contact application admin en Contact application
|
||||
@ -51,6 +56,7 @@ contact settings admin en Contact Settings
|
||||
copied by %1, from record #%2. addressbook en Copied by %1, from record #%2.
|
||||
country common en Country
|
||||
create new links addressbook en Create new links
|
||||
created addressbook en Created
|
||||
credit addressbook en Credit
|
||||
csv-fieldname addressbook en CSV-Fieldname
|
||||
csv-filename addressbook en CSV-Filename
|
||||
@ -59,7 +65,12 @@ custom fields addressbook en Custom Fields
|
||||
debug output in browser addressbook en Debug output in browser
|
||||
default filter addressbook en Default Filter
|
||||
delete a single entry by passing the id. addressbook en Delete a single entry by passing the id.
|
||||
delete this contact addressbook en Delete this contact
|
||||
deleted addressbook en deleted
|
||||
deletes the photo addressbook en Deletes the photo
|
||||
department common en Department
|
||||
displays a remider for birthdays happening today or tomorrow on the startpage (page you get when you enter egroupware or click on the homepage icon). addressbook en Displays a remider for birthdays happening today or tomorrow on the startpage (page you get when you enter eGroupWare or click on the homepage icon).
|
||||
do you want a private addressbook, which can not be viewed by users, you grant access to your personal addressbook? addressbook en Do you want a private addressbook, which can not be viewed by users, you grant access to your personal addressbook?
|
||||
do your really want to delete this contact? addressbook en Do your really want to delete this contact?
|
||||
doesn't matter addressbook en doesn't matter
|
||||
domestic addressbook en Domestic
|
||||
@ -71,12 +82,15 @@ edit custom fields admin en Edit Custom Fields
|
||||
edit phonenumbers - addressbook en Edit Phonenumbers -
|
||||
email & internet addressbook en Email & Internet
|
||||
empty for all addressbook en empty for all
|
||||
enable an extra private addressbook addressbook en Enable an extra private addressbook
|
||||
enter the path to the exported file here addressbook en Enter the path to the exported file here
|
||||
existing links addressbook en Existing links
|
||||
export addressbook en export
|
||||
export as vcard addressbook en Export as VCard
|
||||
export contacts addressbook en Export Contacts
|
||||
export file name addressbook en Export file name
|
||||
export from addressbook addressbook en Export from Addressbook
|
||||
exported addressbook en exported
|
||||
extra addressbook en Extra
|
||||
fax addressbook en Fax
|
||||
fax number common en Fax Number
|
||||
@ -89,11 +103,11 @@ full name addressbook en Full Name
|
||||
geo addressbook en GEO
|
||||
global categories addressbook en Global Categories
|
||||
grant addressbook access common en Grant Addressbook Access
|
||||
home address type addressbook en Home Address Type
|
||||
group %1 addressbook en Group %1
|
||||
home address addressbook en Home address
|
||||
home city addressbook en Home City
|
||||
home country addressbook en Home Country
|
||||
home email addressbook en Home EMail
|
||||
home email type addressbook en Home EMail Type
|
||||
home phone addressbook en Home Phone
|
||||
home state addressbook en Home State
|
||||
home street addressbook en Home Street
|
||||
@ -111,7 +125,6 @@ import next set addressbook en Import next set
|
||||
import_instructions addressbook en In Netscape, open the Addressbook and select <b>Export</b> from the <b>File</b> menu. The file exported will be in LDIF format.<p>Or, in Outlook, select your Contacts folder, select <b>Import and Export...</b> from the <b>File</b> menu and export your contacts into a comma separated text (CSV) file. <p>Or, in Palm Desktop 4.0 or greater, visit your addressbook and select <b>Export</b> from the <b>File</b> menu. The file exported will be in VCard format.
|
||||
income addressbook en Income
|
||||
international addressbook en International
|
||||
isdn phone addressbook en ISDN Phone
|
||||
label addressbook en Label
|
||||
last modified addressbook en last modified
|
||||
ldap context for contacts admin en LDAP context for contacts
|
||||
@ -131,11 +144,13 @@ mobile addressbook en Mobile
|
||||
mobile phone addressbook en Mobile Phone
|
||||
modem phone addressbook en Modem Phone
|
||||
more ... addressbook en More ...
|
||||
moved addressbook en moved
|
||||
multiple vcard addressbook en Multiple VCard
|
||||
no vcard addressbook en No VCard
|
||||
number addressbook en Number
|
||||
number of records to read (%1) addressbook en Number of records to read (%1)
|
||||
options for type addressbook en Options for type
|
||||
only if there is content addressbook en only if there is content
|
||||
options for type admin en Options for type
|
||||
organisation addressbook en organisation
|
||||
other number addressbook en Other Number
|
||||
other phone addressbook en Other Phone
|
||||
@ -143,7 +158,9 @@ pager common en Pager
|
||||
parcel addressbook en Parcel
|
||||
phone number common en Phone Number
|
||||
phone numbers common en Phone Numbers
|
||||
photo addressbook en Photo
|
||||
please enter a name for that field ! addressbook en Please enter a name for that field !
|
||||
please select only one category addressbook en Please select only one category
|
||||
postal common en Postal
|
||||
pref addressbook en pref
|
||||
prefix addressbook en Prefix
|
||||
@ -154,12 +171,18 @@ read a list of entries. addressbook en Read a list of entries.
|
||||
read a single entry by passing the id and fieldlist. addressbook en Read a single entry by passing the id and fieldlist.
|
||||
record access addressbook en Record Access
|
||||
record owner addressbook en Record owner
|
||||
retrieve contacts admin en retrieve contacts
|
||||
role addressbook en Role
|
||||
room addressbook en Room
|
||||
search for '%1' addressbook en Search for '%1'
|
||||
select a portrait format jpeg photo. it will be resized to 60 pixel width. addressbook en Select a portrait format jpeg photo. It will be resized to 60 pixel width.
|
||||
select addressbook type addressbook en Select addressbook type
|
||||
select all addressbook en Select all
|
||||
select an action or addressbook to move to addressbook en Select an action or addressbook to move to
|
||||
select the type of conversion addressbook en Select the type of conversion
|
||||
select the type of conversion: addressbook en Select the type of conversion:
|
||||
select where you want to store admin en Select where you want to store
|
||||
select where you want to store / retrieve contacts admin en Select where you want to store / retrieve contacts
|
||||
show addressbook en Show
|
||||
show a column for %1 addressbook en Show a column for %1
|
||||
show birthday reminders on main screen addressbook en Show birthday reminders on main screen
|
||||
something went wrong by deleting %1 addressbook en Something went wrong by deleting %1
|
||||
something went wrong by deleting this contact addressbook en Something went wrong by deleting this contact
|
||||
@ -175,19 +198,21 @@ test import (show importable records <u>only</u> in browser) addressbook en Test
|
||||
that field name has been used already ! addressbook en That field name has been used already !
|
||||
this person's first name was not in the address book. addressbook en This person's first name was not in the address book.
|
||||
this person's last name was not in the address book. addressbook en This person's last name was not in the address book.
|
||||
timezone addressbook en Timezone
|
||||
to many might exceed your execution-time-limit addressbook en to many might exceed your execution-time-limit
|
||||
today is %1's birthday! common en Today is %1's birthday!
|
||||
tomorrow is %1's birthday. common en Tomorrow is %1's birthday.
|
||||
translation addressbook en Translation
|
||||
update a single entry by passing the fields. addressbook en Update a single entry by passing the fields.
|
||||
upload or delete the photo addressbook en Upload or delete the photo
|
||||
use country list addressbook en Use Country List
|
||||
vcard common en VCard
|
||||
vcards require a first name entry. addressbook en VCards require a first name entry.
|
||||
vcards require a last name entry. addressbook en Vcards require a last name entry.
|
||||
video phone addressbook en Video Phone
|
||||
voice phone addressbook en Voice Phone
|
||||
warning!! ldap is valid only if you are not using contacts for accounts storage! admin en WARNING!! LDAP is valid only if you are NOT using contacts for accounts storage!
|
||||
warning: all contacts found will be deleted! addressbook en WARNING: All contacts found will be deleted!
|
||||
when should the contacts list display that colum. "only if there is content" hides the column, unless there is some content in the view. addressbook en When should the contacts list display that colum. "Only if there is content" hides the column, unless there is some content in the view.
|
||||
whole selection addressbook en whole selection
|
||||
work phone addressbook en Work Phone
|
||||
write (update or add) a single entry by passing the fields. addressbook en Write (update or add) a single entry by passing the fields.
|
||||
you are not permitted to delete contact %1 addressbook en You are not permitted to delete contact %1
|
||||
@ -196,5 +221,6 @@ you are not permittet to edit this contact addressbook en You are not permittet
|
||||
you are not permittet to view this contact addressbook en you are not permittet to view this contact
|
||||
you must select a vcard. (*.vcf) addressbook en You must select a vcard. (*.vcf)
|
||||
you must select at least 1 column to display addressbook en You must select at least 1 column to display
|
||||
you need to select some contacts first addressbook en You need to select some contacts first
|
||||
zip code common en ZIP Code
|
||||
zip_note addressbook en <p><b>Note:</b> The file may be a zip file collection of .csv, .vcf, or .ldif files. However, do not mix file types per import.
|
||||
|
@ -2,7 +2,7 @@
|
||||
/**************************************************************************\
|
||||
* eGroupWare - Addressbook *
|
||||
* http://www.egroupware.org *
|
||||
* -------------------------------------------- *
|
||||
* ------------------------------------------------------------------------ *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU General Public License as published by the *
|
||||
* Free Software Foundation; either version 2 of the License, or (at your *
|
||||
@ -14,11 +14,11 @@
|
||||
/* Basic information about this app */
|
||||
$setup_info['addressbook']['name'] = 'addressbook';
|
||||
$setup_info['addressbook']['title'] = 'Addressbook';
|
||||
$setup_info['addressbook']['version'] = '1.2';
|
||||
$setup_info['addressbook']['version'] = '1.3.001';
|
||||
$setup_info['addressbook']['app_order'] = 4;
|
||||
$setup_info['addressbook']['enable'] = 1;
|
||||
|
||||
$setup_info['addressbook']['author'] = 'Joseph Engo, Miles Lott';
|
||||
$setup_info['addressbook']['author'] = 'Ralf Becker, Cornelius Weiss, Lars Kneschke';
|
||||
$setup_info['addressbook']['note'] = 'The phpgwapi manages contact data. Addressbook manages servers for its remote capability.';
|
||||
$setup_info['addressbook']['license'] = 'GPL';
|
||||
$setup_info['addressbook']['description'] =
|
||||
@ -33,17 +33,21 @@
|
||||
$setup_info['addressbook']['maintainer'] = 'eGroupWare coreteam';
|
||||
$setup_info['addressbook']['maintainer_email'] = 'egroupware-developers@lists.sourceforge.net';
|
||||
|
||||
$setup_info['addressbook']['tables'][] = 'egw_addressbook';
|
||||
$setup_info['addressbook']['tables'][] = 'egw_addressbook_extra';
|
||||
|
||||
/* The hooks this app includes, needed for hooks registration */
|
||||
$setup_info['addressbook']['hooks'][] = 'admin';
|
||||
$setup_info['addressbook']['hooks'][] = 'add_def_pref';
|
||||
$setup_info['addressbook']['hooks']['admin'] = 'addressbook.contacts_admin_prefs.all_hooks';
|
||||
$setup_info['addressbook']['hooks']['preferences'] = 'addressbook.contacts_admin_prefs.all_hooks';
|
||||
$setup_info['addressbook']['hooks']['sidebox_menu'] = 'addressbook.contacts_admin_prefs.all_hooks';
|
||||
$setup_info['addressbook']['hooks']['settings'] = 'addressbook.contacts_admin_prefs.settings';
|
||||
$setup_info['addressbook']['hooks'][] = 'config_validate';
|
||||
$setup_info['addressbook']['hooks'][] = 'home';
|
||||
$setup_info['addressbook']['hooks'][] = 'addaccount';
|
||||
$setup_info['addressbook']['hooks'][] = 'editaccount';
|
||||
$setup_info['addressbook']['hooks'][] = 'deleteaccount';
|
||||
$setup_info['addressbook']['hooks']['editaccount'] = 'addressbook.bocontacts.editaccount';
|
||||
$setup_info['addressbook']['hooks']['deleteaccount'] = 'addressbook.bocontacts.deleteaccount';
|
||||
$setup_info['addressbook']['hooks'][] = 'notifywindow';
|
||||
$setup_info['addressbook']['hooks'][] = 'sidebox_menu';
|
||||
$setup_info['addressbook']['hooks'][] = 'preferences';
|
||||
$setup_info['addressbook']['hooks']['search_link'] = 'addressbook.bocontacts.search_link';
|
||||
$setup_info['addressbook']['hooks']['edit_user'] = 'addressbook.contacts_admin_prefs.edit_user';
|
||||
|
||||
/* Dependencies for this app to work */
|
||||
$setup_info['addressbook']['depends'][] = array(
|
||||
@ -54,4 +58,4 @@
|
||||
'appname' => 'etemplate',
|
||||
'versions' => Array('1.0.0','1.0.1','1.2','1.3')
|
||||
);
|
||||
?>
|
||||
|
||||
|
89
addressbook/setup/tables_baseline.inc.php
Normal file
@ -0,0 +1,89 @@
|
||||
<?php
|
||||
/**************************************************************************\
|
||||
* eGroupWare *
|
||||
* http://www.egroupware.org *
|
||||
* -------------------------------------------- *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU General Public License as published by the *
|
||||
* Free Software Foundation; either version 2 of the License, or (at your *
|
||||
* option) any later version. *
|
||||
\**************************************************************************/
|
||||
|
||||
// $Id$
|
||||
// $Source$
|
||||
|
||||
$phpgw_baseline = array(
|
||||
'egw_addressbook' => array(
|
||||
'fd' => array(
|
||||
'id' => array('type' => 'auto','nullable' => False),
|
||||
'lid' => array('type' => 'varchar','precision' => '32'),
|
||||
'tid' => array('type' => 'char','precision' => '1'),
|
||||
'owner' => array('type' => 'int','precision' => '8'),
|
||||
'access' => array('type' => 'varchar','precision' => '7'),
|
||||
'cat_id' => array('type' => 'varchar','precision' => '32'),
|
||||
'fn' => array('type' => 'varchar','precision' => '64'),
|
||||
'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'),
|
||||
'sound' => array('type' => 'varchar','precision' => '64'),
|
||||
'bday' => array('type' => 'varchar','precision' => '32'),
|
||||
'note' => array('type' => 'text'),
|
||||
'tz' => array('type' => 'varchar','precision' => '8'),
|
||||
'geo' => array('type' => 'varchar','precision' => '32'),
|
||||
'url' => array('type' => 'varchar','precision' => '128'),
|
||||
'pubkey' => array('type' => 'text'),
|
||||
'org_name' => array('type' => 'varchar','precision' => '64'),
|
||||
'org_unit' => array('type' => 'varchar','precision' => '64'),
|
||||
'title' => array('type' => 'varchar','precision' => '64'),
|
||||
'adr_one_street' => 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'),
|
||||
'adr_one_type' => array('type' => 'varchar','precision' => '32'),
|
||||
'label' => array('type' => 'text'),
|
||||
'adr_two_street' => 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'),
|
||||
'adr_two_type' => array('type' => 'varchar','precision' => '32'),
|
||||
'tel_work' => array('type' => 'varchar','precision' => '40','nullable' => False,'default' => '+1 (000) 000-0000'),
|
||||
'tel_home' => array('type' => 'varchar','precision' => '40','nullable' => False,'default' => '+1 (000) 000-0000'),
|
||||
'tel_voice' => array('type' => 'varchar','precision' => '40','nullable' => False,'default' => '+1 (000) 000-0000'),
|
||||
'tel_fax' => array('type' => 'varchar','precision' => '40','nullable' => False,'default' => '+1 (000) 000-0000'),
|
||||
'tel_msg' => array('type' => 'varchar','precision' => '40','nullable' => False,'default' => '+1 (000) 000-0000'),
|
||||
'tel_cell' => array('type' => 'varchar','precision' => '40','nullable' => False,'default' => '+1 (000) 000-0000'),
|
||||
'tel_pager' => array('type' => 'varchar','precision' => '40','nullable' => False,'default' => '+1 (000) 000-0000'),
|
||||
'tel_bbs' => array('type' => 'varchar','precision' => '40','nullable' => False,'default' => '+1 (000) 000-0000'),
|
||||
'tel_modem' => array('type' => 'varchar','precision' => '40','nullable' => False,'default' => '+1 (000) 000-0000'),
|
||||
'tel_car' => array('type' => 'varchar','precision' => '40','nullable' => False,'default' => '+1 (000) 000-0000'),
|
||||
'tel_isdn' => array('type' => 'varchar','precision' => '40','nullable' => False,'default' => '+1 (000) 000-0000'),
|
||||
'tel_video' => array('type' => 'varchar','precision' => '40','nullable' => False,'default' => '+1 (000) 000-0000'),
|
||||
'tel_prefer' => array('type' => 'varchar','precision' => '32'),
|
||||
'email' => array('type' => 'varchar','precision' => '64'),
|
||||
'email_type' => array('type' => 'varchar','precision' => '32','default' => 'INTERNET'),
|
||||
'email_home' => array('type' => 'varchar','precision' => '64'),
|
||||
'email_home_type' => array('type' => 'varchar','precision' => '32','default' => 'INTERNET'),
|
||||
'last_mod' => array('type' => 'int','precision' => '8','nullable' => False)
|
||||
),
|
||||
'pk' => array('id'),
|
||||
'fk' => array(),
|
||||
'ix' => array(array('tid','owner','access','n_family','n_given'),array('tid','cat_id','owner','access','n_family')),
|
||||
'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()
|
||||
),
|
||||
);
|
93
addressbook/setup/tables_current.inc.php
Normal file
@ -0,0 +1,93 @@
|
||||
<?php
|
||||
/**************************************************************************\
|
||||
* eGroupWare *
|
||||
* http://www.egroupware.org *
|
||||
* -------------------------------------------- *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU General Public License as published by the *
|
||||
* Free Software Foundation; either version 2 of the License, or (at your *
|
||||
* option) any later version. *
|
||||
\**************************************************************************/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
$phpgw_baseline = 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'),
|
||||
),
|
||||
'pk' => array('contact_id'),
|
||||
'fk' => array(),
|
||||
'ix' => array('cat_id','contact_owner','contact_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()
|
||||
)
|
||||
);
|
159
addressbook/setup/tables_update.inc.php
Normal file
@ -0,0 +1,159 @@
|
||||
<?php
|
||||
/**************************************************************************\
|
||||
* eGroupWare - Setup *
|
||||
* http://www.eGroupWare.org *
|
||||
* Created by eTemplates DB-Tools written by ralfbecker@outdoor-training.de *
|
||||
* -------------------------------------------- *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU General Public License as published by the *
|
||||
* Free Software Foundation; either version 2 of the License, or (at your *
|
||||
* option) any later version. *
|
||||
\**************************************************************************/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
$test[] = '1.2';
|
||||
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';
|
||||
}
|
@ -1,4 +1,27 @@
|
||||
.redItalic { color: red; font-style: italic; }
|
||||
.fixedHeight,.telNumbers { height: 12px; }
|
||||
.telNumbers { white-space: nowrap; }
|
||||
.leftPad5 { padding-left: 5px; }
|
||||
.bold { font-weight: bold; }
|
||||
.fileas select,.fileas,.owner select,.owner {
|
||||
width: 100%;
|
||||
font-weight: bold;
|
||||
}
|
||||
.photo img {
|
||||
width: 60px;
|
||||
min-height: 80px;
|
||||
}
|
||||
.uploadphoto{
|
||||
position: absolute;
|
||||
top: 168px;
|
||||
left: 48px;
|
||||
display:none;
|
||||
border: 2px solid black;
|
||||
background-color: #ffffff;
|
||||
padding: 4px;
|
||||
}
|
||||
.checkAllArrow { padding-right: 5px; }
|
||||
.typeIcon { height: 16px; width: 16px; }
|
||||
.editphones{
|
||||
position: absolute;
|
||||
top: 10%;
|
||||
@ -17,7 +40,7 @@
|
||||
border-bottom: #9c9c9c 1px solid;
|
||||
}
|
||||
.phoneGroup fieldset{
|
||||
margin-top: 18px;
|
||||
margin-top: 17px;
|
||||
font-size: 110%;
|
||||
height: 117px;
|
||||
border: solid black 2px;
|
||||
@ -29,7 +52,7 @@
|
||||
.emailGroup fieldset{
|
||||
margin-top: 0px;
|
||||
font-size: 110%;
|
||||
height: 104px;
|
||||
height: 112px;
|
||||
border: solid black 2px;
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
@ -22,7 +22,7 @@
|
||||
<td align="center" colspan="2">{lang_WARNING!!_LDAP_is_valid_only_if_you_are_NOT_using_contacts_for_accounts_storage!}</td>
|
||||
</tr> -->
|
||||
<tr class="row_off">
|
||||
<td>{lang_Select_where_you_want_to_store}/{lang_retrieve_contacts}.</td>
|
||||
<td>{lang_Select_where_you_want_to_store_/_retrieve_contacts}.</td>
|
||||
<td>
|
||||
<select name="newsettings[contact_repository]">
|
||||
<option value="sql" {selected_contact_repository_sql}>SQL</option>
|
||||
|
@ -1,59 +1,72 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- $Id$ -->
|
||||
<overlay>
|
||||
<template id="addressbook.edit.personal" template="" lang="" group="0" version="1.0.1.002">
|
||||
<grid class="editphones">
|
||||
<template id="addressbook.edit.personal" template="" lang="" group="0" version="1.3.002">
|
||||
<grid height="258">
|
||||
<columns>
|
||||
<column/>
|
||||
<column/>
|
||||
<column/>
|
||||
</columns>
|
||||
<rows>
|
||||
<row>
|
||||
<image src="personal"/>
|
||||
<description value="prefix"/>
|
||||
<textbox id="n_prefix" size="45" maxlength="64"/>
|
||||
</row>
|
||||
<row>
|
||||
<description/>
|
||||
<description value="first name"/>
|
||||
<textbox id="n_given" size="45" maxlength="64"/>
|
||||
</row>
|
||||
<row>
|
||||
<description/>
|
||||
<description value="middle name"/>
|
||||
<textbox id="n_middle" size="45" maxlength="64"/>
|
||||
</row>
|
||||
<row>
|
||||
<description/>
|
||||
<description value="last name"/>
|
||||
<textbox id="n_family" size="45" maxlength="64"/>
|
||||
</row>
|
||||
<row>
|
||||
<description/>
|
||||
<description value="suffix"/>
|
||||
<textbox id="n_suffix" size="45" maxlength="64"/>
|
||||
</row>
|
||||
<row height="40">
|
||||
<image src="gohome"/>
|
||||
<description value="company name" options=",,,org_name"/>
|
||||
<textbox size="45" maxlength="64" id="org_name"/>
|
||||
</row>
|
||||
<row valign="top">
|
||||
<image src="accounts"/>
|
||||
<vbox>
|
||||
<image src="photo" class="photo"/>
|
||||
<button label="change" id="change_photo" statustext="Upload or delete the photo" onclick="set_style_by_class('table','uploadphoto','display','inline'); return false;"/>
|
||||
<template id="addressbook.edit"/>
|
||||
</vbox>
|
||||
<grid>
|
||||
<columns>
|
||||
<column width="20%"/>
|
||||
<column/>
|
||||
</columns>
|
||||
<rows>
|
||||
<row>
|
||||
<description options=",,,n_prefix" value="prefix"/>
|
||||
<textbox id="n_prefix" size="35" maxlength="64" onchange="setFileasOptions(this);"/>
|
||||
</row>
|
||||
<row>
|
||||
<description value="first name" options=",,,n_given"/>
|
||||
<textbox id="n_given" size="35" maxlength="64" onchange="setFileasOptions(this);"/>
|
||||
</row>
|
||||
<row>
|
||||
<description options=",,,n_middle" value="middle name"/>
|
||||
<textbox id="n_middle" size="35" maxlength="64" onchange="setFileasOptions(this);"/>
|
||||
</row>
|
||||
<row>
|
||||
<description options=",,,n_family" value="last name"/>
|
||||
<textbox id="n_family" size="35" maxlength="64" onchange="setFileasOptions(this);"/>
|
||||
</row>
|
||||
<row>
|
||||
<description options=",,,n_suffix" value="suffix"/>
|
||||
<textbox id="n_suffix" size="35" maxlength="64" onchange="setFileasOptions(this);"/>
|
||||
</row>
|
||||
</rows>
|
||||
</grid>
|
||||
</row>
|
||||
<row height="30">
|
||||
<image src="gohome"/>
|
||||
<description value="company" options=",,,org_name"/>
|
||||
<textbox size="45" maxlength="64" id="org_name" onchange="setFileasOptions(this);"/>
|
||||
</row>
|
||||
<row valign="top" height="70">
|
||||
<image src="folder"/>
|
||||
<description value="category"/>
|
||||
<listbox type="select-cat" id="cat_id" rows="3" options=",width:99%" span="4"/>
|
||||
</row>
|
||||
<row>
|
||||
<image src="password"/>
|
||||
<description value="Private" options=",,,private"/>
|
||||
<checkbox id="private"/>
|
||||
<image src="private.png"/>
|
||||
<description value="Addressbook" options=",,,owner"/>
|
||||
<menulist span=",owner">
|
||||
<menupopup id="owner" statustext="Addressbook the contact should be saved to" no_lang="1"/>
|
||||
</menulist>
|
||||
</row>
|
||||
</rows>
|
||||
</grid>
|
||||
</template>
|
||||
<template id="addressbook.edit.organisation" template="" lang="" group="0" version="1.0.1.001">
|
||||
<grid height="320">
|
||||
<template id="addressbook.edit.organisation" template="" lang="" group="0" version="1.3.001">
|
||||
<grid height="258">
|
||||
<columns>
|
||||
<column/>
|
||||
<column/>
|
||||
@ -63,16 +76,25 @@
|
||||
<rows>
|
||||
<row>
|
||||
<image src="gear"/>
|
||||
<description value="title"/>
|
||||
<description value="title" options=",,,title"/>
|
||||
<textbox size="45" maxlength="64" id="title"/>
|
||||
<description/>
|
||||
</row>
|
||||
<row>
|
||||
<description/>
|
||||
<description value="department"/>
|
||||
<description value="department" options=",,,org_unit"/>
|
||||
<textbox id="org_unit" size="45" maxlength="64"/>
|
||||
<description/>
|
||||
</row>
|
||||
<row>
|
||||
<description/>
|
||||
<description options=",,,role" value="Role"/>
|
||||
<hbox orient=",0,0">
|
||||
<textbox id="role" size="25" maxlength="64"/>
|
||||
<textbox size="8" maxlength="64" label="Room" align="right" id="room"/>
|
||||
</hbox>
|
||||
<description/>
|
||||
</row>
|
||||
<row>
|
||||
<description/>
|
||||
<description/>
|
||||
@ -81,43 +103,37 @@
|
||||
</row>
|
||||
<row>
|
||||
<image src="gohome"/>
|
||||
<description value="street"/>
|
||||
<description value="street" options=",,,adr_one_street"/>
|
||||
<textbox size="45" maxlength="64" id="adr_one_street"/>
|
||||
<description/>
|
||||
</row>
|
||||
<row>
|
||||
<description/>
|
||||
<description value="address line 2"/>
|
||||
<textbox size="45" maxlength="64" id="address2"/>
|
||||
<description value="address line 2" options=",,,adr_one_street2"/>
|
||||
<textbox size="45" maxlength="64" id="adr_one_street2"/>
|
||||
<description/>
|
||||
</row>
|
||||
<row>
|
||||
<description/>
|
||||
<description value="address line 3"/>
|
||||
<textbox size="45" maxlength="64" id="address3"/>
|
||||
<description/>
|
||||
</row>
|
||||
<row>
|
||||
<description/>
|
||||
<description value="city"/>
|
||||
<description value="city" options=",,,adr_one_locality"/>
|
||||
<textbox size="45" maxlength="64" id="adr_one_locality"/>
|
||||
<description/>
|
||||
</row>
|
||||
<row>
|
||||
<description/>
|
||||
<description value="zip code"/>
|
||||
<description value="zip code" options=",,,adr_one_postalcode"/>
|
||||
<textbox size="45" maxlength="64" id="adr_one_postalcode"/>
|
||||
<description/>
|
||||
</row>
|
||||
<row>
|
||||
<description/>
|
||||
<description value="state"/>
|
||||
<description value="state" options=",,,adr_one_region"/>
|
||||
<textbox size="45" maxlength="64" id="adr_one_region"/>
|
||||
<description/>
|
||||
</row>
|
||||
<row>
|
||||
<description/>
|
||||
<description value="country"/>
|
||||
<description value="country" options=",,,adr_one_countryname"/>
|
||||
<textbox size="45" maxlength="64" id="adr_one_countryname"/>
|
||||
<description/>
|
||||
</row>
|
||||
@ -130,8 +146,8 @@
|
||||
</rows>
|
||||
</grid>
|
||||
</template>
|
||||
<template id="addressbook.edit.home" template="" lang="" group="0" version="1.0.1.001">
|
||||
<grid width="100%" height="250" overflow="auto">
|
||||
<template id="addressbook.edit.home" template="" lang="" group="0" version="1.3.001">
|
||||
<grid height="258">
|
||||
<columns>
|
||||
<column/>
|
||||
<column/>
|
||||
@ -140,60 +156,63 @@
|
||||
<rows>
|
||||
<row>
|
||||
<image src="gohome"/>
|
||||
<description value="street"/>
|
||||
<description value="street" options=",,,adr_two_street"/>
|
||||
<textbox size="45" maxlength="64" id="adr_two_street"/>
|
||||
</row>
|
||||
<row>
|
||||
<description/>
|
||||
<description value="city"/>
|
||||
<description options=",,,adr_two_street2" value="address line 2"/>
|
||||
<textbox size="45" maxlength="64" id="adr_two_street2"/>
|
||||
</row>
|
||||
<row>
|
||||
<description/>
|
||||
<description value="city" options=",,,adr_two_locality"/>
|
||||
<textbox size="45" maxlength="64" id="adr_two_locality"/>
|
||||
</row>
|
||||
<row>
|
||||
<description/>
|
||||
<description value="zip code"/>
|
||||
<description value="zip code" options=",,,adr_two_postalcode"/>
|
||||
<textbox size="45" maxlength="64" id="adr_two_postalcode"/>
|
||||
</row>
|
||||
<row>
|
||||
<description/>
|
||||
<description value="state"/>
|
||||
<description value="state" options=",,,adr_two_region"/>
|
||||
<textbox size="45" maxlength="64" id="adr_two_region"/>
|
||||
</row>
|
||||
<row>
|
||||
<description/>
|
||||
<description value="country"/>
|
||||
<description value="country" options=",,,adr_two_countryname"/>
|
||||
<textbox size="45" maxlength="64" id="adr_two_countryname"/>
|
||||
</row>
|
||||
<row height="30">
|
||||
<description/>
|
||||
<description options=",,,bday" value="Birthday"/>
|
||||
<date id="bday" options="m/d/Y"/>
|
||||
<hbox id="bday" orient=",0,0">
|
||||
<date options="Y-m-d" id="bday"/>
|
||||
<menulist>
|
||||
<menupopup id="tz" no_lang="1" label="Timezone" align="right"/>
|
||||
</menulist>
|
||||
</hbox>
|
||||
</row>
|
||||
<row>
|
||||
<description/>
|
||||
<description options=",,,tz" value="Time zone"/>
|
||||
<menulist>
|
||||
<menupopup id="tz" no_lang="1"/>
|
||||
</menulist>
|
||||
</row>
|
||||
<row>
|
||||
<description/>
|
||||
<description value="Public key"/>
|
||||
<textbox multiline="true" rows="2" cols="45" id="pubkey"/>
|
||||
<image src="private"/>
|
||||
<description value="Public key" options=",,,pubkey"/>
|
||||
<textbox multiline="true" rows="2" cols="40" id="pubkey"/>
|
||||
</row>
|
||||
</rows>
|
||||
</grid>
|
||||
</template>
|
||||
<template id="addressbook.edit.details" template="" lang="" group="0" version="1.0.1.001">
|
||||
<grid height="320">
|
||||
<template id="addressbook.edit.details" template="" lang="" group="0" version="1.3.001">
|
||||
<grid width="100%" height="258" overflow="auto">
|
||||
<columns>
|
||||
<column/>
|
||||
</columns>
|
||||
<rows>
|
||||
<row>
|
||||
<description value="Notes"/>
|
||||
<description value="Notes" options=",,,note"/>
|
||||
</row>
|
||||
<row valign="top">
|
||||
<textbox multiline="true" rows="4" cols="56" id="note"/>
|
||||
<textbox multiline="true" rows="4" cols="50" id="note"/>
|
||||
</row>
|
||||
<row class="th">
|
||||
<description value="Custom fields"/>
|
||||
@ -204,8 +223,8 @@
|
||||
</rows>
|
||||
</grid>
|
||||
</template>
|
||||
<template id="addressbook.edit.links" template="" lang="" group="0" version="1.0.1.002">
|
||||
<grid height="320">
|
||||
<template id="addressbook.edit.links" template="" lang="" group="0" version="1.3.001">
|
||||
<grid width="100%" height="258" overflow="auto">
|
||||
<columns>
|
||||
<column/>
|
||||
</columns>
|
||||
@ -225,8 +244,8 @@
|
||||
</rows>
|
||||
</grid>
|
||||
</template>
|
||||
<template id="addressbook.editphones" template="" lang="" group="0" version="1.0.1.001">
|
||||
<grid width="100%">
|
||||
<template id="addressbook.editphones" template="" lang="" group="0" version="1.3.001">
|
||||
<grid class="editphones">
|
||||
<columns>
|
||||
<column/>
|
||||
<column/>
|
||||
@ -244,69 +263,67 @@
|
||||
<description value="pref"/>
|
||||
</row>
|
||||
<row>
|
||||
<description value="business"/>
|
||||
<description value="business" options=",,,tel_work2" class="bold"/>
|
||||
<textbox size="30" id="tel_work2"/>
|
||||
<radio options="tel_work" id="tel_prefer"/>
|
||||
</row>
|
||||
<row>
|
||||
<description value="mobile phone"/>
|
||||
<description value="mobile phone" options=",,,tel_cell2"/>
|
||||
<textbox size="30" id="tel_cell2"/>
|
||||
<radio options="tel_cell" id="tel_prefer"/>
|
||||
</row>
|
||||
<row>
|
||||
<description value="Private"/>
|
||||
<textbox size="30" id="tel_home2"/>
|
||||
<radio options="tel_home" id="tel_prefer"/>
|
||||
</row>
|
||||
<row>
|
||||
<description value="fax"/>
|
||||
<description value="fax" options=",,,tel_fax"/>
|
||||
<textbox size="30" id="tel_fax"/>
|
||||
<radio options="tel_fax" id="tel_prefer"/>
|
||||
</row>
|
||||
<row>
|
||||
<description value="car phone"/>
|
||||
<description value="car phone" options=",,,tel_car"/>
|
||||
<textbox size="30" id="tel_car"/>
|
||||
<radio options="tel_car" id="tel_prefer"/>
|
||||
</row>
|
||||
<row>
|
||||
<description value="video phone"/>
|
||||
<textbox size="30" id="tel_video"/>
|
||||
<radio options="tel_video" id="tel_prefer"/>
|
||||
</row>
|
||||
<row>
|
||||
<description value="pager"/>
|
||||
<description value="pager" options=",,,tel_pager"/>
|
||||
<textbox size="30" id="tel_pager"/>
|
||||
<radio options="tel_pager" id="tel_prefer"/>
|
||||
</row>
|
||||
<row>
|
||||
<description value="voice phone"/>
|
||||
<textbox size="30" id="tel_voice"/>
|
||||
<radio options="tel_voice" id="tel_prefer"/>
|
||||
<hrule span="all"/>
|
||||
</row>
|
||||
<row>
|
||||
<description value="message phone"/>
|
||||
<textbox size="30" id="tel_msg"/>
|
||||
<description value="Assistent" options=",,,assistent" class="bold"/>
|
||||
<textbox size="35" id="assistent" span="2"/>
|
||||
</row>
|
||||
<row>
|
||||
<description value="number" options=",,,tel_assistent"/>
|
||||
<textbox size="30" id="tel_assistent"/>
|
||||
<radio options="tel_msg" id="tel_prefer"/>
|
||||
</row>
|
||||
<row>
|
||||
<description value="bbs phone"/>
|
||||
<textbox size="30" id="tel_bbs"/>
|
||||
<radio options="tel_bbs" id="tel_prefer"/>
|
||||
<hrule span="all"/>
|
||||
</row>
|
||||
<row>
|
||||
<description value="modem phone"/>
|
||||
<textbox size="30" id="tel_modem"/>
|
||||
<radio options="tel_modem" id="tel_prefer"/>
|
||||
<description value="Private" options=",,,tel_home2" class="bold"/>
|
||||
<textbox size="30" id="tel_home2"/>
|
||||
<radio options="tel_home" id="tel_prefer"/>
|
||||
</row>
|
||||
<row>
|
||||
<description value="isdn phone"/>
|
||||
<textbox size="30" id="tel_isdn"/>
|
||||
<radio options="tel_isdn" id="tel_prefer"/>
|
||||
<description value="mobile phone" options=",,,tel_cell_private"/>
|
||||
<textbox size="30" id="tel_cell_private"/>
|
||||
<radio options="tel_cell_private" id="tel_prefer"/>
|
||||
</row>
|
||||
<row>
|
||||
<description value=" Other Phone"/>
|
||||
<textbox size="30" id="ophone"/>
|
||||
<radio options="ophone" id="tel_prefer"/>
|
||||
<description value="fax" options=",,,tel_fax_home"/>
|
||||
<textbox size="30" id="tel_fax_home"/>
|
||||
<radio options="tel_fax_home" id="tel_prefer"/>
|
||||
</row>
|
||||
<row>
|
||||
<hrule span="all"/>
|
||||
</row>
|
||||
<row>
|
||||
<description value=" Other Phone" options=",,,tel_other"/>
|
||||
<textbox size="30" id="tel_other"/>
|
||||
<radio options="tel_other" id="tel_prefer"/>
|
||||
</row>
|
||||
<row>
|
||||
<button label="Ok" onclick="hidephones(this.form); return false;" span="all" align="center"/>
|
||||
@ -314,8 +331,8 @@
|
||||
</rows>
|
||||
</grid>
|
||||
</template>
|
||||
<template id="addressbook.edit" template="" lang="" group="0" version="1.0.1.002">
|
||||
<grid>
|
||||
<template id="addressbook.edit" template="" lang="" group="0" version="1.3.002">
|
||||
<grid width="800">
|
||||
<columns>
|
||||
<column width="450"/>
|
||||
<column/>
|
||||
@ -326,24 +343,12 @@
|
||||
<description/>
|
||||
</row>
|
||||
<row>
|
||||
<grid>
|
||||
<columns>
|
||||
<column disabled="!@org_name"/>
|
||||
<column disabled="!@org_name"/>
|
||||
<column/>
|
||||
</columns>
|
||||
<rows>
|
||||
<row>
|
||||
<textbox id="org_name" readonly="true" no_lang="1"/>
|
||||
<description value=":"/>
|
||||
<textbox id="fn" no_lang="1" readonly="true"/>
|
||||
</row>
|
||||
</rows>
|
||||
</grid>
|
||||
<menulist span=",fileas">
|
||||
<menupopup data="" rows="1" cols="3" id="fileas_type" no_lang="1"/>
|
||||
</menulist>
|
||||
<hbox align="right">
|
||||
<description value="Type"/>
|
||||
<menulist>
|
||||
<menupopup no_lang="1" id="tid" onchange="1"/>
|
||||
<menulist span=",leftPad5">
|
||||
<menupopup no_lang="1" id="tid" onchange="1" label="Type"/>
|
||||
</menulist>
|
||||
<html class="space" needed="1" label=" " no_lang="1" id="typegfx" readonly="true"/>
|
||||
</hbox>
|
||||
@ -376,7 +381,7 @@
|
||||
</columns>
|
||||
<rows>
|
||||
<row>
|
||||
<image src="kaddressbook"/>
|
||||
<image src="phone"/>
|
||||
<description value="business" options=",,,tel_work"/>
|
||||
<textbox id="tel_work" size="28" maxlength="40"/>
|
||||
</row>
|
||||
@ -408,18 +413,23 @@
|
||||
</columns>
|
||||
<rows>
|
||||
<row>
|
||||
<image src="package_network"/>
|
||||
<image src="internet"/>
|
||||
<description value="url" options=",,,url"/>
|
||||
<textbox id="url" size="28" maxlength="128"/>
|
||||
</row>
|
||||
<row>
|
||||
<image src="email_icon"/>
|
||||
<description value="business email" options=",,,email"/>
|
||||
<description/>
|
||||
<description options=",,,url_home" value="Private"/>
|
||||
<textbox id="url_home" size="28" maxlength="128"/>
|
||||
</row>
|
||||
<row>
|
||||
<image src="email.png"/>
|
||||
<description value="email" options=",,,email"/>
|
||||
<textbox id="email" size="28" maxlength="64"/>
|
||||
</row>
|
||||
<row>
|
||||
<description/>
|
||||
<description value="home email" options=",,,email_home"/>
|
||||
<description value="Private" options=",,,email_home"/>
|
||||
<textbox id="email_home" size="28" maxlength="64"/>
|
||||
</row>
|
||||
</rows>
|
||||
@ -427,13 +437,19 @@
|
||||
</groupbox>
|
||||
</vbox>
|
||||
</row>
|
||||
<row disabled="!@id">
|
||||
<menulist>
|
||||
<menupopup type="select-account" id="owner" readonly="true" label="Owner"/>
|
||||
</menulist>
|
||||
<row>
|
||||
<hbox orient=",0,0">
|
||||
<menulist span=",leftPad5">
|
||||
<menupopup type="select-account" id="creator" readonly="true" label="Created"/>
|
||||
</menulist>
|
||||
<date-time id="created" class="leftPad5" readonly="true"/>
|
||||
</hbox>
|
||||
<hbox align="right">
|
||||
<description value="Last modified"/>
|
||||
<date-time id="last_mod" readonly="true"/>
|
||||
<menulist>
|
||||
<menupopup type="select-account" id="modifier" readonly="true"/>
|
||||
</menulist>
|
||||
<date-time id="modified" readonly="true"/>
|
||||
</hbox>
|
||||
</row>
|
||||
<row disabled="@hidebuttons">
|
||||
|
BIN
addressbook/templates/default/images/accounts.png
Executable file
After Width: | Height: | Size: 962 B |
Before Width: | Height: | Size: 1015 B |
BIN
addressbook/templates/default/images/group.png
Normal file
After Width: | Height: | Size: 868 B |
Before Width: | Height: | Size: 754 B After Width: | Height: | Size: 754 B |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 962 B After Width: | Height: | Size: 753 B |
Before Width: | Height: | Size: 299 B After Width: | Height: | Size: 299 B |
Before Width: | Height: | Size: 635 B After Width: | Height: | Size: 635 B |
BIN
addressbook/templates/default/images/template.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
167
addressbook/templates/default/index.xet
Normal file
@ -0,0 +1,167 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- $Id$ -->
|
||||
<overlay>
|
||||
<template id="addressbook.index.right" template="" lang="" group="0" version="1.3.001">
|
||||
<menulist>
|
||||
<menupopup label="Type" id="col_filter[tid]" statustext="Select addressbook type" onchange="1"/>
|
||||
</menulist>
|
||||
</template>
|
||||
<template id="addressbook.index.rows" template="" lang="" group="0" version="1.3.001">
|
||||
<grid width="100%">
|
||||
<columns>
|
||||
<column/>
|
||||
<column/>
|
||||
<column width="60" disabled="@no_photo"/>
|
||||
<column/>
|
||||
<column disabled="!@show_home"/>
|
||||
<column/>
|
||||
<column/>
|
||||
<column disabled="@no_customfields"/>
|
||||
<column width="90"/>
|
||||
</columns>
|
||||
<rows>
|
||||
<row class="th">
|
||||
<description/>
|
||||
<grid spacing="0" padding="0">
|
||||
<columns>
|
||||
<column/>
|
||||
<column/>
|
||||
</columns>
|
||||
<rows>
|
||||
<row disabled="!@order=n_given">
|
||||
<nextmatch-sortheader id="n_given" label="Firstname"/>
|
||||
<nextmatch-sortheader label="Name" id="n_family"/>
|
||||
</row>
|
||||
<row disabled="!@order=n_family">
|
||||
<nextmatch-sortheader label="Name" id="n_family"/>
|
||||
<nextmatch-sortheader id="n_given" label="Firstname"/>
|
||||
</row>
|
||||
<row>
|
||||
<nextmatch-sortheader id="org_name" label="Company" span="all"/>
|
||||
</row>
|
||||
<row disabled="!@order=org_name">
|
||||
<nextmatch-sortheader id="n_family" label="Name"/>
|
||||
<nextmatch-sortheader id="n_given" label="Firstname"/>
|
||||
</row>
|
||||
</rows>
|
||||
</grid>
|
||||
<description value="Photo"/>
|
||||
<description value="Business address"/>
|
||||
<description value="Home address"/>
|
||||
<vbox orient=",0,0">
|
||||
<description id="tel_work" value="Business phone"/>
|
||||
<description value="Mobile phone" id="tel_cell"/>
|
||||
<description id="tel_home" value="Home phone"/>
|
||||
</vbox>
|
||||
<vbox orient=",0,0">
|
||||
<description id="url" value="Url"/>
|
||||
<description value="Business email" id="email"/>
|
||||
<description id="email_home" value="Home email"/>
|
||||
</vbox>
|
||||
<grid spacing="0" padding="0">
|
||||
<columns>
|
||||
<column/>
|
||||
</columns>
|
||||
<rows>
|
||||
<row>
|
||||
<description no_lang="1" id="customfields[$row][label]"/>
|
||||
</row>
|
||||
</rows>
|
||||
</grid>
|
||||
<hbox align="center" class="noPrint">
|
||||
<description value="Actions" align="center"/>
|
||||
<button image="check" label="Check all" id="check_all" statustext="Check all" onclick="toggle_all(this.form,form::name('checked[]')); return false;" needed="1" align="right"/>
|
||||
</hbox>
|
||||
</row>
|
||||
<row class="row" valign="top">
|
||||
<image label="$row_cont[type_label]" src="${row}[type]" align="center" no_lang="1"/>
|
||||
<vbox id="${row}[id]" orient=",0,0">
|
||||
<description id="${row}[first_given]" no_lang="1"/>
|
||||
<description id="${row}[first_family]" no_lang="1"/>
|
||||
<description id="${row}[org_name]" no_lang="1"/>
|
||||
<description id="${row}[org_unit]" no_lang="1"/>
|
||||
<description id="${row}[title]" no_lang="1"/>
|
||||
<description id="${row}[first_org]" no_lang="1"/>
|
||||
</vbox>
|
||||
<image src="${row}[photo]"/>
|
||||
<vbox orient=",0,0">
|
||||
<description id="${row}[adr_one_countryname]" no_lang="1"/>
|
||||
<hbox orient="0,0,0">
|
||||
<description no_lang="1" id="${row}[adr_one_locality]"/>
|
||||
<description id="${row}[adr_one_postalcode]" class="leftPad5" value=" " no_lang="1"/>
|
||||
</hbox>
|
||||
<description no_lang="1" id="${row}[adr_one_street]"/>
|
||||
<description id="${row}[adr_one_street2]" no_lang="1"/>
|
||||
</vbox>
|
||||
<vbox orient=",0,0">
|
||||
<description id="${row}[adr_two_countryname]" no_lang="1"/>
|
||||
<hbox orient=",0,0">
|
||||
<description no_lang="1" id="${row}[adr_two_locality]"/>
|
||||
<description id="${row}[adr_two_postalcode]" class="leftPad5" value=" " no_lang="1"/>
|
||||
</hbox>
|
||||
<description no_lang="1" id="${row}[adr_two_street]"/>
|
||||
<description id="${row}[adr_two_street2]" no_lang="1"/>
|
||||
</vbox>
|
||||
<vbox orient=",0,0">
|
||||
<description no_lang="1" id="${row}[tel_work]" class="telNumbers"/>
|
||||
<description id="${row}[tel_cell]" no_lang="1" class="telNumbers"/>
|
||||
<description id="${row}[tel_home]" no_lang="1" class="telNumbers"/>
|
||||
<description id="${row}[tel_prefered]" no_lang="1"/>
|
||||
</vbox>
|
||||
<vbox orient=",0,0">
|
||||
<description options=",,1" class="fixedHeight" no_lang="1" id="${row}[url]"/>
|
||||
<description options=",@${row}[email_link],,,_blank,$row_cont[email_popup]" class="fixedHeight" id="${row}[email]" no_lang="1"/>
|
||||
<description options=",@${row}[email_home_link],,,_blank,$row_cont[email_home_popup]" class="fixedHeight" id="${row}[email_home]" no_lang="1"/>
|
||||
</vbox>
|
||||
<grid height="60" spacing="0" padding="0" overflow="auto">
|
||||
<columns>
|
||||
<column/>
|
||||
</columns>
|
||||
<rows>
|
||||
<row>
|
||||
<description class="fixedHeight" id="$row" no_lang="1"/>
|
||||
</row>
|
||||
</rows>
|
||||
</grid>
|
||||
<hbox class="noPrint" orient="0,0">
|
||||
<image options="addressbook.uicontacts.view&contact_id=$row_cont[id]" label="View" src="view"/>
|
||||
<button image="edit" label="Edit" onclick="window.open(egw::link('/index.php','menuaction=addressbook.uicontacts.edit&contact_id=$row_cont[id]'),'_blank','dependent=yes,width=850,height=440,scrollbars=yes,status=yes'); return false;" id="edit[$row_cont[id]]"/>
|
||||
<button id="delete[$row_cont[id]]" image="delete" label="Delete" statustext="Delete this contact" onclick="return confirm('Delete this contact');"/>
|
||||
<checkbox id="checked[]" options="$row_cont[id]" statustext="Select multiple contacts for a further action" align="right"/>
|
||||
</hbox>
|
||||
</row>
|
||||
</rows>
|
||||
</grid>
|
||||
</template>
|
||||
<template id="addressbook.index" template="" lang="" group="0" version="1.3.001">
|
||||
<grid width="100%">
|
||||
<columns>
|
||||
<column/>
|
||||
<column/>
|
||||
</columns>
|
||||
<rows>
|
||||
<row disabled="!@msg">
|
||||
<description span="all" class="redItalic" align="center" id="msg" no_lang="1"/>
|
||||
<description/>
|
||||
</row>
|
||||
<row disabled="1">
|
||||
<description/>
|
||||
<template align="right" id="addressbook.index.right"/>
|
||||
</row>
|
||||
<row>
|
||||
<nextmatch options="addressbook.index.rows" id="nm" span="all"/>
|
||||
</row>
|
||||
<row class="noPrint">
|
||||
<button id="add" label="Add" statustext="Add a new contact" onclick="window.open(egw::link('/index.php','menuaction=addressbook.uicontacts.edit'),'_blank','dependent=yes,width=850,height=440,scrollbars=yes,status=yes'); return false;"/>
|
||||
<hbox align="right">
|
||||
<checkbox id="use_all" label="whole selection" onchange="if (!confirm('Apply the action on the whole selection, NOT only the shown contacts!!!')) this.checked=false;" statustext="Apply the action on the whole selection, NOT only the shown contacts!!!"/>
|
||||
<menulist>
|
||||
<menupopup onchange="1" options="Select an action or addressbook to move to..." no_lang="1" id="action" statustext="Select an action or addressbook to move to"/>
|
||||
</menulist>
|
||||
<button image="arrow_ltr" label="Check all" id="check_all" statustext="Check all" onclick="toggle_all(this.form,form::name('nm[rows][checked][]')); return false;" needed="1" class="checkAllArrow"/>
|
||||
</hbox>
|
||||
</row>
|
||||
</rows>
|
||||
</grid>
|
||||
</template>
|
||||
</overlay>
|
@ -3,5 +3,6 @@
|
||||
<td>{user}</td>
|
||||
<td align="center"><input type="checkbox" name="{read}" value="Y"{read_selected}></td>
|
||||
<td align="center"><input type="checkbox" name="{edit}" value="Y"{edit_selected}></td>
|
||||
<td align="center"><input type="checkbox" name="{add}" value="Y"{add_selected}></td>
|
||||
<td align="center"><input type="checkbox" name="{delete}" value="Y"{delete_selected}></td>
|
||||
</tr>
|
||||
|
@ -1,6 +1,8 @@
|
||||
<!-- $Id$ -->
|
||||
<tr bgcolor="{bg_color}">
|
||||
<td>{string}</td>
|
||||
<td align="center">{lang_read}</td>
|
||||
<td align="center">{lang_edit}</td>
|
||||
<td align="center">{lang_add}</td>
|
||||
<td align="center">{lang_delete}</td>
|
||||
</tr>
|
||||
|
Before Width: | Height: | Size: 3.0 KiB |
@ -150,16 +150,17 @@
|
||||
// make this information also in hook available
|
||||
$lid = $GLOBALS['egw']->accounts->id2name($account_id);
|
||||
|
||||
$GLOBALS['hook_values']['account_id'] = $account_id;
|
||||
$GLOBALS['hook_values']['account_lid'] = $lid;
|
||||
|
||||
$singleHookValues = $GLOBALS['hook_values']+array('location' => 'deleteaccount');
|
||||
|
||||
$GLOBALS['hook_values'] = array(
|
||||
'account_id' => $account_id,
|
||||
'account_lid' => $lid,
|
||||
'new_owner' => (int)$_POST['new_owner'],
|
||||
'location' => 'deleteaccount',
|
||||
);
|
||||
foreach($GLOBALS['egw_info']['apps'] as $appname => $data)
|
||||
{
|
||||
if($appname != 'admin' && $appname != 'preferences')
|
||||
{
|
||||
$GLOBALS['egw']->hooks->single($singleHookValues,$appname);
|
||||
$GLOBALS['egw']->hooks->single($GLOBALS['hook_values'],$appname);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -28,11 +28,12 @@
|
||||
$this->rowColor[1] = $GLOBALS['egw_info']['theme']['row_off'];
|
||||
}
|
||||
|
||||
function section_item($pref_link='',$pref_text='', $class)
|
||||
function section_item($pref_link='',$pref_text='', $class='',$options='')
|
||||
{
|
||||
$this->t->set_var('row_link',$pref_link);
|
||||
$this->t->set_var('row_text',$pref_text);
|
||||
$this->t->set_var('class',$class);
|
||||
$this->t->set_var('row_options',$options);
|
||||
$this->t->parse('all_rows','link_row',True);
|
||||
}
|
||||
|
||||
@ -58,7 +59,7 @@
|
||||
{
|
||||
$link = $GLOBALS['egw']->link($value['url'],'account_id=' . get_var('account_id',array('GET','POST')));
|
||||
}
|
||||
$this->section_item($link,lang($value['description']),($i%2) ? "row_on": "row_off");
|
||||
$this->section_item($link,lang($value['description']),($i%2) ? "row_on": "row_off",$value['options']);
|
||||
$i++;
|
||||
}
|
||||
|
||||
|
@ -14,6 +14,6 @@
|
||||
<!-- END menu_links -->
|
||||
<!-- BEGIN link_row -->
|
||||
<tr class="{class}">
|
||||
<td> <a href="{row_link}">{row_text}</a></td>
|
||||
<td> <a href="{row_link}" {row_options}>{row_text}</a></td>
|
||||
</tr>
|
||||
<!-- END link_row -->
|
||||
|