\documentclass{article}
\usepackage{ulem}
\usepackage{graphicx}
\usepackage{hyperref}
\pagestyle{headings}
\begin{document}
Notes on converting apps from Horde 5 to Horde 6

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

\part{Conversion Status}
<table class="horde-table">Package & Strategy & Unit Tests & PHPStan & PHP 8 & Comments/Upgrade path \\
\hline
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 \\
\hline
horde/argv & Parallel & 9.5, 447 tests & Yes & Yes & Modern API complete with contextual option groups. See argv-contextual-option-groups-implementation-complete.md \\
\hline
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/ \\
\hline
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/ \\
\hline
horde/horde-deployment & Modern & n/a & n/a & Yes & The base project for a horde installation with default dir tree - Branches reflect bundles \\
\hline
horde/hordectl & Modern & 9.5 & No & Yes & CLI management tool. 41 src/, 0 lib/ \\
\hline
horde/http\_server & Modern & 9.5, only stub of a test framework & Yes & yes & Successor to horde/controller. 13 src/, 0 lib/ \\
\hline
horde/http & Parallel & 9.4 & No & yes & Major BC breaks. Implementation based on PSR-7, PSR-18. 28 src/, 17 lib/ \\
\hline
horde/injector & Wrapper & 9.5 & Yes & yes & Carefully added signatures, limited BC breaks for child injectors. Now PSR-11. 11 src/, 11 lib/ \\
\hline
horde/crypt\_blowfish & Legacy & 9.5 & No & yes & works with openssl 3 \\
\hline
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/ \\
\hline
horde/stream\_wrapper & Parallel & 9.4 & No & yes & Class names have Wrapper appended to make sense when USEd. 8 src/, 7 lib/ \\
\hline
horde/util & Parallel & 9.5 & No & yes & Slightly renamed classes and typing upgrades. 9 src/, 7 lib/ \\
\hline
horde/text\_diff & Parallel & 9.5 & No & yes, 8.2beta & Renamed classes, typing upgrades. 20 src/, 19 lib/ \\
\hline
horde/support & Parallel & 9.4 & No & yes & Slightly renamed classes and typing upgrades. 10 src/, 15 lib/ \\
\hline
horde/compress\_fast & Parallel & 9.4 & No & yes & Straight. 8 src/, 7 lib/ \\
\hline
horde/mongo & Parallel & 9.4 & No & yes & Removed support for the older extension - Still using the compat library. 7 src/, 6 lib/ \\
\hline
horde/cli & Parallel & 9.4 & No & yes & straight. 10 src/, 3 lib/ \\
\hline
horde/memcache & Parallel & 9.4, started minimal test suite & No & yes & straight. 15 src/, 22 lib/ \\
\hline
horde/cache & Parallel & 9.4, started minimal test suite & No & yes & Dropped some dead in-memory caches. 16 src/, 17 lib/ \\
\hline
horde/test & Parallel & 9.4, started minimal test suite & No & yes & straight. 14 src/, 8 lib/ \\
\hline
horde/routes & Parallel & 9.4 & No & yes & straight. 11 src/, 10 lib/ \\
\hline
horde/db & Parallel & 9.4 & No & yes & src/ Still a WIP mess. Dropped support for classic mysql extension. 42 src/, 41 lib/ \\
\hline
horde/log & Parallel & 9.4 & No & yes & Incompatible new design based on PSR-3, See <a href="https://wiki.horde.org/Doc/Dev/HordeLog">Doc/Dev/HordeLog</a>. 17 src/, 8 lib/ \\
\hline
horde/thrift & Keep & n/a & n/a & yes & Only nominally released as a leaf dependency, may be deprecated \\
\hline
horde/scribe & Keep & n/a & n/a & yes & Only nominally released as a leaf dependency, may be deprecated \\
\hline
horde/translation & Parallel & 9.5, covers only lib/ & No & yes & Slightly renamed classes and typing upgrades. 6 src/, 5 lib/ \\
\hline
horde/exception & Parallel & 9.5 & No & yes & Slightly renamed classes and typing upgrades, better support for 3rd argument. 12 src/, 7 lib/ \\
\hline
horde/eventdispatcher & Modern & 9.5, Stub only & Yes & yes & PSR-14 replacement for <a href="https://wiki.horde.org/PubSub">PubSub</a>, See <a href="https://wiki.horde.org/Doc/Dev/HordeEventDispatcher">Doc/Dev/HordeEventDispatcher</a>. 2 src/, 0 lib/ \\
\hline
horde/skeleton & Modern & 9.5, Stub Only & No & testing & Example app. 11 src/, 0 lib/ \\
\hline
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/ \\
\hline
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/ \\
\hline
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/ \\
\hline
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/ \\
\hline
horde/form & Parallel & 9.5 & Yes & Yes & Major modernization with typed code and PSR compliance. 61 src/, 14 lib/ \\
\hline
horde/constraint & Parallel & 9.5 & No & Yes & PSR-4 conversion complete. 14 src/, 11 lib/ \\
\hline
horde/secret & Modern & 9.5 & Yes & Yes & New implementation. 10 src/, 0 lib/ \\
\hline
horde/token & Modern & 9.5 & Yes & Yes & New implementation. 13 src/, 0 lib/ \\
\hline
horde/url & Parallel & 9.5 & No & Yes & PSR-4 conversion. 4 src/, 3 lib/ \\
\hline
horde/version & Modern & 9.5 & Yes & Yes & New semver implementation. 18 src/, 0 lib/ \\
\hline
horde/composer & Modern & 9.5 & Yes & Yes & Composer utilities. 13 src/, 0 lib/ \\
\hline
horde/githubapiclient & Modern & 9.5 & Yes & Yes & <a href="https://wiki.horde.org/GitHub">GitHub</a> API v3 client. 68 src/, 0 lib/ \\
\hline
horde/hordeymlfile & Modern & 9.5 & Yes & Yes & .horde.yml parser. 8 src/, 0 lib/ \\
\hline
</table>
\part{Apps Status}
<table class="horde-table">App & Strategy & PHPUnit & Status \\
\hline
horde/base & Parallel & Yes & 4 src/, 44 lib/ \\
\hline
horde/imp & Parallel & Yes & 1 src/, 318 lib/ - Major work needed \\
\hline
horde/ingo & Legacy & Yes & 0 src/, 118 lib/ \\
\hline
horde/kronolith & Parallel & Yes & 11 src/, 109 lib/ \\
\hline
horde/turba & Legacy & Yes & 0 src/, 52 lib/ \\
\hline
horde/nag & Parallel & Yes & 1 src/, 46 lib/ \\
\hline
horde/mnemo & Legacy & Yes & 0 src/, 26 lib/ \\
\hline
horde/ansel & Parallel & Yes & 1 src/, 93 lib/ \\
\hline
horde/whups & Parallel & No & 4 src/, 99 lib/ \\
\hline
horde/wicked & Parallel & Yes & 13 src/, 27 lib/ \\
\hline
horde/passwd & Parallel & Yes & 1 src/, 27 lib/ \\
\hline
horde/gollem & Parallel & No & 1 src/, 14 lib/ \\
\hline
horde/jonah & Parallel & Yes & 1 src/, 29 lib/ \\
\hline
horde/sesha & Legacy & Yes & 0 src/, 27 lib/ \\
\hline
horde/trean & Parallel & No & 1 src/, 21 lib/ \\
\hline
</table>
\part{Library strategies}
\section{Parallel}
Parallel strategy means double maint. burden but high freedom for due improvements and necessary BC breaks.

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

