bookmark_borderHorde’s HTTP component goes PSR

This weekend, I gave the horde/http component a some major redesign. See how things escalated. Oh my.
My minimum goals were namespacing, PSR-4 (Revised Autoloading Standard) and some minor, schematic adjustments. The final result is quite different. I ended up implementing PSR-7 (HTTP Message Interface), PSR-17 (HTTP Factories) and PSR-18 (HTTP Client). The code largely complies with PSR-12 (Extended Coding Style Guide) and thus, implicitly, PSR-1 (Basic Coding Standard). I am sure you will find some deviations and issues, so I welcome any Pull Requests against my repo. You will find the new code in /src/. The original, incompatible implementation is untouched and resides in /lib/. They can coexist as they are so different (namespaced vs unnamespaced, among others).

This is not a total rewrite. I could leverage most of the existing code base with some tweaks. This work would not exist without the foundation by Chuck Hagenbuch and all the contributions from the different Horde maintainers over the years. You will also notice similarities to other php PSR-7/18 implementations out there. I checked out Guzzle, httplug/php-http and some others. It was a great learning experience and I will not pretend I am not influenced by it.

As with all my modernisation activities, I made use of features allowed by PHP 7.4. This excludes Constructor Property Promotion and, sadly, Union Types as both are PHP 8. Union Types have been relegated to phpdoc annotations or check methods. Please mind most of the PSR’s target compatibility with PHP releases older than PHP 7.4 and thus do not sport return types or scalar type hints. I followed these signatures where applicable.

One major change between the old codebase and the new one is clients and Request/Response classes.
In the old implementation, there would be one client but different Request/Response implementations using different backing technologies like pecl/http, fopen or curl. The new implementation moves transport code to clients implementing PSR-18. Optionally, they can be wrapped by a Horde\Http\HordeClientWrapper which exposes the PSR-18 itself, but otherwise mimics the old Horde_Http_Client class.

Horde/http is used by very different parts of Horde, including the horde/dav adapter to SabreDAV, various service integrations (Gravatar, Twitter, …), the horde/feed library and application code all over the place. I intend to upgrade those use cases to the new implementation. I am looking forward to criticism or acceptance of that approach.

The goal of this project is more far-reaching. While Horde 4 and Horde 5 already had horde/controller, they made very limited use of it. In my non-public projects, I relied heavily on controllers and I made several attempts at improving the way controllers are set up in horde/core. However, I always felt the results were clunky and not really what I wished to achieve. While horde/controller knows prefilters and postfilters, these are not easy to use and there are few examples. While doing research, I made up my mind. I want to replace Controller/Prefilter/Postfilter with their PSR-15 (HTTP Handlers and Middleware) equivalents. Controllers will be Handlers, Pre/Postfilters will be Middlewares. Together they will be stacks. Authentication, Authorization, Logging etc will be relegated to Middlewares. There will be a default stack to mimic the default controller behaviour in Horde 5 (Be authenticated or be relegated to the login page). You will be able to define application-specific default stacks or request-specific stacks. As Middlewares are a public standard, we might be able to leverage middlewares existing out in the wild or attract microframework users to some horde built middlewares. I want to make it easier for coders to build horde apps without relearning everything they needed to learn for laravel, laminas or symfony. I also want to make it easier for everyone to cooperate. Horde is among the oldest framework vendors, predating most of PEAR and Zend. I think we still have some bits to offer.

Missing Bits:

  • While I did some implementation of UploadedFileInterface, it is still quite basic
  • UploadedFileFactoryInterface is missing as I have not yet built the server side use cases
  • Unit Tests need to be adapted to the new code base. Is there some PSR Acid Test out there?
  • I began implementing the ext-http (PECL_HTTP) backend but stopped as I am unsure about it. That extension is in version 4 now and still services version 3, but we have backends for versions 1 and 2. I need to learn more about it and decice if it makes sense to invest into that aspect.

bookmark_borderMaintaina Horde: Fourth Of July Additions

I packaged some more exotic horde apps and libraries for use with the composer installer and the FRAMEWORK_6_0 codebase. This was mostly formal conversion work, no actual testing was done. Some of these items might not even be very useful to most administrators. Nevertheless, I want to close the gap between what is available in the horde git-tools install and what can be installed through the horde installer plugin for composer.

These apps are now available:

  • refactor (refactoring utility)
  • trean (bookmarks)
  • ulaform (Forms app)
  • sesha (H4ish inventory app)
  • skeleton (template application)
  • sam (Spam Assassin Integration app)
  • operator (phone call details reader)
  • pastie (simple H4ish pastebin app)

The libraries were previously not available for H6 and now have seen their alpha release:

  • horde/thrift
  • horde/service_urlshortener
  • horde/service_vimeo
  • horde/service_facebook
  • horde/service_twitter
  • horde/scribe
  • horde/reflection
  • horde/pgp
  • horde/rampage
  • horde/oauth
  • horde/kolab_resource
  • horde/pdf
  • horde/lens
  • horde/openxchange
  • horde/mongo
  • horde/memcache

I wish you all a joyful fourth of july.

There are still some items missing, including the Klutz cartoon reader app and some Kolab related libraries.

bookmark_borderComposer Installer gets Horde Themes

A while back I added theme package support to the composer installer for horde (horde-installer-plugin). There are some Horde themes or theme customisations available out there, but they come as zip files you have to manually deploy to the right directories, often spanning multiple apps.

The installer recognizes themes and generates appropriate symlinks in the /web dir to make them available.
You can review maintaina-com/theme-hochschule as a template theme. The hochschule theme is more or less a clone of the standard horde theme, but I might add some tweaks at some point as the user of that themes requires it. Themes are registered into a json file to facilitate operations like regenerating the link dir independent of composer actions, but this has not yet been implemented.

The installer handles the main horde theme in the horde/ sub directory and any app specific additions to the theme in the respective folder. In theory, you could also divide a theme into multiple packages, for example a “theme-foo” main package and a “theme-foo-kronolith” package for calendar specific additions. I did not yet complete support for this style as I currently do not need it. I see the use case though as I take care of some unpublished horde apps and might require it one day.

If you happen to have created a horde4/5 theme which might be interesting to the general public, I am glad to help you adopt it into a package for the H6 composer installer.

bookmark_borderNo more master branch in maintaina horde

I am changing the default branch in all maintaina-com/ horde repos to be the FRAMEWORK_6_0 branch. In a separate next step, the master branch on these repos will be removed.

This is not due to any semantic discussion of technical terms like “master”. I am simply acknowledging reality. At the moment I cannot hope to get all those changes merged into horde’s proper master branches. I do incorporate their advances into maintaina but it is not going to the tight feedback loop I would wish to have.

I have no use for a branch pretending to be something different than or beyond the FRAMEWORK_6_0 venture. I had README’s in all those master branches warning against using them. It is way better to simply get rid of them now.