Notes on converting apps from Horde 5 to Horde 6

These are by far not complete.

Conversion Status

Package Strategy Unit Tests PHPStan PHP 8 Comments/Upgrade path
horde/alarm NONE 9.5 n/a Yes Tests for unnamespaced modernized. Actual PSR-4 upgrade postponed, should use PSR-3 logger and modernized SQL when available
horde/components Wrapper 9.4, Story tests broken ? ? Lots of new features related to git, composer and workflows. Still maintains package.xml and requires it in some places
horde/horde-installer-plugin Modern 9.5, very limited Level 9 Yes Handles all the horde setup stuff, symlinks, workaround configs etc
horde/horde-deployment Modern n/a n/a Yes The base project for a horde installation with default dir tree - Branches reflect bundles
horde/http_server Modern 9.5, only stub of a test framework Level 8 yes Successor to horde/controller
horde/http Parallel 9.4 Level 2 yes Major BC breaks. Implementation based on PSR-7, PSR-18
horde/injector Wrapper 9.5 Level 6 yes Carefully added signatures, limited BC breaks for child injectors. Now PSR-11
horde/crypt_blowfish Not Yet 9.5 - yes works with openssl 3
horde/controller Keep 9.4 ? ? Only added namespaced wrapper code for interop with horde/http_server and PSR-7
horde/stream_wrapper Parallel 9.4 Level 8 yes Class names have Wrapper appended to make sense when USEd
horde/util Parallel 9.5 Level 2 yes Slightly renamed classes and typing upgrades
horde/text_diff Parallel 9.5 Level 2 yes, 8.2beta Renamed classes, typing upgrades
horde/support Parallel 9.4 Level 1 yes Slightly renamed classes and typing upgrades
horde/compress_fast Parallel 9.4 Level 1 fails due to reliance on horde-specific extension yes Straight
horde/mongo Parallel 9.4 Level 1 yes Removed support for the older extension - Still using the compat library even though it makes little sense by now
horde/cli Parallel 9.4 Level 1 fails yes straight
horde/memcache Parallel 9.4, started minimal test suite Level 4 yes straight
horde/cache Parallel 9.4, started minimal test suite Level 1 yes Dropped some dead in-memory caches
horde/test Parallel 9.4, started minimal test suite Level 1 yes straight
horde/routes Parallel 9.4 Level 3 yes straight
horde/db Parallel 9.4 Level 0 in progress yes src/ Still a WIP mess. Dropped support for classic mysql extension
horde/log Parallel 9.4 Level 8 yes Incompatible new design based on PSR-3, See Doc/Dev/HordeLog
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/ Level 8 yes Slightly renamed classes and typing upgrades
horde/exception Parallel 9.5 Level 8 yes Slightly renamed classes and typing upgrades, better support for 3rd argument
horde/eventdispatcher Modern 9.5, Stub only Level 8 yes PSR-14 replacement for PubSub?, See Doc/Dev/HordeEventDispatcher
horde/skeleton Wrapper 9.5, Stub Only Level 1 passes, Level 5 for all but View and sidebar testing Example app, see Doc/Dev/Skeleton
horde/share - 9.5, covers only /lib - yes, wip Tests are not really run for the DB specific drivers yet but signatures check out
horde/kolab_format - 9.5, covers only /lib - yes, wip Little interest beyond making test suites for other libs work
horde/kolab_storage - 9.5, covers only /lib - yes, wip Little interest beyond making test suites for other libs work
horde/cli_modular complete redesign 9.5, covers only /lib - 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

Library strategies

Parallel

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

Example: horde/test

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

Modern

Newly developed code should only focus on the composer use case

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

Keep

Libraries which are essentially deprecated but kept around for H6

Example: horde/controller

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