fix SQL-backends of accounts and contacts to return either avatar-url or initials

This commit is contained in:
ralf 2023-01-30 15:48:53 +01:00
parent 7416b158b2
commit 0eff86f61a
5 changed files with 81 additions and 28 deletions

View File

@ -2046,7 +2046,7 @@ class addressbook_ui extends addressbook_bo
{
$row[$name] .= ' '.($row['tel_prefer'] == $name ? $prefer_marker : ''); // .' ' to NOT remove the field
}
// allways show the prefered phone, if not already shown
// always 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']].$prefer_marker;
@ -2070,6 +2070,12 @@ class addressbook_ui extends addressbook_bo
}
$row['class'] .= 'contact_contact ';
if (!self::hasPhoto($row))
{
$row['lname'] = $row['n_family'];
$row['fname'] = $row['n_given'];
unset($row['photo']); // no need to send, as there is no photo
}
unset($row['jpegphoto']); // unused and messes up json encoding (not utf-8)
if (isset($customfields[$row['id']]))

View File

@ -446,15 +446,15 @@ class Accounts
'lname' => $account['account_id'] < 0 ? $account['account_lid'] : $account['account_lastname'],
'fname' => $account['account_id'] < 0 ? lang('group') : $account['account_firstname']
];
// TODO: Ralf find a cheap way to get this
if($actual_picture)
// only if we have a real photo, send avatar-url, otherwise we use the above set lavatar (f|l)name
if(!empty($account['account_has_photo']))
{
$result['icon'] = Framework::link('/api/avatar.php', [
'account_id' => $account['account_id'],
'modified' => $account['account_modified'],
]);
}
$accounts[] = $result;
$accounts[$account['account_id']] = $result;
}
else
{
@ -516,7 +516,7 @@ class Accounts
function json($id)
{
static $keys = array(
'account_id','account_lid','person_id','account_status','memberships',
'account_id','account_lid','person_id','account_status','memberships','account_has_photo',
'account_firstname','account_lastname','account_email','account_fullname','account_phone',
);
if (($account = $this->read($id)))

View File

@ -501,7 +501,7 @@ class Sql
$filter[] = "(egw_addressbook.contact_owner=0 OR egw_addressbook.contact_owner IS NULL)";
break;
}
// fix ambigous account_id (used in accounts and contacts table)
// fix ambiguous account_id (used in accounts and contacts table)
if (array_key_exists('account_id', $filter))
{
if (!$filter['account_id']) // eg. group without members (would give SQL error)
@ -561,13 +561,13 @@ class Sql
if (!isset($this->contacts)) $this->contacts = new Api\Contacts();
$accounts = array();
foreach((array) $this->contacts->search($criteria,
array_merge(array(1,'n_given','n_family','id','created','modified',$this->table.'.account_id AS account_id'),$email_cols),
foreach($this->contacts->search($criteria,
array_merge(array(1,'n_given','n_family','id','created','modified','files',$this->table.'.account_id AS account_id'),$email_cols),
$order, "account_lid,account_type,account_status,account_expires,account_primary_group,account_description".
",account_lastlogin,account_lastloginfrom,account_lastpwd_change",
$wildcard,false,$query[0] == '!' ? 'AND' : 'OR',
!empty($param['offset']) ? array($param['start'], $param['offset']) : $param['start'] ?? false,
$filter,$join) as $contact)
$filter,$join) ?? [] as $contact)
{
if ($contact)
{
@ -592,6 +592,7 @@ class Sql
'account_lastpwd_change' => $contact['account_lastpwd_change'] ?
Api\DateTime::user2server($contact['account_lastpwd_change']) : null,
'account_description' => $contact['account_description'],
'account_has_photo' => Api\Contacts::hasPhoto($contact),
);
}
}

View File

@ -1701,15 +1701,35 @@ class Contacts extends Contacts\Storage
$args[] = $result[$contact['id']];
$result[$contact['id']] = call_user_func_array('imap_rfc822_write_address', $args);
}
if (!is_array($result[$contact['id']]))
{
$result[$contact['id']] = ['label' => $result[$contact['id']]];
}
// if we have a real photo, add avatar.php URL
if (!empty($contact['jpegphoto']) || ($contact['files'] & self::FILES_BIT_PHOTO) &&
filesize($url= Api\Link::vfs_path('addressbook', $contact['id'], self::FILES_PHOTO)))
{
$result[$contact['id']] += [
'icon' => Framework::link('/api/avatar.php', [
'contact_id' => $contact['id'],
'modified' => $contact['modified'],
])
];
}
// else add Lavatar information lname and fname
else
{
$result[$contact['id']] += [
'lname' => $contact['n_family'],
'fname' => $contact['n_given'],
];
}
// show category color
if ($contact['cat_id'] && ($color = Categories::cats2color($contact['cat_id'])))
{
$result[$contact['id']] = array(
'lname' => $contact['n_family'],
'fname' => $contact['n_given'],
'label' => $result[$contact['id']],
$result[$contact['id']] += [
'style.backgroundColor' => $color,
);
];
}
}
}
@ -1854,14 +1874,14 @@ class Contacts extends Contacts\Storage
'app' => 'calendar',
'title' => $bocal->link_title($cal_id . ($start ? '-'.$start : '')),
'extra_args' => array(
'date' => \EGroupware\Api\DateTime::server2user($start,\EGroupware\Api\DateTime::ET2),
'date' => DateTime::server2user($start,DateTime::ET2),
'exception'=> 1
),
);
if ($extra_title)
{
$link['extra_title'] = $link['title'];
$link['title'] = \EGroupware\Api\DateTime::server2user($start, true);
$link['title'] = DateTime::server2user($start, true);
}
$user_id = ($type == 'u' ? '' : $type) . $contact['user_id'];
$calendars[$user_id][$key.'_event'] = $start;
@ -2700,6 +2720,21 @@ class Contacts extends Contacts\Storage
return $ctag;
}
/**
* Check if given contact has a real photo attached
*
* @param array $contact
* @param string|null &$url on return vfs URL of photo
* @param int|null &$size on return size of photo
* @return bool
*/
public static function hasPhoto(array $contact, string &$url=null, int &$size=null)
{
return !empty($contact['jpegphoto']) || // LDAP/AD (not updated SQL)
($contact['files'] & self::FILES_BIT_PHOTO) && // new SQL in VFS
($size = filesize($url = Link::vfs_path('addressbook', $contact['id'], self::FILES_PHOTO)));
}
/**
* download photo of the given ($_GET['contact_id'] or $_GET['account_id']) contact
*/
@ -2718,10 +2753,7 @@ class Contacts extends Contacts\Storage
$contact = $this->read($contact_id);
if (!($contact) ||
empty($contact['jpegphoto']) && // LDAP/AD (not updated SQL)
!(($contact['files'] & \EGroupware\Api\Contacts::FILES_BIT_PHOTO) && // new SQL in VFS
($size = filesize($url= \EGroupware\Api\Link::vfs_path('addressbook', $contact_id, \EGroupware\Api\Contacts::FILES_PHOTO)))))
if (!$contact || !self::hasPhoto($contact, $url, $size))
{
if(!$contact_id && $id < 0)
{
@ -2752,7 +2784,7 @@ class Contacts extends Contacts\Storage
// different url with different etag parameter will force a reload
if (isset($_GET['etag']))
{
\EGroupware\Api\Session::cache_control(30*86400); // cache for 30 days
Session::cache_control(30*86400); // cache for 30 days
}
// if servers send a If-None-Match header, response with 304 Not Modified, if etag matches
if (isset($_SERVER['HTTP_IF_NONE_MATCH']) && $_SERVER['HTTP_IF_NONE_MATCH'] === $etag)
@ -2771,7 +2803,7 @@ class Contacts extends Contacts\Storage
}
exit();
}
Egw::redirect(\EGroupware\Api\Image::find('addressbook','photo'));
Egw::redirect(Image::find('addressbook','photo'));
}
/**

View File

@ -164,6 +164,8 @@ class calendar_owner_etemplate_widget extends Etemplate\Widget\Taglist
public static function ajax_search($search_text=null, array $search_options = [])
{
// close session now, to not block other user actions
$GLOBALS['egw']->session->commit_session();
$bo = new calendar_bo();
@ -193,7 +195,7 @@ class calendar_owner_etemplate_widget extends Etemplate\Widget\Taglist
{
$owngroup_options = $options+array('account_type'=>'owngroups');
$own_groups = Api\Accounts::link_query('',$owngroup_options);
$account_options = $options + array('account_type' => 'both');
$account_options = $options + ['account_type' => 'both', 'tag_list' => true];
$_results += $remove_contacts = Api\Accounts::link_query($search_text, $account_options);
$total += $account_options['total'];
if (!empty($_REQUEST['checkgrants']))
@ -314,11 +316,23 @@ class calendar_owner_etemplate_widget extends Etemplate\Widget\Taglist
break;
case 'c':
case '':
$contact = $contacts_obj->read($type === '' ? 'account:'.$id : $id, true);
if (is_array($contact)) $value['icon'] = Api\Framework::link('/api/avatar.php', array(
'contact_id' => $contact['id'],
'etag' => $contact['etag'] ? $contact['etag'] : 1
));
// check if link-search already returned either icon or (l|f)name and only if not, query contact again
if (!(isset($value['icon']) || isset($value['lname']) && isset($value['fname'])) &&
($contact = $contacts_obj->read($type === '' ? 'account:'.$id : $id, true)))
{
if (Api\Contacts::hasPhoto($contact))
{
$value['icon'] = Api\Framework::link('/api/avatar.php', array(
'contact_id' => $contact['id'],
'etag' => $contact['etag'] ? $contact['etag'] : 1
));
}
else
{
$value['lname'] = $contact['n_family'];
$value['fname'] = $contact['n_given'];
}
}
if($id < 0)
{
$value['resources'] = array_map('strval',$GLOBALS['egw']->accounts->members($id, true));