Skip to content

Conversation

@TDannhauer
Copy link
Contributor

Fix: Country field prompt not initialized correctly

Problem

When creating or editing contacts in Turba with country fields, the prompt option (e.g., "-- select --") was not being displayed in the dropdown. Instead, the browser was defaulting to the first country option (Afghanistan) when no country was selected, even though the country field configuration specified 'params' => array('prompt' => true).

Root Cause

The Horde_Form_Type_country::init() method was incorrectly extracting the prompt parameter from the $params array. When call_user_func_array() is called with an associative array like ['prompt' => 1] and the function uses variadic parameters ...$params, PHP's behavior with associative arrays means that $params itself becomes the associative array (not $params[0]).

The original code was trying to access $params[0], which doesn't exist when an associative array is passed, resulting in $prompt being null, and the prompt option never being created.

Impact

  • Country dropdowns showed "Afghanistan" (first option) when no country was selected
  • Users couldn't see or use the prompt option to explicitly indicate "no country selected"
  • Form validation and data storage worked correctly, but the UI was misleading

Solution

Updated Horde_Form_Type_country::init() to correctly handle associative array parameters:

  1. First checks if $params itself has the 'prompt' key (for associative arrays)
  2. Falls back to checking $params[0]['prompt'] (for numeric arrays)
  3. Falls back to using $params[0] directly (for direct value passing)

This ensures the prompt parameter is correctly extracted regardless of how call_user_func_array() passes it.

Changes

File: vendor/horde/form/lib/Horde/Form/Type.php

Method: Horde_Form_Type_country::init()

// Before:
$prompt = $params[0] ?? null;

// After:
$prompt = null;
if (is_array($params) && isset($params['prompt'])) {
    // $params is directly the associative array with 'prompt' key
    $prompt = $params['prompt'];
} elseif (isset($params[0]) && is_array($params[0]) && isset($params[0]['prompt'])) {
    // $params[0] is an array with 'prompt' key (fallback for numeric arrays)
    $prompt = $params[0]['prompt'];
} elseif (isset($params[0]) && !is_array($params[0])) {
    // Direct value passed as first argument
    $prompt = $params[0];
}

Testing

  • ✅ Create a new contact without selecting a country → prompt option appears and is selected
  • ✅ Edit an existing contact with empty country field → prompt option appears and is selected (not Afghanistan)
  • ✅ Select a country → country is saved and displayed correctly
  • ✅ Edit and unselect country → value is removed properly, prompt option is selected

Related Issues

This fix ensures that country fields (and potentially other enum fields) properly initialize their prompt options when configured with 'params' => array('prompt' => true) in the attribute configuration.

Enhance init method to handle associative arrays for prompt.
@TDannhauer
Copy link
Contributor Author

TDannhauer commented Dec 17, 2025

@amulet1 : I think regarding to my PHP knowledge I'm proud of the digging /analysis part, but for me it smells my solution is not appropriate. I think the underlying problem might affect more than only country selectors.

please review and make up your mind as well. Many thanks!

This would fix horde/turba#21

@amulet1
Copy link
Collaborator

amulet1 commented Dec 19, 2025

In this particular case I think this code is sufficient:

$prompt = $params['prompt'] ?? $params[0] ?? null;

Note, the is_array($params) check is not needed as $params is guaranteed to be an array due to the ...$params in the init function definition.

However, this is just one case of a general issue. There are multiple cases like that with other childs of Horde_Form_Type. Rather than fix them one-by-one, I suggest we fix them at a different level - see #12.

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.

3 participants