Shared configuration accessor library for OpenCoreEMR modules.
Extracts the duplicated config accessor pattern from OCE modules into a single Composer package. Each module provides a ModuleConfigDescriptor instead of copy-pasting six config classes.
composer require opencoreemr/oce-lib-module-configuse OpenCoreEMR\ModuleConfig\ModuleConfigDescriptor;
$descriptor = new ModuleConfigDescriptor(
yamlKeyMap: [
'enabled' => 'oce_sinch_fax_enabled',
'api_secret' => 'oce_sinch_fax_api_secret',
// short YAML key => internal config key
],
envOverrideMap: [
'oce_sinch_fax_enabled' => 'OCE_SINCH_FAX_ENABLED',
'oce_sinch_fax_api_secret' => 'OCE_SINCH_FAX_API_SECRET',
// internal config key => env var name
],
envConfigVar: 'OCE_SINCH_FAX_ENV_CONFIG',
conventionalConfigPath: '/etc/oce/sinch-fax/config.yaml',
conventionalSecretsPath: '/etc/oce/sinch-fax/secrets.yaml',
configFileEnvVar: 'OCE_SINCH_FAX_CONFIG_FILE',
secretsFileEnvVar: 'OCE_SINCH_FAX_SECRETS_FILE',
);use OpenCoreEMR\ModuleConfig\ConfigFactory;
use OpenEMR\Core\OEGlobalsBag;
$factory = new ConfigFactory($descriptor, OEGlobalsBag::getInstance());
$config = $factory->createConfigAccessor();
$apiSecret = $config->getString('oce_sinch_fax_api_secret');
$enabled = $config->getBoolean('oce_sinch_fax_enabled');
$retryCount = $config->getInt('oce_sinch_fax_retry_count', 3);The factory returns the right accessor based on what's available:
- YAML files exist →
FileConfigAccessor(reads YAML, resolves secrets, applies env overrides) - Env config var set →
EnvironmentConfigAccessor(reads from env vars only) - Neither →
GlobalsAccessor(reads from OEGlobalsBag / OpenEMR database settings)
For secrets stored in Google Cloud Secret Manager, use a _secrets block in your secrets YAML:
# /etc/oce/sinch-fax/secrets.yaml
_secrets:
provider: gcp-secret-manager
project: my-tenant-project-id
map:
api_secret: fax_api_secret # Terraform-provisioned secret name
# Non-secret values coexist as plain YAML
webhook_password_bcrypt_hash: "$2y$10$..."Resolution order:
YAML loaded → imports processed → _secrets resolved → env var overrides applied
Env var overrides always win. The google/cloud-secret-manager library is a suggest dependency — it's only needed if you use _secrets.provider: gcp-secret-manager.
All accessors implement four typed methods:
interface ConfigAccessorInterface
{
public function getString(string $key, string $default = ''): string;
public function getBoolean(string $key, bool $default = false): bool;
public function getInt(string $key, int $default = 0): int;
public function has(string $key): bool;
}No mixed getter — consumers must use typed accessors.
composer install
composer check # php-lint, phpcs, phpstan
composer test # phpunitGPL-3.0-or-later