\begin{itemize}
\item Keep unnamespaced PSR-0 code as-is or only make changes required by composer.


\item Add PSR-4 PHP 7.4+ code in src/ - it may contain BC breaks and structural changes.


\item develop new code quality measures only against the src/ version (phpstan, member/parameter/return type hinting, strict types)


\item Convert unit tests for phpunit 9.x+, use PSR-4 for unit tests, test against the namespaced version


\item src/ Code must be php 7.4 compatible and php 8 compatible.


\end{itemize}
Current Count: \textasciitilde{}40 libraries using Parallel strategy

\section{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

\begin{itemize}
\item Move code to src/ and namespace it


\item Add wrappers or child classes to lib so consuming code still works


\item Be conservative about return type hinting, parameter type hinting and other potentially BC breaking measures


\item Convert unit tests for phpunit 9.x+, use PSR-4 for unit tests, test against the namespaced version - maybe keep some duplicate tests against the wrapper code to prove correctness.


\item All Code must be php 7.4 compatible and php 8 compatible.


\end{itemize}
Current Count: \textasciitilde{}3 libraries using Wrapper strategy (components, injector, cli\_application)

\section{Modern}
Newly developed code should only focus on the composer use case

Example: horde/horde-installer-plugin, horde/http\_server, horde/hordectl, horde/skeleton

\begin{itemize}
\item Follow PSR-4, PSR-12, PHP 7.4+, ignore PEARisms unless they belong to the problem domain.


\item PHPStan level 4 and higher.


\item member/parameter/return type hinting, strict types


\item Avoid mixed parameter and return type designs.


\item Avoid array constructors if it makes sense. (When switching to PHP 8, we will get named arguments)


\item src/ Code must be php 7.4 compatible and php 8 compatible.


\end{itemize}
Current Count: \textasciitilde{}15 libraries using Modern strategy (new implementations)

\section{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)

\begin{itemize}
\item Only necessary changes to avoid breaking in modern PHP


\item unit tests should be PHPUnit 9+ ready


\item May eventually be converted or deprecated


\end{itemize}
Current Count: \textasciitilde{}90 libraries still in Legacy mode (0 src/ files)

\part{General}
\begin{itemize}
\item Unnamespaced code mostly follows Horde 5 Coding standards and very little conversion requirements


\item With some necessary exceptions, Horde 6 should be able to cooperate with Horde 5-ish apps and libraries with very little modification for composer compat


\item Unconditional require/require\_once/include to paths outside the library's own lib or src dir need to check for the require'd class first (likely breaks in H6 via composer).<br />
<a href="https://wiki.horde.org/Unnamespaced">code still needs Horde\_Autoloader's slightly different approach than composer's autoloader</a>


\item Consider: Horde 5 Framework lived out 2012-2021, Horde 6 to be intentionally shortlived, deprecating more stuff over time.


\item Allow a very smooth transition path, avoid big bang changes. <a href="https://wiki.horde.org/STILL">TRUE</a>


\end{itemize}
\section{Exceptions to the rule}
\begin{itemize}
\item Most of the upgrade requirements are only targeted at namespaced code


\end{itemize}
\section{Mandatory}
\begin{itemize}
\item Horde:: is deprecated <a href="https://wiki.horde.org/NO">REAL REPLACEMENT YET - Still in planning</a>


\item <a href="https://wiki.horde.org/rla">thinks</a> we should adopt PSR-2, PSR-12 wholesale with an optional opt-out for protected/private underscoring <a href="https://wiki.horde.org/IMPLEMENTED">in Modern libraries</a>


\item Composer based setup must work with all libraries we intend to keep <a href="https://wiki.horde.org/SOLVED">- All H6 libs have composer.json</a>


\item <a href="https://wiki.horde.org/rla">thinks</a> Deprecate Horde\_Forms usage. Keep it where it is until we can refactor, but make it clear this is a legacy concept
\begin{itemize}
\item Form library modernized with src/ implementation - see horde/form


\end{itemize}

\item Update Horde\_Core to support both namespaced apps non-namespaced apps and mixed. <a href="https://wiki.horde.org/ONGOING">- Core has 44 src/, 280 lib/</a>


\item Update Horde\_Test to support namespaced unit tests (PHPUnit 9 spews warnings for unit test classnames different than file name, so there is little use in BC here) <a href="https://wiki.horde.org/DONE">DONE</a>


\item Unit Tests must support the current stable phpunit <a href="https://wiki.horde.org/DONE">- Most libs using PHPUnit 9.x+</a>


\item Check all pear package dependencies if they are also available via packagist or a proper composer channel rather than pear <a href="https://wiki.horde.org/MOSTLY">DONE</a>


\item Update skeleton to use
\begin{itemize}
\item horde/http\_server, <a href="https://wiki.horde.org/DONE">- skeleton is Modern</a>


\item Namespacing, <a href="https://wiki.horde.org/DONE">DONE</a>


\item Type Hints where appropriate <a href="https://wiki.horde.org/DONE">DONE</a>


\item Model Interface and Rdo implementation rather than driver architecture <a href="https://wiki.horde.org/NOT">YET DONE</a>


\end{itemize}

\end{itemize}
\section{Optional / Best Practice}
\begin{itemize}
\item Try to drop usage of pear libraries if we only use little portions of their api
\begin{itemize}
\item Consider if there is a more modern alternative available on packagist


\end{itemize}

\item Unbundle bundled code if you can, use composer dependencies <a href="https://wiki.horde.org/UNBUNDLED">phpunit, sabredav</a>


\item Maintain a branch or fork of Skeleton to showcase Horde Ajax Framework and an SPA frontend


\item All URL generation should be moved to Horde\_Routes\_UrlWriter driven by config/routes.php <a href="https://wiki.horde.org/NOT">DONE</a>


\item A more copy/paste ready boilerplate for <a href="https://wiki.horde.org/ClassLevelDocBlock">ClassLevelDocBlock</a>, <a href="https://wiki.horde.org/FileLevelDocBlock">FileLevelDocBlock</a>, <a href="https://wiki.horde.org/MethodLevelDocBlock">MethodLevelDocBlock</a>
\begin{itemize}
\item Consider: Maybe some custom rules for php-cs-fixer


\end{itemize}

\end{itemize}
\section{Exceptions To The Rule}
\begin{itemize}
\item Empty/deprecated apps (bundle, dashboard, theme-material, etc) - No conversion needed


\end{itemize}
\part{Namespaces and dir layout}
\section{Mandatory}
\begin{itemize}
\item The home namespace for a library is \$Vendor\textbackslash\{\}\$Name\textbackslash\{\}, e.g. Horde\textbackslash\{\}View


\item The home namespace for a subtype library is \$Vendor\textbackslash\{\}\$Parent\textbackslash\{\}\$Name e.g. Horde\textbackslash\{\}Xml\textbackslash\{\}Element rather than Horde\textbackslash\{\}Xml\_Element


\item The Home Namespace for an app in \$Horde\textbackslash\{\}\$Name, e.g. Horde\textbackslash\{\}Turba
\begin{itemize}
\item TODO: Should we allow third party apps to use their proper vendor if the composer package is type horde-app? We could have an optional registry key (B1 clause)


\end{itemize}

\item The Horde Base app is Horde\textbackslash\{\}Base
\begin{itemize}
\item DISCUSS: Any arguments for calling it Horde\textbackslash\{\}Horde? Should we rename/alias the base app horde/base altogether?
\begin{itemize}
\item Base is an even worse name than "horde". Between Base and Core, things are often mixed or simply on the wrong side.


\end{itemize}

\end{itemize}

\item If a library has an interface or base class Horde\_\$Name, promote it to either:
\begin{itemize}
\item Horde\textbackslash\{\}\$Name\textbackslash\{\}\$Name


\item Horde\textbackslash\{\}\$Name\textbackslash\{\}\$<a href="https://wiki.horde.org/NameInterface">NameInterface</a>


\item Horde\textbackslash\{\}\$Name\textbackslash\{\}Base


\item Horde\textbackslash\{\}\$Name\textbackslash\{\}Constants


\item In case of base classes, re-think if we are not better off with an interface and some trait


\end{itemize}

\item Horde:: is Horde\textbackslash\{\}Core\textbackslash\{\}Horde:: though I think we should re-think using it at all


\item Un-namespaced controllers go to app\textbackslash\{\}controllers\textbackslash\{\} dir, namespaced controllers just go anywhere under src/, i.e. src/Middleware, src/Handler, src/Controller with no magic attached.


\item Un-namespaced library code goes to lib/


\item New or converted namespaced library code goes to src/.


\end{itemize}
\section{Optional}
\begin{itemize}
\item Prefer Use statements over prepending unnamespaced code with a backslash \textbackslash\{\} unless it is single-use and would require "use as" to avoid clashes.


\end{itemize}
\section{Exceptions to the rule}
\begin{itemize}
\item Code which was already namespaced before Horde 6 may be left in lib/ if other unnamespaced code depends on it.
\begin{itemize}
\item In this case, don't forget to tweak autoloading rules in .horde.yml and adjust any github actions workflows


\end{itemize}

\end{itemize}
\part{PHPDoc / Type Hints / Type Declarations}
Remember Liskov:

\begin{itemize}
\item Interface/Base class parameters should be as specific as possible. Derived/Implementing classes can only accept the same or less specific definitions


\item Interface/Base class return type parameters should be as unspecific as makes sense. Derived/Implementing classes can announce to return the same or more specific definitions.


\end{itemize}
\section{Mandatory}
\begin{itemize}
\item PHPDoc all parameters and return values, regardless if you have typehinted them.


\item Prefer A|B|null over "mixed"


\end{itemize}
\section{Optional}
\begin{itemize}
\item Parameter Type hints for string, int, boolean SHOULD be added to the namespaced interfaces where possible


\item Parameter Type hints for classes SHOULD be added to be added to the namespaced interfaces where possible.


\item Use Nullable (?) for optional parameters


\item Prefer iterable over array if you can to allow later upgrades from arrays to container objects, generators, iterators etc


\item Where Type Hints cannot express exactly what a parameter accepts, typehint for "object" or leave typehint altogether. In any case, make the PHPDoc more specific and wordy


\end{itemize}
\section{Exceptions to the rule}
\begin{itemize}
\item Wrapper strategy libraries may need to be conservative with type hints to maintain BC


\end{itemize}
\part{GLOBALS usage}
\section{Whitelist}
\begin{itemize}
\item For \$injector:
\begin{itemize}
\item Horde\textbackslash\{\}Core\textbackslash\{\}Registry<br />
*


\end{itemize}

\item For \$\_GET, \$\_POST, \$\_REQUEST
\begin{itemize}
\item Horde\textbackslash\{\}Controller\textbackslash\{\}


\item Horde\textbackslash\{\}Routes\textbackslash\{\}


\item Horde\textbackslash\{\}Core\textbackslash\{\}


\item Horde\textbackslash\{\}Rpc\textbackslash\{\}


\item Horde\textbackslash\{\}Base\textbackslash\{\}


\item Horde\textbackslash\{\}Cli\textbackslash\{\}


\end{itemize}

\item for \$config:
\begin{itemize}
\item Horde\textbackslash\{\}Base\textbackslash\{\}


\item Horde\textbackslash\{\}Core\textbackslash\{\}Registry\textbackslash\{\}


\item Horde\textbackslash\{\}Core\textbackslash\{\}Config\textbackslash\{\}


\end{itemize}

\item for \$page\_output:
\begin{itemize}
\item ?


\end{itemize}

\item for \$\_\_autoload


\end{itemize}
\section{Mandatory}
\begin{itemize}
\item Namespaced Classes which are not in the whitelist must get the listed globals from constructor or method parameter


\end{itemize}
\section{Optional}
\begin{itemize}
\item Factories SHOULD use constructor/setter parameters rather than globals if possible.


\end{itemize}
\section{Exceptions to the rule}
\begin{itemize}
\item Legacy libraries may continue using globals as needed


\end{itemize}
\part{DI / Injector and Constructors}
As Horde has evolved over the years, we have different types of classes, sometimes even mixed.

\begin{itemize}
\item Classes which implement create-on-the-fly objects with no/few dependencies or are mostly static, e.g. Horde\_Url, Horde\_Date, Horde\_String


\item Classes which have one or few instances to cover most or all use cases, e.g. the DB Driver, the registry. They will typically be provided by the injector directly or via a factory without explicit parameters


\item Messy stuff which cannot decide if it is a factory or a base class or wants composition, e.g. Horde\_Form, Horde\_Rpc


\item Classes which are intended as Per-Entity objects


\end{itemize}
\section{Mandatory}
\begin{itemize}
\item Constructors SHOULD depend on interfaces or base classes, not on the (single) implementation.


\item <a href="https://wiki.horde.org/HordeBase">HordeBase</a> or App configuration SHOULD be depended on as *TODO* object, not as array and explicitly not via global state


\item Apps must not care for configuration of other apps, only theirs or <a href="https://wiki.horde.org/HordeBase">HordeBase</a>


\item Namespaced app-internal objects which implement an interface should be registered with the injector using the class combined with ::class, e.g.


\end{itemize}
<pre><code class="language-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\textbackslash\{\}Kronolith\textbackslash\{\}Calendar\textbackslash\{\}Resource::class, Horde\textbackslash\{\}Kronolith\textbackslash\{\}Calendar\textbackslash\{\}Factory::class, 'create')
       // In case you want a specific implementation and it can be autowired, just bind it.
       \$injector->bindImplementation(Horde\textbackslash\{\}Kronolith\textbackslash\{\}Renderer::class, Horde\textbackslash\{\}Kronolith\textbackslash\{\}Renderer\textbackslash\{\}Default::class);
</code></pre>
\begin{itemize}
\item Note there are no strings, this is the class itself - ::class returns the fully qualified strings


\item If you have imported the class with use, you can just use the imported name:


\end{itemize}
<pre><code class="language-php">
       use Horde\textbackslash\{\}Kronolith\textbackslash\{\}Calendar\textbackslash\{\}Resource;
       use Horde\textbackslash\{\}Kronolith\textbackslash\{\}Calendar\textbackslash\{\}Factory as CalendarFactory;
       use Horde\textbackslash\{\}Kronolith\textbackslash\{\}Renderer;
       use Horde\textbackslash\{\}Kronolith\textbackslash\{\}Renderer\textbackslash\{\}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);
