[horde] Horde 6 upgrade Windows

admin at wap.dynu.net admin at wap.dynu.net
Wed Oct 28 12:52:07 UTC 2026


I ran into a bug today. I was trying to share a calendar with an outside 
resource and it failed with a 404 because the url was malformed - 
missing the user. Here's an example:

https://domain.tld/horde/rpc.php/kronolith//<calendar_id>.ics

Notice the double slash where the user should be. So I fired up Claude, 
which gave me this working fix. Sorry if the .md ticks don't come 
through properly. Emclient doesn't seem to handle md properly.
-----------

That's the bug, and it's in the Horde 6 code. In `EditCalendar.php`, 
when the calendar has an owner, it works out the DAV user name (`$user`) 
and then never adds it to the URL:

```php
$webdavUrl = Horde::url($webdavUrl, true, -1);
if ($calendar->get('owner')) {
     $user = $registry->convertUsername($calendar->get('owner'), false);
     try {
         $user = $injector->getInstance('Horde_Core_Hooks')
             ->callHook('davusername', 'horde', [$user, false]);
     } catch (Horde_Exception_HookNotSet $e) {
     }
} else {
     $webdavUrl .= '-system-';
}
$webdavUrl .= '/' . $calendar->getName() . '.ics';
```

Only the no-owner branch appends anything, so owned calendars get 
`kronolith/` + `/` + `<id>.ics`, which is the double slash. The Horde 5 
version added the owner directly (`. $registry->convertUsername(...)`), 
so this is a regression from the refactor that added the `davusername` 
hook. The calendar list code in `Internal.php` is not affected. Your 
data was fine all along.

**Fix.** In 
`X:\xampp\htdocs\horde-six\vendor\horde\kronolith\lib\Form\EditCalendar.php`, 
add one line after the `try`/`catch` inside the `if`:

```php
         if ($calendar->get('owner')) {
             $user = $registry->convertUsername($calendar->get('owner'), 
false);
             try {
                 $user = $injector->getInstance('Horde_Core_Hooks')
                     ->callHook('davusername', 'horde', [$user, false]);
             } catch (Horde_Exception_HookNotSet $e) {
             }
             $webdavUrl .= $user;
         } else {
             $webdavUrl .= '-system-';
         }
```

Reload the calendar's edit page and the URL should read 
`.../rpc.php/kronolith/<user>/<id>.ics`, the one that already works for 
you. Like the Content patch, this is lost when `horde/kronolith` is 
updated, so redo the edit if the doubled slash comes back.

It's worth adding to your mailing-list summary as a short extra item:

G. Kronolith 5.0.3: the "WebDAV/ICS Subscription URL" shown in Edit 
Calendar is wrong for calendars with an owner 
(`.../rpc.php/kronolith//<id>.ics`, which returns 404). In 
`lib/Form/EditCalendar.php` the computed DAV user name `$user` is never 
appended to `$webdavUrl` (the Horde 5 code did append the owner). The 
fix is `$webdavUrl .= $user;` inside the `if ($calendar->get('owner'))` 
branch.




------ Original Message ------
>From "admin at wap.dynu.net" <admin at wap.dynu.net>
To "horde at lists.horde.org" <horde at lists.horde.org>
Date 10/28/2026 8:33:00 AM
Subject Re: [horde] Horde 6 upgrade Windows

