Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Empty/null confusion with preferences due to switch to Entity-based DB access #1769

Open
kainhofer opened this issue Mar 15, 2025 · 0 comments

Comments

@kainhofer
Copy link
Contributor

In Commit a00346e, I switched the Preferences handling from direct database access to Entity-based DB access.

However, this introduced a subtle change in value handling and I'm currently runing into issues with my change to the preferences handling to use the Entity-based Preferences class. In particular, there are several preferences that have an empty default, like

    'system_url_imprint'             => '',
    'system_url_data_protection'     => '',

There are several places in the codebase that rely on Preferences having an empty string value, or that Preferences always have a string value (argument type matching of funciton calls).

However, the Entity class never writes an empty string as column value, but is hardcoded to store null instead (Entity::save, file Entity.php lines 796-800):

                        if ($value === '' || $value === null) {
                            $queryParams[] = null;
                        } else {
                            $queryParams[] = $value;
                        }

As a consequence, the preferences listed above are stored with a null value rather than an empty string into the db. On the other hand, the SettingsManager relies on the preferences having a string value:
private function load(string $name): string

    {
        $sql = 'SELECT prf_value
                  FROM '.TBL_PREFERENCES.'
                 WHERE prf_org_id = ? -- $this->orgId
                   AND prf_name   = ? -- $name';
        $pdoStatement = $this->db->queryPrepared($sql, array($this->orgId, $name));
        if ($pdoStatement->rowCount() === 0 && $this->throwExceptions) {
            throw new \UnexpectedValueException('Settings name "' . $name . '" does not exist!');
        }
        return $pdoStatement->fetchColumn();
    }

For example, a clean installation fails:
Image

Image

As this is a change quite deep inside the core code, I'd like your ideas how this should be best fixed.

  • What's the reason to never store an empty string and rather use null instead in all cases?
  • Should there be a significant difference for preferences with a null value and an empty string value?
  • What is the best solution in your eyes:
    • Change the Preference class to return '' for null values (return $this->settings[$name]??'';)
    • Change the SettingsManager class to allow null values as return values
    • Change the Entity class to store null as null and empty strings as empty strings
    • Override the methods in the Preference class to handle empty strings different for the adm_preferences table only.
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

No branches or pull requests

1 participant