</code></pre>
\begin{itemize}
\item Registering an implementation by an arbitrary string is still legal, we even might need it for bc compat with some designs.


\end{itemize}
<pre><code class="language-php">
       \$injector->bindImplementation('Forms', '\textbackslash\{\}Horde\_Forms\_Base');
</code></pre>
\section{Optional}
\begin{itemize}
\item Constructors SHOULD better depend on interfaces rather than base classes but SHOULD NOT depend on the (single) implementation.


\item Try to refactor constructors to only require interfaces which can be provided by the injector (directly or via a factory)


\item If a class used to have a very flexible constructor allowing multiple calling convention, try to distill one calling convention and create either static creator methods or an external factory/builder class


\item Internal creation of objects from other packages should be left to trivial cases (e.g. Horde\_Date). Otherwise it should happen by injecting some instance provider.


\item Use sub-injectors to ensure we do not spill application specific bindings into other apps.


\end{itemize}
\section{Exceptions to the rule}
\begin{itemize}
\item Dependencies may be created internally with some hardcoded setup in case of convenience/fallback scenarios. We should not overuse this as it encourages relying on it.


\end{itemize}
\part{reqire/require\_once, Horde\textbackslash\{\}Autoloader and Composer Autoloader}
\section{Required}
\begin{itemize}
\item include, require and require\_once should only ever happen to setup autoloading or as part of the autoloader or related to non-php code (templates, data)


