Skip to content

Refactor VarRenderer class to use candidates for class loading#119

Closed
TDannhauer wants to merge 1 commit into
FRAMEWORK_6_0from
fix/VarRenderer_class_candidates
Closed

Refactor VarRenderer class to use candidates for class loading#119
TDannhauer wants to merge 1 commit into
FRAMEWORK_6_0from
fix/VarRenderer_class_candidates

Conversation

@TDannhauer

Copy link
Copy Markdown
Contributor

Fix Horde_Core_Ui_VarRenderer::factory() app renderer resolution

Summary

  • Fix Horde_Core_Ui_VarRenderer::factory() so lowercase application IDs in varrenderer_driver (e.g. ['kronolith', 'html']) resolve to the correct {App}_Ui_VarRenderer_{Driver} class via Composer autoload.
  • Remove the broken legacy include_once fallback that could instantiate Horde_Core_Ui_VarRenderer_* after loading an application renderer file.
  • Use Horde\Util\HordeString for string normalization instead of deprecated Horde_String.

Problem

Horde applications extend Horde_Core_Ui_VarRenderer_Html with app-specific classes (e.g. Kronolith_Ui_VarRenderer_Html, Turba_Ui_VarRenderer_Html) to render custom form field types. Forms pass a driver tuple to the form renderer:

['varrenderer_driver' => ['kronolith', 'html']]

When the factory cannot load the application renderer, form fields fall back to Horde_Core_Ui_VarRenderer_Html::_renderVarInputDefault(), which outputs inline HTML such as:

Warning: Unknown variable type …

Those messages are usually not written to the application log.

Root cause

In Horde_Core_Ui_VarRenderer::factory():

  1. The driver segment was normalized with Horde_String::ucfirst() (htmlHtml).
  2. The application segment was used verbatim (kronolithkronolith).
  3. The factory requested class kronolith_Ui_VarRenderer_Html, which is not in Composer’s classmap (Kronolith_Ui_VarRenderer_Html is).

Autoload failed. The legacy path then:

  1. include_once’d the app’s lib/Ui/VarRenderer/Html.php (defining Kronolith_Ui_VarRenderer_Html, etc.).
  2. Checked class_exists('Horde_Core_Ui_VarRenderer_Html') — always true.
  3. Returned new Horde_Core_Ui_VarRenderer_Html() — the base renderer without app-specific _renderVarInput_* methods.

This regressed as applications renamed renderers to {App}_Ui_VarRenderer_{Driver} for classmap autoloading without updating the factory fallback.

Solution

lib/Horde/Core/Ui/VarRenderer.php

  • Resolve the renderer class through autoload only (no manual include_once or registry fileroot paths).
  • Try candidate class names in order:
    1. {Ucfirst(app)}_Ui_VarRenderer_{Ucfirst(driver)} — matches Composer classmap names.
    2. {app}_Ui_VarRenderer_{Ucfirst(driver)} — only if different from (1), for callers that already pass a capitalized app id.
    3. Horde_Core_Ui_VarRenderer_{Ucfirst(driver)} — fallback when an app has no custom renderer.
  • Use Horde\Util\HordeString::ucfirst() and basename() for driver normalization.

Package

horde/coreHorde_Core_Ui_VarRenderer::factory() only.

Test plan

  • In an application with a custom lib/Ui/VarRenderer/Html.php and lowercase varrenderer_driver (e.g. Kronolith calendar edit, Turba contact edit, Ingo filter forms), open a form that uses app-specific field types and confirm controls render correctly (no “Unknown variable type” warnings).
  • Trigger a reload action on a field that uses Horde_Form_Action_reload and confirm the re-rendered form still uses the application renderer.
  • Confirm a form with varrenderer_driver set to 'html' only (no app segment) still uses Horde_Core_Ui_VarRenderer_Html.
  • Confirm an application without a custom VarRenderer still receives Horde_Core_Ui_VarRenderer_Html when passing ['someapp', 'html'].

Notes for reviewers

  • Failures were user-visible HTML warnings from the default var renderer, not thrown exceptions.
  • Call sites may continue passing lowercase registry app ids; no caller changes are required in this PR.

@TDannhauer TDannhauer requested a review from ralflang May 22, 2026 21:09
@TDannhauer TDannhauer closed this May 22, 2026
@TDannhauer TDannhauer deleted the fix/VarRenderer_class_candidates branch May 22, 2026 21:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant