Merge remote-tracking branch 'origin/master'

This commit is contained in:
Milan 2023-07-20 16:40:50 +02:00
commit c170c44168
18 changed files with 166 additions and 128 deletions

View File

@ -56,7 +56,7 @@ class addressbook_wizard_import_contacts_csv extends importexport_wizard_basic_i
unset($this->mapping_fields['jpegphoto']); // can't cvs import that
// Add in special handled fields
$this->mapping_fields[lang('Special')] = addressbook_import_contacts_csv::$special_fields;
$this->mapping_fields += addressbook_import_contacts_csv::$special_fields;
// Actions
$this->actions = array(

View File

@ -2336,8 +2336,9 @@ class CalDAV extends HTTP_WebDAV_Server
$this->store_request = $_SERVER['REQUEST_METHOD'] != 'POST' ||
!self::isFileUpload() ||
substr($_SERVER['CONTENT_TYPE'], 0, 5) == 'text/';
ob_start();
}
// unconditionally start output-buffering to fix problems with huge multiget reports from TB110 AB
ob_start();
parent::ServeRequest($prefix);
if (self::$request_starttime) self::log_request();

View File

@ -78,13 +78,13 @@ class Contact extends Entry
'__default__' => array(
'options' => array(
'bday' => array('type' => 'date', 'options' => 'Y-m-d'),
'owner' => array('type' => 'select-account', 'options' => ''),
'modifier' => array('type' => 'select-account', 'options' => ''),
'creator' => array('type' => 'select-account', 'options' => ''),
'modifed' => array('type' => 'date-time', 'options' => ''),
'created' => array('type' => 'date-time', 'options' => ''),
'cat_id' => array('type' => 'select-cat', 'options' => ''),
'__default__' => array('type' => 'label', 'options' => ''),
'owner' => array('type' => 'select-account'),
'modifier' => array('type' => 'select-account'),
'creator' => array('type' => 'select-account'),
'modifed' => array('type' => 'date-time'),
'created' => array('type' => 'date-time'),
'cat_id' => array('type' => 'select-cat'),
'__default__' => array('type' => 'label'),
),
'noLang' => true,
),

View File

