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

Prototype for new site configuration infrastructure #1450

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

cpeel
Copy link
Member

@cpeel cpeel commented Mar 9, 2025

This PR is a prototype for a new site configuration infrastructure (see #1256) that will allow us to:

  1. stop using global variables -- beyond not using globals being a best practice, this makes phpunit much happier
  2. have the configuration variables be typed (yay!)
  3. allow variables to have default values, allowing us to add new ones more easily

Now, instead of the config values being in the global context, they are only accessible in the SiteConfig static object, so:

global $preceding_proofer_restriction;
echo $preceding_proofer_restriction;

becomes

echo SiteConfig::$preceding_proofer_restriction;

The new method re-uses the existing site_vars.php file which means there are no changes required to how the code is configured, just how we use those configuration variables. If we went forward with this approach, a second PR would later move away from the bash-based configuration model to just using the PHP file directly.

Keeping the configurations in a PHP file was intentional because PHP files are cached in the opcache and do not need to go to disk or be processed upon access, unlike a yaml, json, or ini-based file.

I have a fully-converted branch (site-config) that updates all config variables uses (with the exception of the 4 mentioned at the end of SiteConfig::load()) passes all unit tests and smoke tests but it's huge and I wanted to focus the initial review on the proposed system rather than all of the individual changes. If we agree that this approach makes sense I'll close this PR and open a new one with the full set of changes.

Specific questions I'd like your feedback on:

  • Thoughts on the SiteConfig class, both as a structure, its status as a static (ie: singleton).
  • The verbosity of needing SiteConfig:: prefixed to use the configs -- this explicitness seems like a good thing to me, but it is wordier.

I evaluated using an existing package like Symfony's Config package but it's huge and very complex and I don't think we need that complexity.

@cpeel cpeel self-assigned this Mar 9, 2025
Copy link
Collaborator

@jchaffraix jchaffraix left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's a step in the right direction!

One high-level comment would be whether we want to include all the variables under a single object: we used to have the DB configuration by itself and could use N objects grouped based on some criteria as we move those variables out of the global scope.

private static bool $_is_loaded = false;

// alert messages
public static bool $maintenance = false;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we could make the SiteConfig object immutable.

Unfortunately, I don't think this is possible with all the fields static as we would need a specific instance. This could be done through a singleton (e.g. SiteConfig::get()) and making the fields readonly, this would be a slightly longer than the current scheme but it would enforce that the fields can't be changed mid-request.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I originally started with an object-based scheme which meant accessing things was SiteConfig::get()->value which seemed more unwieldy than SiteConfig::$value when I started using it.

re: immutability - we'd need to think about how to make default values work since we can't set them and override them. I can probably figure that out. We'll also need to figure out how to handle some unit test that do need to override these (which is decidedly an anti-pattern but also where we are right now).

It's a good suggestion, let me noodle over it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I've figured out how to make default values work with readonly, but as I think more about our unit tests and wanting to test variations I'm unclear how we do that without either making the config modifiable at runtime or allowing the creation, and somehow use, of a new SiteConfig object.

I'm not sure enforcing immutability is important enough for the effort. Thoughts?

@@ -49,7 +49,7 @@ if (!defined('SKIP_DB_CONNECT')) {
} catch (Exception $e) {
// If we're in maintenance mode, don't die here - we'll more gracefully
// error out later
if (!$maintenance) {
if (!SiteConfig::$maintenance) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The prefix is fine. As you pointed it, it is worth being explicit and the overhead seems small to me.

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.

2 participants