Page MenuHomePhorge

D5847.1775155788.diff
No OneTemporary

Authored By
Unknown
Size
34 KB
Referenced Files
None
Subscribers
None

D5847.1775155788.diff

diff --git a/plugins/calendar/calendar.php b/plugins/calendar/calendar.php
--- a/plugins/calendar/calendar.php
+++ b/plugins/calendar/calendar.php
@@ -97,6 +97,9 @@
} elseif ($this->rc->task != 'login') {
// default startup routine
$this->add_hook('startup', [$this, 'startup']);
+
+ // health check in CLI
+ $this->add_hook('health_check', [$this, 'health_check']);
}
$this->add_hook('user_delete', [$this, 'user_delete']);
@@ -304,6 +307,23 @@
return $this->ical;
}
+ /**
+ * Health check action handler
+ */
+ public function health_check($args)
+ {
+ $this->load_driver();
+
+ if (method_exists($this->driver, 'healthcheck')) {
+ $args['checks']['Calendar'] = function ($opts) {
+ // @phpstan-ignore-next-line
+ return $this->driver->healthcheck($opts['user'] ?? '', $opts['pass'] ?? '');
+ };
+ }
+
+ return $args;
+ }
+
/**
* Get properties of the calendar this user has specified as default
*/
@@ -3010,7 +3030,9 @@
$calendars = $this->driver->list_calendars(calendar_driver::FILTER_PERSONAL);
$events = $this->driver->load_events($day_start->format('U'), $day_end->format('U'), null, array_keys($calendars));
- usort($events, function ($a, $b) { return $a['start'] > $b['start'] ? 1 : -1; });
+ usort($events, function ($a, $b) {
+ return $a['start'] > $b['start'] ? 1 : -1;
+ });
$before = $after = [];
foreach ($events as $event) {
@@ -3499,7 +3521,9 @@
if ($attendee['status'] == 'DELEGATED') {
//Also find and copy the delegatee
$delegatee_email = $attendee['email'];
- $delegatees = array_filter($event['attendees'], function ($attendee) use ($delegatee_email) { return $attendee['role'] != 'ORGANIZER' && $this->itip->compare_email($attendee['delegated-from'], $delegatee_email); });
+ $delegatees = array_filter($event['attendees'], function ($attendee) use ($delegatee_email) {
+ return $attendee['role'] != 'ORGANIZER' && $this->itip->compare_email($attendee['delegated-from'], $delegatee_email);
+ });
if ($delegatee = $this->itip->find_attendee_by_email($event['attendees'], 'delegated-from', $attendee['email'])) {
$update_attendees[] = $delegatee;
diff --git a/plugins/calendar/drivers/caldav/caldav_driver.php b/plugins/calendar/drivers/caldav/caldav_driver.php
--- a/plugins/calendar/drivers/caldav/caldav_driver.php
+++ b/plugins/calendar/drivers/caldav/caldav_driver.php
@@ -562,7 +562,9 @@
$newcats = array_udiff(
array_keys($categories),
array_keys($old_categories),
- function ($a, $b) { return strcasecmp($a, $b); }
+ function ($a, $b) {
+ return strcasecmp($a, $b);
+ }
);
if (!empty($newcats)) {
@@ -748,4 +750,12 @@
return kolab_utils::folder_form($form, $folder ?? null, 'calendar', []);
}
+
+ /**
+ * CalDAV connection health check
+ */
+ public function healthcheck($user, $pass)
+ {
+ return $this->storage->dav->healthcheck($user, $pass);
+ }
}
diff --git a/plugins/calendar/drivers/kolab/kolab_driver.php b/plugins/calendar/drivers/kolab/kolab_driver.php
--- a/plugins/calendar/drivers/kolab/kolab_driver.php
+++ b/plugins/calendar/drivers/kolab/kolab_driver.php
@@ -1676,7 +1676,9 @@
$newcats = array_udiff(
array_keys($categories),
array_keys($old_categories),
- function ($a, $b) { return strcasecmp($a, $b); }
+ function ($a, $b) {
+ return strcasecmp($a, $b);
+ }
);
if (!empty($newcats)) {
diff --git a/plugins/kolab/Kolab/Client.php b/plugins/kolab/Kolab/Client.php
--- a/plugins/kolab/Kolab/Client.php
+++ b/plugins/kolab/Kolab/Client.php
@@ -7,6 +7,8 @@
*/
class Client
{
+ protected static $lastError;
+
protected static $cached_requests = [
'get:api/v4/config/webmail',
'get:api/v4/users/%d/delegators',
@@ -123,9 +125,11 @@
return $json;
} else {
- $rcube->raise_error("Request to $base_uri/$path failed [$code]: " . (string) $response->getBody(), true);
+ self::$lastError = "Request to $base_uri/$path failed [$code]";
+ $rcube->raise_error(self::$lastError . ': ' . (string) $response->getBody(), true);
}
} catch (\Exception $e) {
+ self::$lastError = $e->getMessage();
$rcube->raise_error($e, true, false);
}
}
@@ -285,6 +289,30 @@
}
*/
+ /**
+ * Configuration/Health check
+ */
+ public static function healthcheck(string $user, string $pass): array
+ {
+ $post = [
+ 'email' => $user,
+ 'password' => $pass,
+ 'mode' => 'fast',
+ ];
+
+ if (strlen($pass) > 0) {
+ $response = self::request('POST', 'api/auth/login', [], $post);
+ } else {
+ $response = self::request('GET', 'api/health/liveness');
+ }
+
+ if (empty($response)) {
+ return [false, self::$lastError ?? "Unknown error"];
+ }
+
+ return [true, null];
+ }
+
/**
* Clear all cache entries
*/
diff --git a/plugins/kolab/Kolab/HealthCheck.php b/plugins/kolab/Kolab/HealthCheck.php
new file mode 100644
--- /dev/null
+++ b/plugins/kolab/Kolab/HealthCheck.php
@@ -0,0 +1,76 @@
+<?php
+
+namespace Kolab;
+
+/**
+ * Provides health checkers for various Kolab connections
+ */
+class HealthCheck extends Feature
+{
+ /**
+ * Feature initialization
+ */
+ public function init()
+ {
+ $this->plugin->add_hook('health_check', [$this, 'healthCheck']);
+ }
+
+ /**
+ * Handler for 'health_check' hook
+ */
+ public function healthCheck($args): array
+ {
+ $args['checks']['Kolab-API'] = function ($opts) {
+ return $this->checkAPI($opts);
+ };
+
+ $args['checks']['Kolab-Collabora'] = function ($opts) {
+ return $this->checkCollabora($opts);
+ };
+
+ // TODO: Check for Chwala connecting to Cockpit API?
+
+ return $args;
+ }
+
+ /**
+ * Check connection to the Kolab API
+ */
+ public function checkAPI($args): array
+ {
+ return Client::healthcheck($args['user'] ?? '', $args['pass'] ?? '');
+ }
+
+ /**
+ * Check connection from Chwala to the Collabora server
+ */
+ public function checkCollabora($args): array
+ {
+ try {
+ if (!file_exists($file = '/etc/roundcubemail/chwala.inc.php')) {
+ throw new \Exception("Config file ({$file}) not found");
+ }
+
+ $config = [];
+ include $file;
+
+ $url = $config['fileapi_wopi_office'] ?? ''; // @phpstan-ignore-line
+
+ if (!strlen($url)) {
+ throw new \Exception("Collabora URL not configured");
+ }
+
+ $client = $this->rc->get_http_client([]);
+ $response = $client->get(rtrim($url, '/') . '/hosting/discovery');
+ $body = $response->getBody()->getContents();
+
+ if (!str_contains($body, '<wopi-discovery>')) {
+ throw new \Exception("Invalid XML content from {$url}");
+ }
+
+ return [true, null];
+ } catch (\Exception $e) {
+ return [false, $e->getMessage()];
+ }
+ }
+}
diff --git a/plugins/kolab/kolab.php b/plugins/kolab/kolab.php
--- a/plugins/kolab/kolab.php
+++ b/plugins/kolab/kolab.php
@@ -30,6 +30,7 @@
'Kolab\Contacts',
'Kolab\Delegation',
'Kolab\Helpdesk',
+ 'Kolab\HealthCheck',
'Kolab\Users',
];
diff --git a/plugins/kolab_2fa/lib/Kolab2FA/Storage/LDAP.php b/plugins/kolab_2fa/lib/Kolab2FA/Storage/LDAP.php
--- a/plugins/kolab_2fa/lib/Kolab2FA/Storage/LDAP.php
+++ b/plugins/kolab_2fa/lib/Kolab2FA/Storage/LDAP.php
@@ -211,7 +211,9 @@
$new_attrs = $old_attrs = Net_LDAP3::normalize_entry($user_attrs);
$new_attrs[$role_attr] = array_merge(
array_unique($auth_roles),
- array_filter((array)$old_attrs[$role_attr], function ($f) use ($internals) { return !in_array($f, $internals); })
+ array_filter((array)$old_attrs[$role_attr], function ($f) use ($internals) {
+ return !in_array($f, $internals);
+ })
);
$result = $this->conn->modify_entry($this->userdn, $old_attrs, $new_attrs);
diff --git a/plugins/kolab_addressbook/drivers/carddav/carddav_contacts.php b/plugins/kolab_addressbook/drivers/carddav/carddav_contacts.php
--- a/plugins/kolab_addressbook/drivers/carddav/carddav_contacts.php
+++ b/plugins/kolab_addressbook/drivers/carddav/carddav_contacts.php
@@ -273,7 +273,9 @@
}
// sort groups by name
- uasort($groups, function ($a, $b) { return strcoll($a['name'], $b['name']); });
+ uasort($groups, function ($a, $b) {
+ return strcoll($a['name'], $b['name']);
+ });
return array_values($groups);
}
diff --git a/plugins/kolab_addressbook/drivers/carddav/carddav_contacts_driver.php b/plugins/kolab_addressbook/drivers/carddav/carddav_contacts_driver.php
--- a/plugins/kolab_addressbook/drivers/carddav/carddav_contacts_driver.php
+++ b/plugins/kolab_addressbook/drivers/carddav/carddav_contacts_driver.php
@@ -303,4 +303,14 @@
'share_invitation' => $abook->share_invitation,
];
}
+
+ /**
+ * CardDAV connection health check
+ */
+ public function healthcheck($user, $pass)
+ {
+ $storage = self::get_storage();
+
+ return $storage->dav->healthcheck($user, $pass);
+ }
}
diff --git a/plugins/kolab_addressbook/drivers/kolab/kolab_contacts.php b/plugins/kolab_addressbook/drivers/kolab/kolab_contacts.php
--- a/plugins/kolab_addressbook/drivers/kolab/kolab_contacts.php
+++ b/plugins/kolab_addressbook/drivers/kolab/kolab_contacts.php
@@ -332,7 +332,9 @@
}
// sort groups by name
- uasort($groups, function ($a, $b) { return strcoll($a['name'], $b['name']); });
+ uasort($groups, function ($a, $b) {
+ return strcoll($a['name'], $b['name']);
+ });
return array_values($groups);
}
diff --git a/plugins/kolab_addressbook/kolab_addressbook.php b/plugins/kolab_addressbook/kolab_addressbook.php
--- a/plugins/kolab_addressbook/kolab_addressbook.php
+++ b/plugins/kolab_addressbook/kolab_addressbook.php
@@ -114,6 +114,8 @@
$this->add_texts('localization');
$this->add_hook('preferences_list', [$this, 'prefs_list']);
$this->add_hook('preferences_save', [$this, 'prefs_save']);
+ } elseif ($this->rc->task == 'cli') {
+ $this->add_hook('health_check', [$this, 'health_check']);
}
if ($this->driver instanceof kolab_contacts_driver) {
@@ -123,6 +125,20 @@
}
}
+ /**
+ * Health check action handler
+ */
+ public function health_check($args)
+ {
+ if (method_exists($this->driver, 'healthcheck')) {
+ $args['checks']['Contacts'] = function ($opts) {
+ return $this->driver->healthcheck($opts['user'] ?? '', $opts['pass'] ?? '');
+ };
+ }
+
+ return $args;
+ }
+
/**
* Handler for the addressbooks_list hook.
*
@@ -211,7 +227,9 @@
$kolab .= $this->folder_tree_html($tree, $sources, $jsdata);
}
} else {
- $filter = function ($source) { return !empty($source['kolab']) && empty($source['hidden']); };
+ $filter = function ($source) {
+ return !empty($source['kolab']) && empty($source['hidden']);
+ };
foreach (array_filter($sources, $filter) as $j => $source) {
$id = strval(strlen($source['id']) ? $source['id'] : $j);
$kolab .= $this->addressbook_list_item($id, $source, $jsdata) . '</li>';
@@ -220,8 +238,12 @@
$out .= $kolab . $spec;
- $this->rc->output->set_env('contactgroups', array_filter($jsdata, function ($src) { return isset($src['type']) && $src['type'] == 'group'; }));
- $this->rc->output->set_env('address_sources', array_filter($jsdata, function ($src) { return !isset($src['type']) || $src['type'] != 'group'; }));
+ $this->rc->output->set_env('contactgroups', array_filter($jsdata, function ($src) {
+ return isset($src['type']) && $src['type'] == 'group';
+ }));
+ $this->rc->output->set_env('address_sources', array_filter($jsdata, function ($src) {
+ return !isset($src['type']) || $src['type'] != 'group';
+ }));
$args['content'] = html::tag('ul', $args, $out, html::$common_attrib);
return $args;
diff --git a/plugins/kolab_files/kolab_files.php b/plugins/kolab_files/kolab_files.php
--- a/plugins/kolab_files/kolab_files.php
+++ b/plugins/kolab_files/kolab_files.php
@@ -66,6 +66,8 @@
$this->add_hook('startup', [$this, 'startup']);
$this->add_hook('preferences_save', [$this, 'preferences_save']);
+
+ $this->add_hook('health_check', [$this, 'health_check']);
}
/**
@@ -120,6 +122,22 @@
}
}
+ /**
+ * Health check action handler
+ */
+ public function health_check($args)
+ {
+ $args['checks']['Kolab-Files'] = function ($opts) {
+ $engine = $this->engine();
+ if ($engine === false) {
+ return [false, "Files engine misconfigured"];
+ }
+
+ return $engine->healthcheck($opts['user'] ?? '', $opts['pass'] ?? '');
+ };
+
+ return $args;
+ }
/**
* Refresh hook handler
*/
diff --git a/plugins/kolab_files/lib/kolab_files_engine.php b/plugins/kolab_files/lib/kolab_files_engine.php
--- a/plugins/kolab_files/lib/kolab_files_engine.php
+++ b/plugins/kolab_files/lib/kolab_files_engine.php
@@ -1033,7 +1033,7 @@
/**
* Get API token for current user session, authenticate if needed
*/
- public function get_api_token($configure = true)
+ public function get_api_token($configure = true, $conf = [])
{
$token = $_SESSION['kolab_files_token'] ?? null;
$time = $_SESSION['kolab_files_time'] ?? null;
@@ -1067,7 +1067,13 @@
// Go with authenticate request
$url->setQueryVariables(['method' => 'authenticate', 'version' => self::API_VERSION]);
$request->setUrl($url);
- $request->setAuth($this->rc->user->get_username(), $this->rc->decrypt($_SESSION['password']));
+
+ $pass = (string) ($conf['pass'] ?? $this->rc->decrypt($_SESSION['password']));
+ $user = (string) ($conf['user'] ?? $this->rc->user->get_username());
+
+ if ($user !== '' && $pass !== '') {
+ $request->setAuth($user, $pass);
+ }
// Allow plugins (e.g. kolab_sso) to modify the request
$this->rc->plugins->exec_hook('chwala_authenticate', ['request' => $request]);
@@ -1182,8 +1188,10 @@
// set Referer which is used as an origin for cross-window
// communication with document editor iframe
- $host = $_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER['HTTP_HOST'];
- $this->request->setHeader('referer', $host);
+ if (isset($_SERVER['REQUEST_SCHEME']) && isset($_SERVER['HTTP_HOST'])) {
+ $host = $_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER['HTTP_HOST'];
+ $this->request->setHeader('referer', $host);
+ }
return $this->request;
}
@@ -1217,6 +1225,28 @@
}
}
+ /**
+ * File server connection health check
+ */
+ public function healthcheck($user, $pass)
+ {
+ if ($pass !== '') {
+ $result = $this->get_api_token(false, ['user' => $user, 'pass' => $pass]);
+ } else {
+ $result = false;
+ try {
+ $request = $this->get_request(['method' => 'ping']);
+ $response = $request->send();
+ $status = $response->getStatus();
+ $result = $status === 200 && str_contains($response->getBody(), '401');
+ } catch (Exception $e) {
+ $error = $e->getMessage();
+ }
+ }
+
+ return [$result, $result ? null : ($error ?? "Failed base URL: {$this->url_srv}/api")];
+ }
+
/**
* Handler for main files interface (Files task)
*/
diff --git a/plugins/kolab_notes/drivers/kolab/kolab_notes_driver.php b/plugins/kolab_notes/drivers/kolab/kolab_notes_driver.php
--- a/plugins/kolab_notes/drivers/kolab/kolab_notes_driver.php
+++ b/plugins/kolab_notes/drivers/kolab/kolab_notes_driver.php
@@ -886,7 +886,9 @@
{
$config = kolab_storage_config::get_instance();
$tags = $config->get_tags($uid);
- $tags = array_map(function ($v) { return $v['name']; }, $tags);
+ $tags = array_map(function ($v) {
+ return $v['name'];
+ }, $tags);
return $tags;
}
@@ -981,7 +983,9 @@
// convert link references into simple URIs
if (array_key_exists('links', $note)) {
- $object['links'] = array_map(function ($link) { return is_array($link) ? $link['uri'] : strval($link); }, $note['links']);
+ $object['links'] = array_map(function ($link) {
+ return is_array($link) ? $link['uri'] : strval($link);
+ }, $note['links']);
} else {
if ($old) {
$object['links'] = $old['links'] ?? null;
diff --git a/plugins/kolab_notes/drivers/webdav/webdav_notes_driver.php b/plugins/kolab_notes/drivers/webdav/webdav_notes_driver.php
--- a/plugins/kolab_notes/drivers/webdav/webdav_notes_driver.php
+++ b/plugins/kolab_notes/drivers/webdav/webdav_notes_driver.php
@@ -587,7 +587,9 @@
// convert link references into simple URIs
if (array_key_exists('links', $object)) {
- $object['links'] = array_map(function ($link) { return is_array($link) ? $link['uri'] : strval($link); }, $object['links']);
+ $object['links'] = array_map(function ($link) {
+ return is_array($link) ? $link['uri'] : strval($link);
+ }, $object['links']);
} else {
if ($old) {
$object['links'] = $old['links'] ?? [];
diff --git a/plugins/kolab_tags/drivers/database/Driver.php b/plugins/kolab_tags/drivers/database/Driver.php
--- a/plugins/kolab_tags/drivers/database/Driver.php
+++ b/plugins/kolab_tags/drivers/database/Driver.php
@@ -219,7 +219,9 @@
$tag_members = self::resolve_members($tag);
foreach ((array) $tag_members as $folder => $_uids) {
- array_walk($_uids, function (&$uid, $key, $folder) { $uid .= '-' . $folder; }, $folder);
+ array_walk($_uids, function (&$uid, $key, $folder) {
+ $uid .= '-' . $folder;
+ }, $folder);
foreach (array_intersect($uids, $_uids) as $uid) {
$message_tags[$uid][] = $tag['uid'];
diff --git a/plugins/kolab_tags/drivers/kolab/Driver.php b/plugins/kolab_tags/drivers/kolab/Driver.php
--- a/plugins/kolab_tags/drivers/kolab/Driver.php
+++ b/plugins/kolab_tags/drivers/kolab/Driver.php
@@ -162,7 +162,9 @@
$tag['uids'] = kolab_storage_config::resolve_members($tag, true);
foreach ((array) $tag['uids'] as $folder => $_uids) {
- array_walk($_uids, function (&$uid, $key, $folder) { $uid .= '-' . $folder; }, $folder);
+ array_walk($_uids, function (&$uid, $key, $folder) {
+ $uid .= '-' . $folder;
+ }, $folder);
foreach (array_intersect($uids, $_uids) as $uid) {
$message_tags[$uid][] = $tag['uid'];
diff --git a/plugins/libcalendaring/lib/libcalendaring_vcalendar.php b/plugins/libcalendaring/lib/libcalendaring_vcalendar.php
--- a/plugins/libcalendaring/lib/libcalendaring_vcalendar.php
+++ b/plugins/libcalendaring/lib/libcalendaring_vcalendar.php
@@ -489,7 +489,9 @@
case 'EXDATE':
if (!empty($value)) {
- $exdates = array_map(function ($_) { return is_array($_) ? $_[0] : $_; }, self::convert_datetime($prop, true));
+ $exdates = array_map(function ($_) {
+ return is_array($_) ? $_[0] : $_;
+ }, self::convert_datetime($prop, true));
if (!empty($event['recurrence']['EXDATE'])) {
$event['recurrence']['EXDATE'] = array_merge($event['recurrence']['EXDATE'], $exdates);
} else {
@@ -500,7 +502,9 @@
case 'RDATE':
if (!empty($value)) {
- $rdates = array_map(function ($_) { return is_array($_) ? $_[0] : $_; }, self::convert_datetime($prop, true));
+ $rdates = array_map(function ($_) {
+ return is_array($_) ? $_[0] : $_;
+ }, self::convert_datetime($prop, true));
if (!empty($event['recurrence']['RDATE'])) {
$event['recurrence']['RDATE'] = array_merge($event['recurrence']['RDATE'], $rdates);
} else {
diff --git a/plugins/libkolab/lib/kolab_dav_client.php b/plugins/libkolab/lib/kolab_dav_client.php
--- a/plugins/libkolab/lib/kolab_dav_client.php
+++ b/plugins/libkolab/lib/kolab_dav_client.php
@@ -49,6 +49,7 @@
protected $path;
protected $rc;
protected $responseHeaders = [];
+ protected $responseCode = null;
/**
* Object constructor
@@ -87,13 +88,16 @@
];
$this->responseHeaders = [];
+ $this->responseCode = null;
$path = $this->normalize_location($path);
try {
$request = $this->initRequest($this->url . $path, $method, $request_config);
- $request->setAuth($this->user, $this->password);
+ if ($this->password !== null && $this->password !== '') {
+ $request->setAuth($this->user, $this->password);
+ }
if ($body) {
$request->setBody($body);
@@ -128,6 +132,7 @@
}
$this->responseHeaders = $response->getHeader();
+ $this->responseCode = $code;
return $noxml ? $body : $this->parseXML($body);
} catch (Exception $e) {
@@ -141,12 +146,12 @@
*
* @return array|false Homes locations or False on error
*/
- public function discover()
+ public function discover($force = false)
{
if ($cache = $this->get_cache()) {
$cache_key = "discover." . md5($this->url);
- if ($homes = $cache->get($cache_key)) {
+ if (!$force && ($homes = $cache->get($cache_key))) {
return $homes;
}
}
@@ -253,6 +258,25 @@
return null;
}
+ /**
+ * Health check.
+ *
+ * @return array
+ */
+ public function healthcheck(string $user, string $pass)
+ {
+ $this->setCredentials($user, $pass);
+
+ if ($pass !== '') {
+ $result = $this->discover(true) !== false;
+ } else {
+ $result = $this->request('', 'OPTIONS');
+ $result = $result !== false || $this->responseCode === 401;
+ }
+
+ return [$result, $result ? null : "Failed base URL: {$this->url}"];
+ }
+
/**
* Get list of folders of specified type.
*
@@ -1111,6 +1135,18 @@
return $response !== false;
}
+ /**
+ * Set user name and password
+ *
+ * @param string $user Username
+ * @param string $password Password
+ */
+ public function setCredentials($user, $password): void
+ {
+ $this->user = $user;
+ $this->password = $password;
+ }
+
/**
* Parse XML content
*/
diff --git a/plugins/libkolab/lib/kolab_format_contact.php b/plugins/libkolab/lib/kolab_format_contact.php
--- a/plugins/libkolab/lib/kolab_format_contact.php
+++ b/plugins/libkolab/lib/kolab_format_contact.php
@@ -146,7 +146,9 @@
$vemails->push(new Email($email['address'], intval($type)));
}
} else {
- $vemails = self::array2vector(array_map(function ($v) { return $v['address']; }, $object['email']));
+ $vemails = self::array2vector(array_map(function ($v) {
+ return $v['address'];
+ }, $object['email']));
}
$this->obj->setEmailAddresses($vemails);
diff --git a/plugins/libkolab/lib/kolab_storage.php b/plugins/libkolab/lib/kolab_storage.php
--- a/plugins/libkolab/lib/kolab_storage.php
+++ b/plugins/libkolab/lib/kolab_storage.php
@@ -977,7 +977,9 @@
$folders = self::$imap->list_folders($root, $mbox, null, null, !empty($postfilter));
if (!empty($postfilter)) {
- $folders = array_filter($folders, function ($folder) use ($postfilter) { return !preg_match($postfilter, $folder); });
+ $folders = array_filter($folders, function ($folder) use ($postfilter) {
+ return !preg_match($postfilter, $folder);
+ });
$folders = self::$imap->sort_folder_list($folders);
}
diff --git a/plugins/libkolab/lib/kolab_storage_cache.php b/plugins/libkolab/lib/kolab_storage_cache.php
--- a/plugins/libkolab/lib/kolab_storage_cache.php
+++ b/plugins/libkolab/lib/kolab_storage_cache.php
@@ -1139,7 +1139,9 @@
$extra_args[] = '?';
}
- $cols = implode(', ', array_map(function ($n) { return "`{$n}`"; }, $cols));
+ $cols = implode(', ', array_map(function ($n) {
+ return "`{$n}`";
+ }, $cols));
$extra_args = count($extra_args) ? ', ' . implode(', ', $extra_args) : '';
$result = $this->db->query(
@@ -1174,8 +1176,12 @@
}
if ($buffer && (!$msguid || (strlen($buffer) + strlen($line) > $this->max_sql_packet()))) {
- $columns = implode(', ', array_map(function ($n) { return "`{$n}`"; }, $cols));
- $update = implode(', ', array_map(function ($i) { return "`{$i}` = VALUES(`{$i}`)"; }, array_slice($cols, 2)));
+ $columns = implode(', ', array_map(function ($n) {
+ return "`{$n}`";
+ }, $cols));
+ $update = implode(', ', array_map(function ($i) {
+ return "`{$i}` = VALUES(`{$i}`)";
+ }, array_slice($cols, 2)));
$result = $this->db->query(
"INSERT INTO `{$this->cache_table}` ($columns) VALUES $buffer"
diff --git a/plugins/libkolab/lib/kolab_storage_cache_configuration.php b/plugins/libkolab/lib/kolab_storage_cache_configuration.php
--- a/plugins/libkolab/lib/kolab_storage_cache_configuration.php
+++ b/plugins/libkolab/lib/kolab_storage_cache_configuration.php
@@ -86,7 +86,9 @@
foreach ($query as $idx => $param) {
// convert category filter
if ($param[0] == 'category') {
- $param[2] = array_map(function ($n) { return 'category:' . $n; }, (array) $param[2]);
+ $param[2] = array_map(function ($n) {
+ return 'category:' . $n;
+ }, (array) $param[2]);
$query[$idx][0] = 'tags';
$query[$idx][2] = count($param[2]) > 1 ? $param[2] : $param[2][0];
diff --git a/plugins/libkolab/lib/kolab_storage_config.php b/plugins/libkolab/lib/kolab_storage_config.php
--- a/plugins/libkolab/lib/kolab_storage_config.php
+++ b/plugins/libkolab/lib/kolab_storage_config.php
@@ -644,7 +644,9 @@
while (!empty($uids)) {
$chunk = array_splice($uids, 0, $limit);
- $chunk = array_map(function ($v) { return ['member', '=', $v]; }, $chunk);
+ $chunk = array_map(function ($v) {
+ return ['member', '=', $v];
+ }, $chunk);
$filter = [
['type', '=', 'relation'],
diff --git a/plugins/libkolab/lib/kolab_storage_dav_cache.php b/plugins/libkolab/lib/kolab_storage_dav_cache.php
--- a/plugins/libkolab/lib/kolab_storage_dav_cache.php
+++ b/plugins/libkolab/lib/kolab_storage_dav_cache.php
@@ -534,7 +534,9 @@
$extra_args[] = '?';
}
- $cols = implode(', ', array_map(function ($n) { return "`{$n}`"; }, $cols));
+ $cols = implode(', ', array_map(function ($n) {
+ return "`{$n}`";
+ }, $cols));
$extra_args = count($extra_args) ? ', ' . implode(', ', $extra_args) : '';
$result = $this->db->query(
@@ -569,14 +571,20 @@
}
if ($buffer && ($force || (strlen($buffer) + strlen($line) > $this->max_sql_packet()))) {
- $columns = implode(', ', array_map(function ($n) { return "`{$n}`"; }, $cols));
+ $columns = implode(', ', array_map(function ($n) {
+ return "`{$n}`";
+ }, $cols));
if ($this->db->db_provider == 'postgres') {
$update = "ON CONFLICT (folder_id, uid) DO UPDATE SET "
- . implode(', ', array_map(function ($i) { return "`{$i}` = EXCLUDED.`{$i}`"; }, array_slice($cols, 2)));
+ . implode(', ', array_map(function ($i) {
+ return "`{$i}` = EXCLUDED.`{$i}`";
+ }, array_slice($cols, 2)));
} else {
$update = "ON DUPLICATE KEY UPDATE "
- . implode(', ', array_map(function ($i) { return "`{$i}` = VALUES(`{$i}`)"; }, array_slice($cols, 2)));
+ . implode(', ', array_map(function ($i) {
+ return "`{$i}` = VALUES(`{$i}`)";
+ }, array_slice($cols, 2)));
}
$result = $this->db->query("INSERT INTO `{$this->cache_table}` ($columns) VALUES $buffer $update");
diff --git a/plugins/libkolab/lib/kolab_subscriptions.php b/plugins/libkolab/lib/kolab_subscriptions.php
--- a/plugins/libkolab/lib/kolab_subscriptions.php
+++ b/plugins/libkolab/lib/kolab_subscriptions.php
@@ -195,7 +195,9 @@
// Update subscriptions if any folder was removed from the list
if (!empty($update)) {
- $data = array_map(function ($v) { return $v[0]; }, $result);
+ $data = array_map(function ($v) {
+ return $v[0];
+ }, $result);
$this->update_subscriptions($deviceid, $type, $data);
}
}
diff --git a/plugins/libkolab/libkolab.php b/plugins/libkolab/libkolab.php
--- a/plugins/libkolab/libkolab.php
+++ b/plugins/libkolab/libkolab.php
@@ -262,7 +262,7 @@
}
// proxy User-Agent string
- $request->setHeader('user-agent', $_SERVER['HTTP_USER_AGENT']);
+ $request->setHeader('user-agent', $_SERVER['HTTP_USER_AGENT'] ?? 'Libkolab HTTP client');
self::$http_requests[$key] = $request;
}
diff --git a/plugins/tasklist/drivers/caldav/tasklist_caldav_driver.php b/plugins/tasklist/drivers/caldav/tasklist_caldav_driver.php
--- a/plugins/tasklist/drivers/caldav/tasklist_caldav_driver.php
+++ b/plugins/tasklist/drivers/caldav/tasklist_caldav_driver.php
@@ -1590,4 +1590,12 @@
return kolab_utils::folder_form($form, $folder ?? null, 'tasklist', $hidden_fields);
}
+
+ /**
+ * CalDAV connection health check
+ */
+ public function healthcheck($user, $pass)
+ {
+ return $this->storage->dav->healthcheck($user, $pass);
+ }
}
diff --git a/plugins/tasklist/drivers/kolab/tasklist_kolab_driver.php b/plugins/tasklist/drivers/kolab/tasklist_kolab_driver.php
--- a/plugins/tasklist/drivers/kolab/tasklist_kolab_driver.php
+++ b/plugins/tasklist/drivers/kolab/tasklist_kolab_driver.php
@@ -569,7 +569,9 @@
{
$config = kolab_storage_config::get_instance();
$tags = $config->get_tags();
- $backend_tags = array_map(function ($v) { return $v['name']; }, $tags);
+ $backend_tags = array_map(function ($v) {
+ return $v['name'];
+ }, $tags);
return array_values(array_unique(array_merge($this->tags, $backend_tags)));
}
@@ -1201,7 +1203,9 @@
} else {
$config = kolab_storage_config::get_instance();
$tags = $config->get_tags($object['uid']);
- $object['tags'] = array_map(function ($v) { return $v['name']; }, $tags);
+ $object['tags'] = array_map(function ($v) {
+ return $v['name'];
+ }, $tags);
}
}
diff --git a/plugins/tasklist/tasklist.php b/plugins/tasklist/tasklist.php
--- a/plugins/tasklist/tasklist.php
+++ b/plugins/tasklist/tasklist.php
@@ -97,6 +97,7 @@
$this->add_hook('startup', [$this, 'startup']);
$this->add_hook('user_delete', [$this, 'user_delete']);
+ $this->add_hook('health_check', [$this, 'health_check']);
}
/**
@@ -217,6 +218,23 @@
$this->rc->output->set_env('tasklist_driver', $driver_name);
}
+ /**
+ * Health check action handler
+ */
+ public function health_check($args)
+ {
+ $this->load_driver();
+
+ if (method_exists($this->driver, 'healthcheck')) {
+ $args['checks']['Tasklist'] = function ($opts) {
+ // @phpstan-ignore-next-line
+ return $this->driver->healthcheck($opts['user'] ?? '', $opts['pass'] ?? '');
+ };
+ }
+
+ return $args;
+ }
+
/**
* Dispatcher for task-related actions initiated by the client
*/
@@ -753,7 +771,9 @@
// convert link references into simple URIs
if (array_key_exists('links', $rec)) {
- $rec['links'] = array_map(function ($link) { return is_array($link) ? $link['uri'] : strval($link); }, (array)$rec['links']);
+ $rec['links'] = array_map(function ($link) {
+ return is_array($link) ? $link['uri'] : strval($link);
+ }, (array)$rec['links']);
}
// convert invalid data

File Metadata

Mime Type
text/plain
Expires
Thu, Apr 2, 6:49 PM (19 h, 17 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
18820349
Default Alt Text
D5847.1775155788.diff (34 KB)

Event Timeline