@ -69,7 +69,7 @@ abstract class Entry extends Transformer
$form_name = self::form_name($cname, $this->id);
$prefixed_id = (substr($this->id, 0, 1) == self::ID_PREFIX ? $this->id : self::ID_PREFIX . $this->id);
$data_id = $attrs['value'] ? self::form_name($cname, $attrs['value']) : self::form_name($cname, $prefixed_id);
$data_id = !empty($attrs['value']) ? self::form_name($cname, $attrs['value']) : self::form_name($cname, $prefixed_id);
// No need to proceed
if(!$data_id) return;
@ -151,9 +151,9 @@ abstract class Entry extends Transformer
$value =& $data;
if(!is_array($value)) return $value;
foreach(array($attrs['field']) + explode(':',$attrs['alternate_fields']) as $field)
foreach(array($attrs['field']) + explode(':', ($attrs['alternate_fields'] ?? '')) as $field)
{
if($value[$field])
if(!empty($value[$field]))
{
return $value[$field];
}
@ -175,12 +175,12 @@ abstract class Entry extends Transformer
*/
protected function customfield($attrs, &$data)
{
list($app, $type) = explode('-',$attrs['type']);
$data_id = $attrs['value'] ?: $attrs['id'];
list($app, $type) = explode('-', $attrs['type']);
$data_id = isset($attrs['value']) ? $attrs['value'] : $attrs['id'];
$id = is_array($data) ? static::get_array($data, $data_id) : $data;
if(!$app || !$type || !$GLOBALS['egw_info']['apps'][$app] || !$id ||
if(!$app || !$type || !isset($GLOBALS['egw_info']['apps'][$app]) || !$id ||
// Simple CF, already there
$data[$attrs['field']]
isset($data[$attrs['field']])
)
{
return;
@ -194,7 +194,7 @@ abstract class Entry extends Transformer
$merge = new $classname();
$replacement_field = '$$'.$attrs['field'].'$$';
$replacements = $merge->get_app_replacements($app, $id, $replacement_field);
$data[$attrs['field']] = $replacements[$replacement_field];
$data[$attrs['field']] = $replacements[$replacement_field] ?? '';
}
catch(\Exception $e)
{
@ -212,7 +212,7 @@ abstract class Entry extends Transformer
protected function regex($attrs, &$data)
{
$value =& $this->get_data_field($attrs, $data);
if(!$attrs['regex'] || !$value)
if(!isset($attrs['regex']) || !$value)
{
return;
}

View File

@ -219,15 +219,18 @@ abstract class Transformer extends Etemplate\Widget
elseif(is_array($action))
{
// case matches --> run all actions
if (isset($action[$attrs[$attr]]) || !isset($action[$attrs[$attr]]) && isset($action['__default__']))
if(isset($attrs[$attr]) && isset($action[$attrs[$attr]]) || (!isset($attrs[$attr]) || !isset($action[$attrs[$attr]])) && isset($action['__default__']))
{
$actions = isset($action[$attrs[$attr]]) ? $action[$attrs[$attr]] : $action['__default__'];
$actions = isset($attrs[$attr]) && isset($action[$attrs[$attr]]) ? $action[$attrs[$attr]] : $action['__default__'];
if(!is_array($actions))
{
$attrs[$attr] = $actions;
$actions = array($attr => $actions);
}
if (self::DEBUG) error_log(__METHOD__."(attr='$attr', action=".array2string($action).") attrs['$attr']=='{$attrs[$attr]}' --> running actions");
if(self::DEBUG)
{
error_log(__METHOD__ . "(attr='$attr', action=" . array2string($action) . ") attrs['$attr']=='{$attrs[$attr]}' --> running actions");
}
foreach($actions as $attr => $action)
{
$this->action($attr, $action, $attrs);

View File

@ -331,6 +331,7 @@ class IncludeMgr
// we will do no further processing but just include the file
// XXX: Is this case still used? If yes, it will not work with
// adding the ctime to all js files...
$args = '';
if (is_array($file))
{
foreach($file as $name => $val)

View File

@ -60,10 +60,10 @@ class Http
static function schema()
{
return !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' ||
$_SERVER['SERVER_PORT'] == 443 ||
!empty($GLOBALS['egw_info']['server']['enforce_ssl']) ||
$_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https' ?
'https' : 'http';
$_SERVER['SERVER_PORT'] == 443 ||
!empty($GLOBALS['egw_info']['server']['enforce_ssl']) ||
isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https' ?
'https' : 'http';
}
/**

View File

@ -1683,13 +1683,14 @@ abstract class Merge
{
if(str_starts_with($cf_sub, '#'))
{
$expand_sub_cfs[$cf[$index]] .= '$$' . $cf_sub . '$$ ';
$expand_sub_cfs[$cf[$index]] = (isset($expand_sub_cfs[$cf[$index]]) ? $expand_sub_cfs[$cf[$index]] : '') .
'$$' . $cf_sub . '$$ ';
}
}
foreach($cf as $index => $field)
{
if($cfs[$field])
if(isset($cfs[$field]))
{
if(in_array($cfs[$field]['type'], array_keys($GLOBALS['egw_info']['apps'])))
{
@ -1719,18 +1720,18 @@ abstract class Merge
}
// Get replacements for that application
if(!$app_replacements[$field])
if(!isset($app_replacements[$field]))
{
// If we send the real content it can result in infinite loop of lookups
// so we send only the used fields
$content = $expand_sub_cfs[$field] ?? $matches[0][$index];
$app_replacements[$field] = $this->get_app_replacements($field_app, $values['#' . $field], $content);
}
$replacements[$placeholders[$index]] = $app_replacements[$field]['$$' . $sub[$index] . '$$'];
$replacements[$placeholders[$index]] = $app_replacements[$field]['$$' . $sub[$index] . '$$'] ?? '';
}
else
{
if($cfs[$field]['type'] == 'date' || $cfs[$field]['type'] == 'date-time')
if(isset($cfs[$field]) && ($cfs[$field]['type'] == 'date' || $cfs[$field]['type'] == 'date-time'))
{
$this->date_fields[] = '#' . $field;
}

View File

@ -1450,6 +1450,19 @@ div.et2_vfsPath li img {
visibility: visible;
}
/* Category indents in select options */
sl-menu-item.cat_level1::part(label) {
padding-left: var(--sl-spacing-medium, 1em);
}
sl-menu-item.cat_level2::part(label) {
padding-left: calc(2 * var(--sl-spacing-medium, 1em));
}
sl-menu-item.cat_level3::part(label) {
padding-left: calc(3 * var(--sl-spacing-medium, 1em));
}
.egw_tooltip {
position: fixed;
border: 1px solid #897f51;

View File

@ -134,7 +134,7 @@ class calendar_holidays
{
ksort($data);
}
error_log(__METHOD__."('$country', $year, $end_year) took ". number_format(microtime(true)-$starttime, 3).'s to fetch '.count(call_user_func_array('array_merge', $years)).' events');
//error_log(__METHOD__."('$country', $year, $end_year) took ". number_format(microtime(true)-$starttime, 3).'s to fetch '.count(call_user_func_array('array_merge', $years)).' events');
unset($starttime);
return $until_year ? $years : $years[$year];

View File

@ -51,7 +51,7 @@ export class CalendarOwner extends Et2StaticSelectMixin(Et2Select)
// Start fetch of users
const type = this.egw().preference('account_selection', 'common');
if(!type || type == "none" || type == "selectbox")
if(!type || type == "none")
{
return;
}
@ -65,6 +65,7 @@ export class CalendarOwner extends Et2StaticSelectMixin(Et2Select)
else
{
fetch.push(this.egw().accounts('accounts').then(options => {this.static_options = this.static_options.concat(cleanSelectOptions(options))}));
fetch.push(this.egw().accounts('groups').then(options => {this.static_options = this.static_options.concat(cleanSelectOptions(options))}));
}
this.fetchComplete = Promise.all(fetch)
.then(() => this._renderOptions());

View File

@ -4010,8 +4010,17 @@ export class CalendarApp extends EgwApp
var all_loaded = this.sidebox_et2 !== null;
// Avoid home portlets using our templates, and get them right
if(_et2.uniqueId.indexOf('portlet') === 0) return;
if(_et2.uniqueId === 'calendar-add') return;
if(_et2.uniqueId.indexOf('portlet') === 0)
{
return;
}
// Skip templates not involved in main view
if(['calendar.conflicts', 'calendar.add'].includes(_name))
{
return;
}
// Flag to make sure we don't hide non-view templates
var view_et2 = false;

View File

@ -540,7 +540,7 @@ export class et2_calendar_view extends et2_valueWidget
{
// Create event
this._drag_create_event()
}, 100);
}, 500);
}
/**

View File

@ -115,48 +115,39 @@
</grid>
</template>
<template id="filemanager.file.eacl" template="" lang="" group="0" version="1.9.001">
<grid width="100%" spacing="10">
<columns>
<column width="120"/>
<column/>
<column/>
</columns>
<rows>
<row valign="top" height="200">
<groupbox span="all">
<caption label="Extended access control list"/>
<grid width="100%" overflow="auto" id="eacl">
<columns>
<column width="80"/>
<column width="80"/>
<column width="20%"/>
<column width="16"/>
</columns>
<rows>
<row class="th">
<et2-description value="Owner"></et2-description>
<et2-description value="Rights"></et2-description>
<et2-description value="Inherited"></et2-description>
<et2-description></et2-description>
</row>
<row class="row" disabled="!@1">
<et2-select-account id="${row}[owner]" readonly="true"></et2-select-account>
<et2-select id="${row}[rights]" readonly="true"></et2-select>
<et2-description id="${row}[path]"></et2-description>
<et2-button label="Delete" id="delete[$row_cont[ino]-$row_cont[owner]]" onclick="et2_dialog.confirm(widget,'Delete this extended ACL?','Delete')" image="delete"></et2-button>
</row>
</rows>
</grid>
</groupbox>
</row>
<row valign="bottom" disabled="!@is_owner">
<et2-select-account class="filemanager-file_filemanager-file-eaclowner eaclAccount" label="Owner" id="eacl_owner" emptyLabel="select one" accountType="both"></et2-select-account>
<et2-select class="eaclRights" statustext="You can only grant additional rights, you can NOT take rights away!" label="Rights" id="eacl[rights]"></et2-select>
<et2-button label="Add" id="button[eacl]" image="add"></et2-button>
</row>
</rows>
</grid>
</template>
<et2-vbox class="full-height">
<groupbox style="flex-grow: 1">
<caption label="Extended access control list"/>
<grid width="100%" overflow="auto" id="eacl">
<columns>
<column width="80"/>
<column width="80"/>
<column width="20%"/>
<column width="16"/>
</columns>
<rows>
<row class="th">
<et2-description value="Owner"></et2-description>
<et2-description value="Rights"></et2-description>
<et2-description value="Inherited"></et2-description>
<et2-description></et2-description>
</row>
<row class="row" disabled="!@1">
<et2-select-account id="${row}[owner]" readonly="true"></et2-select-account>
<et2-select id="${row}[rights]" readonly="true"></et2-select>
<et2-description id="${row}[path]"></et2-description>
<et2-button label="Delete" id="delete[$row_cont[ino]-$row_cont[owner]]" onclick="et2_dialog.confirm(widget,'Delete this extended ACL?','Delete')" image="delete"></et2-button>
</row>
</rows>
</grid>
</groupbox>
<et2-hbox valign="bottom" disabled="!@is_owner">
<et2-select-account class="filemanager-file_filemanager-file-eaclowner eaclAccount" label="Owner" id="eacl_owner" emptyLabel="select one" accountType="both" placement="top"></et2-select-account>
<et2-select class="eaclRights" statustext="You can only grant additional rights, you can NOT take rights away!" label="Rights" id="eacl[rights]"></et2-select>
<et2-button label="Add" id="button[eacl]" image="add"></et2-button>
</et2-hbox>
</et2-vbox>
</template>
<template id="filemanager.file.preview" template="" lang="" group="0" version="1.5.001">
<grid width="100%" spacing="10" overflow="auto">
<columns>
@ -259,48 +250,49 @@
<et2-button align="right" statustext="Enter setup user and password to get root rights" label="Superuser" id="sudouser" onclick="jQuery('.superuser').css('display','inline'); document.getElementById(form::name('sudo[user]')).focus();" image="superuser" noSubmit="true"></et2-button>
</et2-hbox>
</row>
<row>
<groupbox class="superuser">
<caption label="Enter setup user and password"/>
<grid>
<columns>
<column/>
<column/>
</columns>
<rows>
<row>
<et2-description for="sudo[user]" value="User"></et2-description>
<et2-textbox id="sudo[user]"></et2-textbox>
</row>
<row>
<et2-description for="sudo[passwd]" value="Password"></et2-description>
<et2-password id="sudo[passwd]" autocomplete="on"></et2-password>
</row>
<row>
<et2-description></et2-description>
<et2-hbox>
<et2-button label="Submit" id="button[setup]"></et2-button>
<et2-button label="Cancel" onclick="jQuery('.superuser').hide();" noSubmit="true"></et2-button>
</et2-hbox>
<row>
<groupbox class="superuser">
<caption label="Enter setup user and password"/>
<grid>
<columns>
<column/>
<column/>
</columns>
<rows>
<row>
<et2-description for="sudo[user]" value="User"></et2-description>
<et2-textbox id="sudo[user]"></et2-textbox>
</row>
<row>
<et2-description for="sudo[passwd]" value="Password"></et2-description>
<et2-password id="sudo[passwd]" autocomplete="on"></et2-password>
</row>
<row>
<et2-description></et2-description>
<et2-hbox>
<et2-button label="Submit" id="button[setup]"></et2-button>
<et2-button label="Cancel" onclick="jQuery('.superuser').hide();" noSubmit="true"></et2-button>
</et2-hbox>
</row>
</rows>
</grid>
</groupbox>
</row>
</rows>
</grid>
<styles>
.eaclAccount select,.eaclRights select { width: 160px; }
.superuser {
position: absolute;
top: 130px;
left: 120px;
width: 200px;
background-color: white;
z-index: 1;
display: none;
}
</styles>
</template>
</row>
</rows>
</grid>
</groupbox>
</row>
</rows>
</grid>
<styles>
.full-height { height: 100% }
.full-height > fieldset { flex-grow: 1; }
.superuser {
position: absolute;
top: 130px;
left: 120px;
width: 200px;
background-color: white;
z-index: 1;
display: none;
}
</styles>
</template>
</overlay>

View File

@ -351,7 +351,24 @@ class importexport_export_csv implements importexport_iface_export_record
$names = array();
foreach($record->$name as $_name)
{
$option = $selects[$name][$_name];
$select_options = $selects[$name] ?? [];
$option = '';
foreach($select_options as $key => $select_option)
{
if(is_array($select_option) && isset($select_option['value']) && $select_option['value'] == $name && isset($select_option['label']))
{
$option = $select_option['label'];
break;
}
else
{
if($key == $_name && !is_array($select_option))
{
$option = $select_option;
break;
}
}
}
$names[] = lang(is_array($option) && $option['label'] ? $option['label'] : $option);
}
$record->$name = implode(', ', $names);

View File

@ -357,9 +357,9 @@ class mail_integration {
foreach($mailcontent['attachments'] as $key => $attachment)
{
$data_attachments[$key] = array(
'name' => $mailcontent['attachments'][$key]['name'],
'type' => $mailcontent['attachments'][$key]['type'],
'size' => $mailcontent['attachments'][$key]['size'],
'name' => $attachment['filename'] ?? $mailcontent['attachments'][$key]['name'],
'type' => $mailcontent['attachments'][$key]['type'],
'size' => $mailcontent['attachments'][$key]['size'],
'tmp_name' => $mailcontent['attachments'][$key]['tmp_name']
);
if ($uid && !$mailcontent['attachments'][$key]['add_raw'])

View File

@ -1207,13 +1207,13 @@ app.classes.mail = AppJS.extend(
},
{
id: 'saveOneToVfs',
label: 'Save in Filemanager',
label: 'Save to Filemanager',
icon: 'filemanager/navbar',
value: 'saveOneToVfs'
},
{
id: 'saveAllToVfs',
label: 'Save all to Filemanager',
label: 'Save all attachments to Filemanager',
icon: 'mail/save_all',
value: 'saveAllToVfs'
},

View File

@ -502,7 +502,7 @@ rule with priority mail en rule with priority
rules mail en rules
s/mime encryption failed because no certificate has been found for sender address: %1 mail en S/MIME Encryption failed because no certificate has been found for sender address: %1
save all mail en Save all
save all attachments to filemanager mail en Save all attachments to filemanager
save all attachments to filemanager mail en Save all to filemanager
save as calendar mail en Save as Calendar
save as default mail en save as default
save as draft mail en Save as Draft
@ -518,7 +518,7 @@ save message to disk mail en Save Message to disk
save of message %1 failed. could not save message to folder %2 due to: %3 mail en Save of message %1 failed. Could not save message to folder %2 due to: %3
save the drafted message as eml file into vfs mail en Save the drafted message as eml file into VFS
save to disk mail en Save to disk
save to filemanager mail en Save to filemanager
save to filemanager mail en Save in filemanager
save: mail en Save:
saves subscription changes mail en Save subscription changes
saves this acl mail en Save this ACL