Merge branch 'master' into web-components

This commit is contained in:
nathan
2021-12-01 15:31:45 -07:00
17 changed files with 160 additions and 50 deletions

View File

@ -764,7 +764,7 @@ class Contacts extends Contacts\Storage
$data[$name] = DateTime::server2user($data[$name], $date_format);
}
}
$data['photo'] = $this->photo_src($data['id'],!empty($data['jpegphoto']) || (($data['files']??0) & self::FILES_BIT_PHOTO), '', $data['etag'] ?? null);
$data['photo'] = $this->photo_src($data['id'] ?? null,!empty($data['jpegphoto']) || (($data['files']??0) & self::FILES_BIT_PHOTO), '', $data['etag'] ?? null);
// set freebusy_uri for accounts
if (empty($data['freebusy_uri']) && empty($data['owner']) && !empty($data['account_id']) && empty($GLOBALS['egw_setup']))

View File

@ -482,13 +482,13 @@ class Sql extends Api\Storage
$owner = isset($filter['owner']) ? $filter['owner'] : (isset($criteria['owner']) ? $criteria['owner'] : null);
// fix cat_id criteria to search in comma-separated multiple cats and return subcats
if (is_array($criteria) && ($cats = $criteria['cat_id']))
if (is_array($criteria) && !empty($criteria['cat_id']))
{
$criteria = array_merge($criteria, $this->_cat_search($criteria['cat_id']));
unset($criteria['cat_id']);
}
// fix cat_id filter to search in comma-separated multiple cats and return subcats
if (($cats = $filter['cat_id']))
if (!empty($filter['cat_id']))
{
if ($filter['cat_id'][0] == '!')
{
@ -680,7 +680,7 @@ class Sql extends Api\Storage
{
$extra_cols[$key] = "$shared_with AS shared_with";
}
switch ((string)$filter['shared_with'])
switch ($filter['shared_with'] ?? '')
{
case '': // filter not set
break;

View File

@ -655,7 +655,7 @@ class Storage
//error_log(__METHOD__.'('.array2string($criteria,true).','.array2string($only_keys).",'$order_by','$extra_cols','$wildcard','$empty','$op',".array2string($start).','.array2string($filter,true).",'$join')");
// Handle 'None' country option
if(is_array($filter) && $filter['adr_one_countrycode'] == '-custom-')
if(is_array($filter) && isset($filter['adr_one_countrycode']) && $filter['adr_one_countrycode'] === '-custom-')
{
$filter[] = 'adr_one_countrycode IS NULL';
unset($filter['adr_one_countrycode']);

View File

@ -1630,9 +1630,10 @@ class Db
$not_null = is_array($column_definitions) && isset($column_definitions[$col]['nullable']) ? !$column_definitions[$col]['nullable'] : false;
$maxlength = null;
if ($truncate_varchar)
if ($truncate_varchar && !is_int($col) && isset($column_definitions[$col]) &&
in_array($column_definitions[$col]['type'], ['varchar','ascii']))
{
$maxlength = in_array($column_definitions[$col]['type'], array('varchar','ascii')) ? $column_definitions[$col]['precision'] : null;
$maxlength = $column_definitions[$col]['precision'];
}
// dont use IN ( ), if there's only one value, it's slower for MySQL
if (is_array($data) && count($data) <= 1)

View File

@ -67,6 +67,10 @@ class Backup
* @var string|boolean
*/
var $egw_tables = false;
/**
* Regular expression to identify a Guacamole table OR view
*/
const GUACAMOLE_REGEXP = '/^guacamole_/';
/**
* Backup directory.
*
@ -360,6 +364,8 @@ class Backup
if (substr($this->db->Type,0,5) == 'mysql')
{
$this->db->query("SET SESSION sql_mode=(SELECT REPLACE(REPLACE(@@sql_mode,'STRICT_ALL_TABLES',''),'STRICT_TRANS_TABLES',''))", __LINE__, __FILE__);
// disable foreign key checks, in case Guacamole is installed
$this->db->query('SET FOREIGN_KEY_CHECKS = 0');
}
else
{
@ -371,7 +377,9 @@ class Backup
foreach($this->adodb->MetaTables('TABLES') as $table)
{
if ($this->system_tables && preg_match($this->system_tables,$table) ||
$this->egw_tables && !preg_match($this->egw_tables,$table))
$this->egw_tables && !preg_match($this->egw_tables,$table) ||
// do NOT drop Guacamole tables and views
preg_match(self::GUACAMOLE_REGEXP, $table))
{
continue;
}
@ -513,7 +521,7 @@ class Backup
if (substr($line,0,9) == 'version: ')
{
// currenty not used: $api_version = trim(substr($line,9));
// currently not used: $api_version = trim(substr($line,9));
continue;
}
if (substr($line,0,9) == 'charset: ')
@ -536,6 +544,12 @@ class Backup
$this->schemas = json_php_unserialize(trim(substr($line,8)));
foreach($this->schemas as $table_name => $schema)
{
// do NOT create GUACAMOLE tables, just truncate them (as we have no abstraction to create the foreign keys)
if (preg_match(self::GUACAMOLE_REGEXP, $table_name))
{
$this->db->query('TRUNCATE TABLE '.$this->db->name_quote($table_name));
continue;
}
// if column is longtext in current schema, convert text to longtext, in case user already updated column
foreach($schema['fd'] as $col => &$def)
{
@ -566,7 +580,7 @@ class Backup
{
if ($data['type'] == 'blob') $blobs[] = $col;
}
// check if we have an old PostgreSQL backup useing 't'/'f' for bool values
// check if we have an old PostgreSQL backup using 't'/'f' for bool values
// --> convert them to MySQL and our new PostgreSQL format of 1/0
$bools = array();
foreach($this->schemas[$table]['fd'] as $col => $def)

View File

@ -119,22 +119,22 @@ class Etemplate extends Etemplate\Widget\Template
{
if (!empty($extra['data']) && is_array($extra['data']))
{
$content = array_merge($content, $extra['data']);
$content = array_merge_recursive($content, $extra['data']);
}
if (!empty($extra['preserve']) && is_array($extra['preserve']))
{
$preserv = array_merge($preserv, $extra['preserve']);
$preserv = array_merge_recursive($preserv, $extra['preserve']);
}
if (!empty($extra['readonlys']) && is_array($extra['readonlys']))
{
$readonlys = array_merge($readonlys, $extra['readonlys']);
$readonlys = array_merge_recursive($readonlys, $extra['readonlys']);
}
if (!empty($extra['sel_options']) && is_array($extra['sel_options']))
{
$sel_options = array_merge($sel_options, $extra['sel_options']);
$sel_options = array_merge_recursive($sel_options, $extra['sel_options']);
}
}
}

View File

@ -569,7 +569,10 @@ class Widget
$types = $paramType instanceof \ReflectionUnionType
? $paramType->getTypes()
: [$paramType];
if(in_array('array', array_map(fn(\ReflectionNamedType $t) => $t->getName(), $types)) && !is_array($params[$index]))
if(in_array('array', array_map(static function(\ReflectionNamedType $t)
{
return $t->getName();
}, $types)) && !is_array($params[$index]))
{
error_log("$method_name expects an array for {$param->getPosition()}: {$param->getName()}");
$params[$index] = (array)$params[$index];

View File

@ -75,11 +75,32 @@ class File extends Etemplate\Widget
return;
}
if (!($template = Template::instance(self::$request->template['name'], self::$request->template['template_set'],
self::$request->template['version'], self::$request->template['load_via'])))
{
// Can't use callback
error_log("Could not get template for file upload, callback skipped");
try {
if (!($template = Template::instance(self::$request->template['name'], self::$request->template['template_set'],
self::$request->template['version'], self::$request->template['load_via'])))
{
// Can't use callback
error_log("Could not get template for file upload, callback skipped");
}
}
catch (\Error $e) {
// retry 3 times, in case the problem (Call to undefined method EGroupware\Api\Etemplate\Widget\Vfs::set_attrs()) is caused by something internal in PHP 8.0
if (!isset($_REQUEST['retry']) || $_REQUEST['retry'] < 3)
{
$url = Api\Header\Http::schema().'://'.Api\Header\Http::host().$_SERVER['REQUEST_URI'];
if (strpos($url, '&retry=') === false)
{
$url .= '&retry=1';
}
else
{
$url = preg_replace('/&retry=\d+/', '&retry='.($_REQUEST['retry']+1), $url);
}
header('Location: '.$url);
http_response_code(307);
exit;
}
throw new \Error('Error instantiating template '.json_encode(self::$request->template).', $_REQUEST='.json_encode($_REQUEST).': '.$e->getMessage(), $e->getCode(), $e);
}
$file_data = array();