>>>Yes, of course. :-)
>>>
>>>
>>>------ Original Message ------
>>>From "Ralf Lang" <ralf.lang at gmail.com>
>>>To admin at wap.dynu.net
>>>Cc "horde" <horde at lists.horde.org>
>>>Date 10/28/2026 4:43:11 AM
>>>Subject Re: [horde] Horde 6 upgrade Windows
>>>
>>>Hello,
>>>
>>>I will look into the problems reported. May I use your instructions on the website?
>>>
>>>admin at wap.dynu.net <admin at wap.dynu.net> schrieb am Di., 27. Okt. 2026, 13:48:
>>>Hi, everyone. I don't have any problems - everything is working as
>>>expected so far. I finally upgraded to Horde 6 and since I'm on Windows,
>>>I thought I'd share the quirks I ran into. Claude AI helped me upgrade
>>>and after finishing I asked for this summary below. Problems A & D are
>>>kind of serious because every update will break Horde. Maybe one of the
>>>maintainers can look at those. I'm not sure if D is windows specific.
>>>
>>>And 1 milliion thanks to the Horde devs. I've been using it for years,
>>>on Windows no less, and its always been rock solid. Great software.
>>>
>>>-----------------
>>>Subject: Horde 6 on Windows (XAMPP Apache 2.4 + mod_fcgid, PHP 8.5):
>>>working setup, and the Windows-specific problems I hit
>>>
>>>ENVIRONMENT
>>>
>>>Windows 11, Apache 2.4.54 with mod_fcgid, PHP 8.5.12 (CLI and FastCGI),
>>>MariaDB, Composer 2, Git. I migrated an existing Horde 5 install (PHP 7)
>>>to a fresh Horde 6 deployment, reusing the Horde 5 database. The wiki
>>>lists PHP 8.1/8.2. I used 8.5, and everything below works with the
>>>workarounds listed.
>>>
>>>Installed versions: horde/horde 6.2.1, core 3.3.0, imp 7.2.0, kronolith
>>>5.0.3, turba 5.0.2, nag 5.0.0, mnemo 5.0.0, ingo 4.0.1, content 3.0.0,
>>>routes 3.0.1, horde-installer-plugin 2.7.3, plus gollem 5.0.0beta3,
>>>passwd 6.0.0RC3 and timeobjects 3.0.0beta4.
>>>
>>>Tested and working: web login, IMP mailbox, Kronolith/Nag/task data from
>>>the migrated database, scheduled horde-alarms, CalDAV discovery from eM
>>>Client, ActiveSync from two Android clients (Nine and Samsung Mail). I
>>>have not tested every app.
>>>
>>>INSTALL
>>>git clone https://github.com/maintaina-com/horde-deployment.git horde6
>>>cd horde6
>>>composer install
>>>composer require horde/imp horde/ingo horde/turba horde/kronolith
>>>horde/nag horde/mnemo horde/content horde/timeobjects horde/gollem
>>>horde/passwd
>>>
>>>In php.ini the gettext extension must be enabled (Composer fails without
>>>it). Also enable intl, mbstring, openssl, pdo_mysql, mysqli, curl,
>>>fileinfo, sodium, zip, gd and exif. iconv is built in on the Windows
>>>builds.
>>>
>>>DATABASE (MIGRATING FROM HORDE 5)
>>>Work on a copy. Dump the old database, import it into a new database and
>>>user, and set the sql database name, username and password in
>>>var\config\horde\conf.php. Then run:
>>>
>>>vendor\bin\horde-db-migrate up
>>>
>>>This upgraded my Horde 5 schema without errors (horde 0 to 2, kronolith
>>>23 to 29, turba 11 to 13, nag 14 to 18, token 1 to 2).
>>>
>>>CONFIG
>>>Copy the old generated conf.php (and backends.local.php and similar
>>>files) into var\config<app>. Fix any hard-coded paths (log, cache, temp)
>>>and create those directories. I kept these Horde 5 lines and they work:
>>>
>>>$conf['server']['name'] = $_SERVER['SERVER_NAME'] ?? 'mail.example.com';
>>>$conf['cookie']['domain'] = $_SERVER['SERVER_NAME'] ??
>>>'mail.example.com';
>>>
>>>The configuration lives in var\config. The command "composer
>>>horde-reconfigure" copies it into web<app>\config ("copy" mode). Until
>>>that is run you get "Please create a .../var/config/horde/conf.php file
>>>and then run 'composer horde-reconfigure'", even though the file exists.
>>>
>>>APACHE
>>>DocumentRoot is ...\horde6\web, with AllowOverride All and Require all
>>>granted. The apps are then at /horde/, /imp/, /kronolith/ and so on.
>>>
>>>For DAV and ActiveSync on a separate hostname I aliased rpc.php, one
>>>Alias line per path:
>>>
>>>FcgidPassHeader Authorization
>>>Alias /horde/rpc.php "<horde6>/web/horde/rpc.php"
>>>Alias /rpc.php "<horde6>/web/horde/rpc.php"
>>>Alias /Microsoft-Server-ActiveSync "<horde6>/web/horde/rpc.php"
>>>Alias /autodiscover/autodiscover.xml "<horde6>/web/horde/rpc.php"
>>><Directory "<horde6>/web/horde">
>>>Require all granted
>>></Directory>
>>>
>>>FcgidPassHeader is only allowed at server or vhost level, not inside
>>>Directory. The aliased script must run under the same PHP handler as the
>>>rest of Horde. CalDAV/CardDAV URL: https://host/horde/rpc.php/
>>>
>>>SCHEDULED ALARMS
>>>C:\php85\php.exe <horde6>\vendor\horde\horde\bin\horde-alarms
>>>
>>>Run every 5 minutes from Task Scheduler (it reports exit code 0). The
>>>CLI scripts print "The system cannot find the path specified." a few
>>>times, which is harmless.
>>>
>>>PROBLEMS I HIT (WINDOWS-SPECIFIC OR VERSION MISMATCHES)
>>>
>>>A. The installer writes a PHP syntax error on Windows. The generated
>>>registry.d/-location-.php files contain paths like 'X:...\horde' and the
>>>trailing backslash escapes the closing quote. This breaks every request
>>>and horde-db-migrate. Workaround, to be repeated after every composer
>>>install, update or horde-reconfigure (PowerShell):
>>>
>>>Get-ChildItem <root> -Recurse -File -Filter "0*-location-*.php" |
>>>ForEach-Object {
>>>$t = Get-Content $.FullName -Raw
>>>$n = $t -replace "\';", "/';"
>>>if ($n -ne $t) { Set-Content $.FullName -Value $n -NoNewline }
>>>}
>>>
>>>B. The JavaScript tree is not deployed when Composer runs as a normal
>>>user. web\js was created but stayed empty ("Linking javascript tree"
>>>fails silently, probably because symlinks need privileges). Symptoms:
>>>mail stuck on "loading", and 404s such as /js/horde/sidebar.js. Running
>>>"composer horde-reconfigure" from an Administrator prompt created a
>>>junction for web\js\horde. prototype.js and scriptaculous live in
>>>vendor\horde\core\js, so they also had to be copied into web\js\horde.
>>>The apps' JavaScript had to be copied manually into web\js<app>.
>>>
>>>C. Trean 2.0.2 breaks everything routed through rampage.php. Its
>>>config outes.php calls connect(), which the GroupMapper in horde/routes
>>>3.0.1 rejects ("connect() is not supported by GroupMapper. Use
>>>buildRoute() instead"). The fatal error hits any request that loads all
>>>apps' routes. I removed Trean with "composer remove horde/trean".
>>>
>>>D. DAV fails with "Call to undefined method
>>>Horde\Content\Api::methods()". The Content 3.0.0 Api class implements
>>>only getApiInterfaceList(), but Registry.php in core 3.3.0 (lines 1107,
>>>1193 and 1247) calls $api_ob->methods() on every app's API object, so
>>>rpc.php returns a 500. My workaround was to add this method to
>>>vendor/horde/content/src/Api.php; it is lost whenever Content is
>>>updated:
>>>
>>>public function methods(): array { return []; }
>>>
>>>E. Cosmetic: script URLs for the base app come out as
>>>/js/horde//prototype.js (the registry's jsuri has a trailing slash and
>>>another is appended). It works once the files exist.
>>>
>>>F. Unresolved: warnings 'Undefined array key "horde"' from lines 12 and
>>>14 of each generated 02-location-<app>.php (the horde webroot is not set
>>>yet), logged on rampage.php and rpc.php requests. They look harmless,
>>>but I don't know the cause.
>>>
>>>QUESTIONS FOR THE LIST
>>>
>>>Is there a supported way to deploy the web\js, web	hemes and config
>>>trees on Windows without symlinks or Administrator rights?
>>>Is Trean expected to work with horde/routes 3.0.1, and is Content meant
>>>to provide methods() for the current Registry?
>>>Should the trailing-backslash path problem be fixed in
>>>horde-installer-plugin? (A newer 3.6.0 is available; I have not tried
>>>it.)
>>>--
>>>Horde mailing list
>>>Frequently Asked Questions: http://horde.org/faq/
>>>To unsubscribe, mail: horde-unsubscribe at lists.horde.org
>>>
>>>
>>>
>>>
>>>
>>>
>-- Horde mailing list
>Frequently Asked Questions: http://horde.org/faq/
>To unsubscribe, mail: horde-unsubscribe at lists.horde.org



More information about the horde mailing list