Notes on converting apps from Horde 5 to Horde 6

These are by far not complete. Last updated: 2026-03-04

Conversion Status

Package Strategy Unit Tests PHPStan PHP 8 Comments/Upgrade path
horde/alarm Legacy 9.5 Yes Yes Tests for unnamespaced modernized. Actual PSR-4 upgrade postponed, should use PSR-3 logger and modernized SQL when available
horde/argv Parallel 9.5, 447 tests Yes Yes Modern API complete with contextual option groups. See argv-contextual-option-groups-implementation-complete.md
horde/components Wrapper 9.4, Story tests broken Yes Yes Lots of new features related to git, composer and workflows. Still maintains package.xml and requires it in some places. 219 src/, 5 lib/
horde/horde-installer-plugin Modern 9.5, very limited Yes Yes Handles all the horde setup stuff, symlinks, workaround configs etc. 33 src/, 0 lib/
horde/horde-deployment Modern n/a n/a Yes The base project for a horde installation with default dir tree - Branches reflect bundles
horde/hordectl Modern 9.5 No Yes CLI management tool. 41 src/, 0 lib/
horde/http_server Modern 9.5, only stub of a test framework Yes yes Successor to horde/controller. 13 src/, 0 lib/
horde/http Parallel 9.4 No yes Major BC breaks. Implementation based on PSR-7, PSR-18. 28 src/, 17 lib/
horde/injector Wrapper 9.5 Yes yes Carefully added signatures, limited BC breaks for child injectors. Now PSR-11. 11 src/, 11 lib/
horde/crypt_blowfish Legacy 9.5 No yes works with openssl 3
horde/controller Keep 9.4 No Yes Only added namespaced wrapper code for interop with horde/http_server and PSR-7. 2 src/, 22 lib/
horde/stream_wrapper Parallel 9.4 No yes Class names have Wrapper appended to make sense when USEd. 8 src/, 7 lib/
horde/util Parallel 9.5 No yes Slightly renamed classes and typing upgrades. 9 src/, 7 lib/
horde/text_diff Parallel 9.5 No yes, 8.2beta Renamed classes, typing upgrades. 20 src/, 19 lib/
horde/support Parallel 9.4 No yes Slightly renamed classes and typing upgrades. 10 src/, 15 lib/
horde/compress_fast Parallel 9.4 No yes Straight. 8 src/, 7 lib/
horde/mongo Parallel 9.4 No yes Removed support for the older extension - Still using the compat library. 7 src/, 6 lib/
horde/cli Parallel 9.4 No yes straight. 10 src/, 3 lib/
horde/memcache Parallel 9.4, started minimal test suite No yes straight. 15 src/, 22 lib/
horde/cache Parallel 9.4, started minimal test suite No yes Dropped some dead in-memory caches. 16 src/, 17 lib/
horde/test Parallel 9.4, started minimal test suite No yes straight. 14 src/, 8 lib/
horde/routes Parallel 9.4 No yes straight. 11 src/, 10 lib/
horde/db Parallel 9.4 No yes src/ Still a WIP mess. Dropped support for classic mysql extension. 42 src/, 41 lib/
horde/log Parallel 9.4 No yes Incompatible new design based on PSR-3, See Doc/Dev/HordeLog. 17 src/, 8 lib/
horde/thrift Keep n/a n/a yes Only nominally released as a leaf dependency, may be deprecated
horde/scribe Keep n/a n/a yes Only nominally released as a leaf dependency, may be deprecated
horde/translation Parallel 9.5, covers only lib/ No yes Slightly renamed classes and typing upgrades. 6 src/, 5 lib/
horde/exception Parallel 9.5 No yes Slightly renamed classes and typing upgrades, better support for 3rd argument. 12 src/, 7 lib/
horde/eventdispatcher Modern 9.5, Stub only Yes yes PSR-14 replacement for PubSub?, See Doc/Dev/HordeEventDispatcher. 2 src/, 0 lib/
horde/skeleton Modern 9.5, Stub Only No testing Example app. 11 src/, 0 lib/
horde/share Legacy 9.5, covers only /lib No yes, wip Tests are not really run for the DB specific drivers yet but signatures check out. 0 src/, 44 lib/
horde/kolab_format Legacy 9.5, covers only /lib No yes, wip Little interest beyond making test suites for other libs work. 0 src/, 79 lib/
horde/kolab_storage Legacy 9.5, covers only /lib No yes, wip Little interest beyond making test suites for other libs work. 0 src/, 119 lib/
horde/cli_modular Parallel 9.5, covers only /lib No yes, wip Lib/ needs some minor fixes for PHP 8.1 compat. src/ is a major rewrite to account for modern autoloading, dependency injection, much more typing and lessons learned from cli_modular applications. 8 src/, 6 lib/
horde/form Parallel 9.5 Yes Yes Major modernization with typed code and PSR compliance. 61 src/, 14 lib/
horde/constraint Parallel 9.5 No Yes PSR-4 conversion complete. 14 src/, 11 lib/
horde/secret Modern 9.5 Yes Yes New implementation. 10 src/, 0 lib/
horde/token Modern 9.5 Yes Yes New implementation. 13 src/, 0 lib/
horde/url Parallel 9.5 No Yes PSR-4 conversion. 4 src/, 3 lib/
horde/version Modern 9.5 Yes Yes New semver implementation. 18 src/, 0 lib/
horde/composer Modern 9.5 Yes Yes Composer utilities. 13 src/, 0 lib/
horde/githubapiclient Modern 9.5 Yes Yes GitHub? API v3 client. 68 src/, 0 lib/
horde/hordeymlfile Modern 9.5 Yes Yes .horde.yml parser. 8 src/, 0 lib/

