Merge branch 'master' into web-components

This commit is contained in:
nathan 2021-11-10 10:25:51 -07:00
commit ed66beaf8f
15 changed files with 82 additions and 24 deletions

View File

@ -1855,7 +1855,10 @@ class addressbook_ui extends addressbook_bo
if ($query['grouped_view']) // view the contacts of one organisation only
{
if (strpos($query['grouped_view'],'*AND*') !== false) $query['grouped_view'] = str_replace('*AND*','&',$query['grouped_view']);
$fields = explode(',',$GLOBALS['egw_info']['user']['preferences']['addressbook']['duplicate_fields']);
if (!is_array($fields = $GLOBALS['egw_info']['user']['preferences']['addressbook']['duplicate_fields'] ?? []))
{
$fields = explode(',', $fields);
}
foreach(explode('|||',$query['grouped_view']) as $part)
{
list($name,$value) = explode(':',$part,2);
@ -2911,7 +2914,10 @@ class addressbook_ui extends addressbook_bo
*/
public function ajax_check_values($values, $name, $own_id=0)
{
$fields = explode(',',$GLOBALS['egw_info']['user']['preferences']['addressbook']['duplicate_fields']);
if (!is_array($fields = $GLOBALS['egw_info']['user']['preferences']['addressbook']['duplicate_fields'] ?? []))
{
$fields = explode(',', $fields);
}
$threshold = (int)$GLOBALS['egw_info']['user']['preferences']['addressbook']['duplicate_threshold'];
$ret = array('doublicates' => array(), 'msg' => null);

View File

@ -431,12 +431,13 @@ class admin_mail
'acc_folder_archive' => array('', 'archive'),
) as $name => $common_names)
{
unset($content[$name]);
// first check special-use attributes
if (($special_use = array_shift($common_names)))
{
foreach((array)$attributes[$special_use] as $mailbox)
{
if (empty($content[$name]) || strlen($mailbox) < strlen($content[$name]))
if (empty($content[$name]) || is_string($mailbox) && strlen($mailbox) < strlen($content[$name]))
{
$content[$name] = $mailbox;
}
@ -450,7 +451,7 @@ class admin_mail
$delimiter = !empty($data['delimiter']) ? $data['delimiter'] : '.';
$name_parts = explode($delimiter, strtolower($mailbox));
if (array_intersect($name_parts, $common_names) &&
(empty($content[$name]) || strlen($mailbox) < strlen($content[$name]) && substr($content[$name], 0, 6) != 'INBOX'.$delimiter))
(empty($content[$name]) || is_string($mailbox) && strlen($mailbox) < strlen($content[$name]) && substr($content[$name], 0, 6) != 'INBOX'.$delimiter))
{
//error_log(__METHOD__."() $mailbox --> ".substr($name, 11).' folder');
$content[$name] = $mailbox;

View File

@ -168,6 +168,7 @@ class Widget
else
{
libxml_use_internal_errors(true);
libxml_clear_errors();
$reader = new XMLReader();
if (!$reader->XML($xml))
{

View File

@ -405,7 +405,7 @@ class Customfields extends Transformer
$all_readonly = $this->is_readonly($cname, $form_name);
$value_in = self::get_array($content, $form_name);
// if we have no id / use self::GLOBAL_ID, we have to set $value_in in global namespace for regular widgets validation to find
if (!$this->id) $content = array_merge($content, $value_in);
if (!$this->id) $content = array_merge($content, (array)$value_in);
//error_log(__METHOD__."($cname, ...) form_name=$form_name, use-private={$this->attrs['use-private']}, value_in=".array2string($value_in));
if($this->getElementAttribute($form_name, 'customfields'))
{

View File

@ -403,8 +403,8 @@ class History
*/
public static function needs_diff($name, $value)
{
// No diff on encrypted content
if(strpos($value, static::BEGIN_PGP) == 0 && strpos($value, static::END_PGP) !== FALSE)
// No diff on arrays or encrypted content
if (is_array($value) || strpos($value, static::BEGIN_PGP) == 0 && strpos($value, static::END_PGP) !== FALSE)
{
return false;
}

View File

@ -947,9 +947,14 @@ class Translation
{
return utf8_decode($data);
}
if (self::$mbstring && !$prefer_iconv && ($data = @mb_convert_encoding($data,$to,$from)) != '')
{
return $data;
try {
if (self::$mbstring && !$prefer_iconv && ($data = @mb_convert_encoding($data, $to, $from)) != '')
{
return $data;
}
}
catch (\ValueError $e) {
// ignore encodings unknown to mb_convert_encoding
}
if (function_exists('iconv'))
{

View File

@ -1829,12 +1829,13 @@ class calendar_boupdate extends calendar_bo
}
// Update history
$event = $this->read($cal_id, $recur_date, $ignore_acl, 'server');
$tracking = new calendar_tracking($this);
$tracking->track($event, $old_event);
if (($event = $this->read($cal_id, $recur_date, $ignore_acl, 'server')))
{
$tracking = new calendar_tracking($this);
$tracking->track($event, $old_event);
}
// notify the link-class about the update, as other apps may be subscribed to it
Link::notify_update('calendar',$event['id'],$event,"update");
Link::notify_update('calendar', $cal_id, $event, "update");
}
return $Ok;
}

View File

@ -600,8 +600,8 @@ class calendar_ical extends calendar_boupdate
if (empty($event['whole_day']))
{
// Hack for CalDAVTester to export duration instead of endtime
if ($tzid == 'UTC' && $event['end'] - $event['start'] <= 86400)
$attributes['duration'] = $event['end'] - $event['start'];
if ($tzid == 'UTC' && ($duration = Api\DateTime::to($event['end'], 'ts') - Api\DateTime::to($event['start'], 'ts')) <= 86400)
$attributes['duration'] = $duration;
else
$attributes['DTEND'] = self::getDateTime($event['end'],$tzid,$parameters['DTEND']);
}
@ -871,6 +871,24 @@ class calendar_ical extends calendar_boupdate
{
$attr_name = 'X-EGROUPWARE-'.$attr_name;
}
// fix certain stock fields like GEO, which are not in EGroupware schema, but Horde Icalendar requires a certain format
switch($name)
{
case '##GEO':
if (!is_array($value))
{
if (strpos($value, ';'))
{
list($lat, $long) = explode(';', $value);
}
else
{
list($long, $lat) = explode(',', $value);
}
$value = ['latitude' => $lat, 'logitude' => $long];
}
break;
}
if ($value[0] === '{' && ($attr = json_decode($value, true)) && is_array($attr))
{
// check if attribute was stored compressed --> uncompress it

View File

@ -779,6 +779,7 @@ class calendar_so
}
if(isset($params['sql_filter']['cal_id']))
{
if (!is_array($params['query'])) $params['query'] = [];
$params['query']['cal_id'] = $params['sql_filter']['cal_id'];
$where[] = $this->db->column_data_implode(", ", [$this->cal_table.'.cal_id' => $params['sql_filter']['cal_id']], True, False);
unset($params['sql_filter']['cal_id']);

View File

@ -2192,7 +2192,7 @@ class calendar_uiforms extends calendar_ui
break;
case 'cancel':
// first participant is the (external) organizer (our iCal parser adds owner first!)
$parts = $event['participants'];
$parts = $event['participants'] ?? [];
unset($parts[$existing_event['owner']]);
$event['ical_sender_uid'] = key($parts);
if (empty($existing_event['id']) || !$this->bo->check_perms(Acl::DELETE, $existing_event['id']))

View File

@ -20,7 +20,7 @@
<row>
<box id="portlets">
<!-- Box wrapper needed to get box to auto-repeat -->
<box id="${row}"><portlet id="${_cont[id]}" title="${_cont[title]}" color="@color" parent_node="home-index_portlets" settings="@settings" width="@width" height="@height" row="@row" col="@col" value="@content" class="@class"/></box>
<box id="${row}"><portlet id="${_cont[id]}" title="$_cont[title]" color="@color" parent_node="home-index_portlets" settings="@settings" width="@width" height="@height" row="@row" col="@col" value="@content" class="@class"/></box>
</box>
</row>
</rows>

View File

@ -412,9 +412,30 @@ class infolog_ical extends infolog_bo
{
if (substr($name, 0, 2) == '##')
{
if (($v = json_php_unserialize($value)) && is_array($v))
{
$value = $v;
}
// fix certain stock fields like GEO, which are not in EGroupware schema, but Horde Icalendar requires a certain format
switch($name)
{
case '##GEO':
if (!is_array($value))
{
if (strpos($value, ';') !== false)
{
list($lat, $long) = explode(';', $value);
}
else
{
list($long, $lat) = explode(',', $value);
}
$value = ['latitude' => $lat, 'logitude' => $long];
}
break;
}
if ($name[2] == ':')
{
if (($v = json_php_unserialize($value)) && is_array($v)) $value = $v;
foreach((array)$value as $compvData)
{
$comp = Horde_Icalendar::newComponent(substr($name,3), $vevent);
@ -422,9 +443,9 @@ class infolog_ical extends infolog_bo
$vevent->addComponent($comp);
}
}
elseif (($attr = json_php_unserialize($value)) && is_array($attr))
elseif (is_array($value))
{
$vevent->setAttribute(substr($name, 2), $attr['value'], $attr['params'], true, $attr['values']);
$vevent->setAttribute(substr($name, 2), $value['value'], $value['params'], true, $value['values']);
}
else
{

View File

@ -212,6 +212,10 @@ class infolog_tracking extends Api\Storage\Tracking
{
$id = ' #'.$data['info_id'];
}
if (is_array($data['info_cat']))
{
$data['info_cat'] = array_shift($data['info_cat']);
}
foreach(array(
'info_type' => lang($this->infolog->enums['type'][$data['info_type']]).$id,
'info_from' => $data['info_from'],

View File

@ -806,7 +806,7 @@ class mail_zpush implements activesync_plugin_write, activesync_plugin_sendmail,
}
}
//$BCCmail='';
if (count($mailAddr)>0) $mailObject->forceBccHeader();
if (!empty($mailAddr)) $mailObject->forceBccHeader();
//$BCCmail = $mailObject->AddrAppend("Bcc",$mailAddr);
foreach($folderArray as $folderName) {
if($this->mail->isSentFolder($folderName)) {

View File

@ -750,7 +750,7 @@ class resources_bo
$end = $start->format('ts') + 86399;
} else {
$start = $start->format('ts');
$end = $start + ($cal_info['duration']);
$end = $start + (int)$cal_info['duration'];
}
// search events matching our timestamps