\item make all explicit require/require\_once check if the required class is already available for loading.


\item At least for now, we should not drop Horde\textbackslash\{\}Autoloader


\item Horde\textbackslash\{\}Autoloader must always act AFTER the composer autoloader, not first


\end{itemize}
\section{Optional}
\begin{itemize}
\item Detect composer autoloader and provide a backend which translates Horde\textbackslash\{\}Autoloader runtime API to composer API


\end{itemize}
\section{UNCLEAR}
\begin{itemize}
\item Do we still want to support git-tools setups?
\begin{itemize}
\item I have implemented some basic git handling in components now.


\item git-tools package exists but has 0 src/, 27 lib/ and no PHPUnit tests


\end{itemize}

\end{itemize}
\part{package specific notes}
\section{horde\textbackslash\{\}imp}
\begin{itemize}
\item Find replacement for optional dependency File\_ASN1 from phpseclib


\item Major app - needs significant conversion work (1 src/, 318 lib/)


\end{itemize}
\section{Horde\textbackslash\{\}Injector}
\section{Optional}
\begin{itemize}
\item Implement PSR-11 but do not deprecate getInstance(), setInstance() <a href="https://wiki.horde.org/DONE">- PSR-11 implemented</a>


\end{itemize}
\section{Horde\textbackslash\{\}Date}
\section{Optional}
\begin{itemize}
\item Horde\textbackslash\{\}Date use cases should generally be checked for timezone mismatches e.g. when converting UTC strings from database
\begin{itemize}
\item There is some headache potential with Horde\textbackslash\{\}Db implicitly using Horde\textbackslash\{\}Date without timezone information when SELECTing datetime values.