Apps Status

App Strategy PHPUnit Status
horde/base Parallel Yes 4 src/, 44 lib/
horde/imp Parallel Yes 1 src/, 318 lib/ - Major work needed
horde/ingo Legacy Yes 0 src/, 118 lib/
horde/kronolith Parallel Yes 11 src/, 109 lib/
horde/turba Legacy Yes 0 src/, 52 lib/
horde/nag Parallel Yes 1 src/, 46 lib/
horde/mnemo Legacy Yes 0 src/, 26 lib/
horde/ansel Parallel Yes 1 src/, 93 lib/
horde/whups Parallel No 4 src/, 99 lib/
horde/wicked Parallel Yes 13 src/, 27 lib/
horde/passwd Parallel Yes 1 src/, 27 lib/
horde/gollem Parallel No 1 src/, 14 lib/
horde/jonah Parallel Yes 1 src/, 29 lib/
horde/sesha Legacy Yes 0 src/, 27 lib/
horde/trean Parallel No 1 src/, 21 lib/

Library strategies

Parallel

Parallel strategy means double maint. burden but high freedom for due improvements and necessary BC breaks.

Example: horde/test, horde/cache, horde/cli

Current Count: ~40 libraries using Parallel strategy

Wrapper

Wrapper strategy allows both old and new calling code to leverage the same slightly modernized code base. However, BC breaks must be prevented.

Example: horde/components, horde/injector

Current Count: ~3 libraries using Wrapper strategy (components, injector, cli_application)

Modern

Newly developed code should only focus on the composer use case

Example: horde/horde-installer-plugin, horde/http_server, horde/hordectl, horde/skeleton

Current Count: ~15 libraries using Modern strategy (new implementations)

Legacy / Keep

Libraries which are essentially deprecated but kept around for H6, or not yet converted

Example: horde/controller (Keep), horde/alarm (Legacy but functional)

Current Count: ~90 libraries still in Legacy mode (0 src/ files)

General

[Unnamespaced code still needs Horde_Autoloader's slightly different approach than composer's autoloader]

Exceptions to the rule

Mandatory

Optional / Best Practice

Exceptions To The Rule

Namespaces and dir layout

Mandatory

- Horde\$Name\$Name
- Horde\$Name\$NameInterface?
- Horde\$Name\Base
- Horde\$Name\Constants
- In case of base classes, re-think if we are not better off with an interface and some trait

Optional

Exceptions to the rule

PHPDoc / Type Hints / Type Declarations

Remember Liskov:

Mandatory

Optional

Exceptions to the rule

GLOBALS usage

Whitelist

*

Mandatory

Optional

Exceptions to the rule

DI / Injector and Constructors

As Horde has evolved over the years, we have different types of classes, sometimes even mixed.

Mandatory

<?php

       // Use a factory to get an implementation
       // In case the factory cannot be autowired itself, you need to register how to get it first.
       $injector->bindFactory(Horde\Kronolith\Calendar\Resource::class, Horde\Kronolith\Calendar\Factory::class, 'create')
       // In case you want a specific implementation and it can be autowired, just bind it.
       $injector->bindImplementation(Horde\Kronolith\Renderer::class, Horde\Kronolith\Renderer\Default::class);
?>
<?php

       use Horde\Kronolith\Calendar\Resource;
       use Horde\Kronolith\Calendar\Factory as CalendarFactory;
       use Horde\Kronolith\Renderer;
       use Horde\Kronolith\Renderer\Default as RendererDefault;
       // Use a factory to get an implementation
       // In case the factory cannot be autowired itself, you need to register how to get it first.
       $injector->bindFactory(Resource::class, CalendarFactory::class, 'create')
       // In case you want a specific implementation and it can be autowired, just bind it.
       $injector->bindImplementation(Renderer::class, RendererDefault::class);
?>
<?php

       $injector->bindImplementation('Forms', '\Horde_Forms_Base');
?>

Optional

Exceptions to the rule

reqire/require_once, Horde\Autoloader and Composer Autoloader

Required

Optional

UNCLEAR

package specific notes

horde\imp

Horde\Injector

Optional

Horde\Date

Optional

* Horde\Date use cases should generally be checked for timezone mismatches e.g. when converting UTC strings from database
* There is some headache potential with Horde\Db implicitly using Horde\Date without timezone information when SELECTing datetime values.
* This is especially annoying with Horde\Rdo
* Horde\Date constructor should always require an explicit timezone and current time
* Provide convenience static methods for "fromThisFormat()", "fromThatFormat()" to keep that complexity out of the value object

Horde\Core

Mandatory:

Optional:

Horde\Rpc

Mandatory:

Optional:
* Default to JsonRpc? rather than XmlRpc?
* Refactor to controller framework

Library Upgrade strategy (pre release)

Apart from mandatory changes, we should not currently port all horde to the new standard quickly.

Mandatory

Optional

Exception to the rule

App Upgrade Strategy (pre release)

Required

Optional

Developer's wishlist