Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F117738597
D5847.1775155788.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
34 KB
Referenced Files
None
Subscribers
None
D5847.1775155788.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D5847: Health Checks
Attached
Detach File
Event Timeline