\item This is especially annoying with Horde\textbackslash\{\}Rdo


\end{itemize}

\item Horde\textbackslash\{\}Date constructor should always require an explicit timezone and current time


\item Provide convenience static methods for "fromThisFormat()", "fromThatFormat()" to keep that complexity out of the value object


\end{itemize}
\section{Horde\textbackslash\{\}Core}
Mandatory:

\begin{itemize}
\item Provide an alternative for Horde\_PageOutput which only returns strings rather than doing output (needed, otherwise controllers are littered with ob\_start())


\item Provide a type to wrap horde config array for DI <a href="https://wiki.horde.org/DONE">DONE</a>


\item A lot of class names must be fixed for namespacing <a href="https://wiki.horde.org/IN">PROGRESS - 44 src/, 280 lib/</a>


\end{itemize}
Optional:

\begin{itemize}
\item Registry (probably rather 6.1) Provide a more robust inter-app API but don't break the current inter-app API for now
\begin{itemize}
\item Allow passing objects as long as they implement sleep/wakeup so RPC usecases don't break


\item Allow implementing specific APIs and methods in Horde\textbackslash\{\}\$App\textbackslash\{\}Api\textbackslash\{\}\$Api but still support \$App\_Api class for non-namespaced


\item Move vfs/webdav implementations to Horde\textbackslash\{\}\$App\textbackslash\{\}Api\textbackslash\{\}Vfs


\end{itemize}

\end{itemize}
\section{Horde\textbackslash\{\}Rpc}
Mandatory:

\begin{itemize}
\item Fix the signature missmatch errors <a href="https://wiki.horde.org/NOT">DONE</a><br />
Optional:


\item Default to <a href="https://wiki.horde.org/JsonRpc">JsonRpc</a> rather than <a href="https://wiki.horde.org/XmlRpc">XmlRpc</a>


\item Refactor to controller framework


\end{itemize}
\part{Library Upgrade strategy (pre release)}
Apart from mandatory changes, we should not currently port all horde to the new standard quickly.

\section{Mandatory}
\begin{itemize}
\item Existing close-to-core libraries should provide some backward compat either by keeping the code in lib/ mostly unchanged or by having lib/ be some wrapper for src/


\item Once H6 has been released, H6.x libraries need to keep whatever legacy support they had until H7


\end{itemize}
\section{Optional}
\begin{itemize}
\item New libraries should only be implemented according to current best practices


\item Existing fringe libraries may be completely converted to namespaces, dropping unnamespaced versions altogether (pre H6 release)


\end{itemize}
\section{Exception to the rule}
\begin{itemize}
\item Breaking apps which have not officially been released as Horde 5 is OK, we may fix them later. Still, it's nice to be nice if you can.


\end{itemize}
\part{App Upgrade Strategy (pre release)}
\section{Required}
\begin{itemize}
\item Apps may change their internal composition in minor releases (middle digit)


\item Apps may mix and match src/ and lib/ but may only ever have ONE implementation of a class either src/ or lib/. (internal consistency)


\end{itemize}
\section{Optional}
\begin{itemize}
\item Apps should move from unnamespaced library usage to namespaced library usage whenever feasible even if there is a compat layer.


\end{itemize}
\part{Developer's wishlist}
\begin{itemize}
\item JSON version of the topbar


\item Have more control over the prefs menu (passwd app related prefs should merge with global/horde prefs related to passwords etc)


\item Have a version of <a href="https://wiki.horde.org/PageOutput">PageOutput</a> that returns a string or a stream


\item Make the Themes \& JS output useful for custom view types without default prototype/jquery stuff (React UI or similar use cases)


\item Assist with user-customized translations


\item Default way to expose translations to js world


\end{itemize}
\end{document}
