{"id":25423294,"url":"https://github.com/magium/configuration-manager","last_synced_at":"2025-10-31T14:30:41.089Z","repository":{"id":62522575,"uuid":"80840105","full_name":"magium/configuration-manager","owner":"magium","description":"A library for managing context-based configuration for PHP applications","archived":false,"fork":false,"pushed_at":"2018-09-17T21:49:56.000Z","size":281,"stargazers_count":20,"open_issues_count":0,"forks_count":5,"subscribers_count":4,"default_branch":"develop","last_synced_at":"2024-04-20T14:14:48.073Z","etag":null,"topics":["configuration","configuration-by-code","configuration-by-environment","configuration-management","php","php-applications","xml","yaml"],"latest_commit_sha":null,"homepage":null,"language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/magium.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-02-03T15:11:59.000Z","updated_at":"2023-10-20T09:47:27.000Z","dependencies_parsed_at":"2022-11-02T13:46:33.261Z","dependency_job_id":null,"html_url":"https://github.com/magium/configuration-manager","commit_stats":null,"previous_names":[],"tags_count":58,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/magium%2Fconfiguration-manager","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/magium%2Fconfiguration-manager/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/magium%2Fconfiguration-manager/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/magium%2Fconfiguration-manager/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/magium","download_url":"https://codeload.github.com/magium/configuration-manager/tar.gz/refs/heads/develop","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239207437,"owners_count":19599963,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["configuration","configuration-by-code","configuration-by-environment","configuration-management","php","php-applications","xml","yaml"],"created_at":"2025-02-16T22:38:12.804Z","updated_at":"2025-10-31T14:30:39.652Z","avatar_url":"https://github.com/magium.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/magium/configuration-manager/badges/quality-score.png?b=develop)](https://scrutinizer-ci.com/g/magium/configuration-manager/?branch=develop) \n[![Code Coverage](https://scrutinizer-ci.com/g/magium/configuration-manager/badges/coverage.png?b=develop)](https://scrutinizer-ci.com/g/magium/configuration-manager/?branch=develop)\n[![Build Status](https://scrutinizer-ci.com/g/magium/configuration-manager/badges/build.png?b=develop)](https://scrutinizer-ci.com/g/magium/configuration-manager/build-status/develop)\n# The Magium Configuration Manager (MCM)\n\nThe Magium Configuration Manager provides a configuration setup that is similar to Magento's configuration management.  There are 3 purposes for this library:\n\n1. Provide a standardized configuration panel/CLI so developers don't need to do a code deployment to change a configuration value.\n2. Provide an inheritable interface where values can \"bubble up\" through child contexts\n3. Provide a unified (read merged) configuration interface for third parties that work in your application like magical unicorn dust.\n\nIn order for it to work for you it needs 3 things\n\n1. A few different configuration files (more details later)\n2. A database adapter to store persistent configuration values\n3. A cache adapter to store the processed configuration objects\n\nIf you want to see it in action, instead of reading about it, check out the introductory YouTube video.\n\n[![Magium Configuration Manager ](http://img.youtube.com/vi/76MLD9Kl2Lk/0.jpg)](http://www.youtube.com/watch?v=76MLD9Kl2Lk \"Magium Configuration Manager \")\n\n## Getting Started\n### Wiring Configuration\n\nThe core object is the [`ConfigurationRepository`](lib/Config/Repository/ConfigurationRepository.php) object.  That is what your application will typically interact with.  The intent is that all you need to do is require a `ConfigurationRepository` object (or an object implementing `ConfigInterface`)as a dependency and it all works out nicely.  \n\nIn other words, this:\n\n```\nuse Magium\\Configuration\\Config\\Repository\\ConfigInterface;\n\nclass Pinky\n{\n\n    protected $brain;\n    \n    public function __construct(ConfigInterface $brain) \n    {\n        $this-\u003ebrain = $brain;\n    }\n\n}\n\n$magiumFactory = new \\Magium\\Configuration\\MagiumConfigurationFactory();\nnew Pinky($magiumFactory-\u003egetConfiguration());\n\n```\n\nHowever, there is a bunch of wiring need to get done in order to make that work.  Thankfully, if you want to just use what I've written, you can use that and not have to worry about the writing.  Out of the box, MCM provides a configuration factory.  It will build the two classes that are needed: the manager **(provides the appropriate configuration object to the application)**, and the builder **(builds and populates the configuration object)**.\n\n#### Configuration Files\n\nBut before you can do any of that you need to provide a minimum of 3 (!) configuration files.  The are\n\n1. The global magium configuration file.  This contains a preset list of configuration files, cache adapter, and database adapter configurations.  It is typically called `magium-configuration.xml` and generally needs to be in the root of your project, preferably just below the `vendor` directory.\n2. The context configuration file.  This contains the context hierarchy.  It is usually called `contexts.xml` and should be in a location refenced in the `magium-configuration.xml` file.\n3. At least one actual configuration file.\n\n1 and 2 are actually really easy to get started.  You can write them by hand or you can use the handy dandy `vendor/bin/magium-configuration` CLI script.  The first time you run that it will ask you where to put both files.\n\n```\nphp vendor/bin/magium-configuration\nCould not find a magium-configuration.xml file.  Where would you like me to put it?\n  [0] C:\\Projects\\magium-configuration.xml\n  [1] C:\\Projects\\example\\magium-configuration.xml\n \u003e 1\nWrote XML configuration file to: C:\\Projects\\example\\magium-configuration.xml\nThe context file C:\\Projects\\example\\contexts.xml does not exist next to the magium-configuration.xml file.  Create it? y\n```\n\nOpen them up and take a look around.\n\n\u003e A quick word on XML.  Why is he using XML?  It's not cool anymore!  YAML or JSON would make me feel much better.\n\u003e\n\u003e The answer is that neither YAML, JSON, nor PHP files are self documenting.  I'm sure there are tools out there that might allow you to do some of that but there is nothing out there that compares to what is available for XML.  I am a firm believer that when introspection is be used for error detection or, more importantly, code completion, it significantly reduce the amount of time spent on getting things to work.  It simply requires less memorizing and less copy-and-pasting.  But that said, if you look in the /lib directory you will find that the intention is to support all of those formats for the masochists out there.  \n\nTake a look inside the `magium-configuration.xml` file.  Much of it is, I believe, self explanatory.  However, note the `persistenceConfiguration` and `cache` nodes.  Those are converted to arrays and passed into the `Zend\\Db\\Adapter\\Adapter` and `Zend\\Cache\\StorageFactory` classes, respectively.  Note, also, the `contextConfigurationFile` node.  That contains a reference to the next configuration file.\n\nYour magium-configuration.xml file may look something like this:\n\n```\n\u003c?xml version=\"1.0\" encoding=\"UTF-8\" ?\u003e\n\u003cmagiumBase xmlns=\"http://www.magiumlib.com/BaseConfiguration\"\u003e\n    \u003cpersistenceConfiguration\u003e\n        \u003cdriver\u003epdo_mysql\u003c/driver\u003e\n        \u003cdatabase\u003emagium_configuration\u003c/database\u003e\n        \u003cusername\u003eroot\u003c/username\u003e\n        \u003cpassword\u003epassword\u003c/password\u003e\n        \u003chostname\u003edatabase\u003c/hostname\u003e\n    \u003c/persistenceConfiguration\u003e\n    \u003ccontextConfigurationFile file=\"contexts.xml\" type=\"xml\"/\u003e\n    \u003cconfigurationDirectories\u003e\n        \u003cdirectory\u003econfig\u003c/directory\u003e\n    \u003c/configurationDirectories\u003e\n    \u003cconfigurationFiles\u003e\n        \u003cfile\u003esettings.xml\u003c/file\u003e\n    \u003c/configurationFiles\u003e\n    \u003ccache\u003e\n        \u003cadapter\u003eredis\u003c/adapter\u003e\n        \u003coptions\u003e\n            \u003cserver\u003edatabase:6379\u003c/server\u003e\n        \u003c/options\u003e\n    \u003c/cache\u003e\n\u003c/magiumBase\u003e\n```\n\nThe `contexts.xml` file does not need to be called that; that's just what the CLI creates by default.  It contains a hierarchical list of contexts.  Each context must be uniquely named, but they can be hierarchical.\n\n```\n\u003c?xml version=\"1.0\" encoding=\"UTF-8\" ?\u003e\n\u003cmagiumDefaultContext xmlns=\"http://www.magiumlib.com/ConfigurationContext\"\u003e\n    \u003ccontext id=\"production\" title=\"Production\"\u003e\n        \u003ccontext id=\"website1\" title=\"Website 1\"/\u003e\n        \u003ccontext id=\"website2\" title=\"Website 2\"/\u003e\n    \u003c/context\u003e\n    \u003ccontext id=\"development\" title=\"Development\" /\u003e\n\u003c/magiumDefaultContext\u003e\n```\n\nThere is always a default context that all contexts inherit from.  If you don't want contexts, just have the `\u003cmagiumDefaultContext /\u003e` node alone in there.\n\nThe structure allows for an overriding hierarchy.  That means that if there are two different values specified for `website1` and `website2` they will have two different values in the resulting config object.  However, if there is a value provided for the context `production` it will exist in both `website1` and `website2` unless overridden in those contexts.  Nice and easy.\n \n The next configuration file are the actual settings file.  There must be at least one, but there can also be many.  Hundreds, if you want.  They are all merged into one big meta configuration XML file which is used to denote the paths to retrieve the configuration settings.\n\nFor example, take two configuration files:\n\n```\n\u003cmagiumConfiguration xmlns=\"http://www.magiumlib.com/Configuration\"\u003e\n    \u003csection identifier=\"web\"\u003e\n        \u003cgroup identifier=\"items\"\u003e\n            \u003celement identifier=\"element1\" /\u003e\n        \u003c/group\u003e\n    \u003c/section\u003e\n\u003c/magiumConfiguration\u003e\n```\n\nand \n\n```\n\u003cmagiumConfiguration xmlns=\"http://www.magiumlib.com/Configuration\"\u003e\n    \u003csection identifier=\"web\"\u003e\n        \u003cgroup identifier=\"items\"\u003e\n            \u003celement identifier=\"element2\" /\u003e\n        \u003c/group\u003e\n    \u003c/section\u003e\n\u003c/magiumConfiguration\u003e\n```\n\nThey will merge together to create:\n\n```\n\u003cmagiumConfiguration xmlns=\"http://www.magiumlib.com/Configuration\"\u003e\n    \u003csection identifier=\"web\"\u003e\n        \u003cgroup identifier=\"items\"\u003e\n            \u003celement identifier=\"element1\" /\u003e\n            \u003celement identifier=\"element2\" /\u003e\n        \u003c/group\u003e\n    \u003c/section\u003e\n\u003c/magiumConfiguration\u003e\n```\n\nThe ID attributes are used to denote the actual paths that will be queried.  So, for this configuration, you can ask `Config` object for the values for `web/items/element1` and `web/items/element2`.\n\nAlso, you can provide default values and descriptions:\n\n```\n\u003cmagiumConfiguration xmlns=\"http://www.magiumlib.com/Configuration\"\u003e\n    \u003csection identifier=\"section\"\u003e\n        \u003cgroup identifier=\"group\"\u003e\n            \u003celement identifier=\"element1\"\u003e\n                \u003cdescription\u003eJust some silly value\u003c/description\u003e\n                \u003cvalue\u003eTest Value\u003c/value\u003e\n            \u003c/element\u003e\n        \u003c/group\u003e\n    \u003c/section\u003e\n\u003c/magiumConfiguration\u003e\n```\n\nThat is just the tip of the iceberg of configuration, though.  The configuration can be managed either via the CLI command using `bin/magium-configuration magium:configuration:set` or with an [included](tests/View/standalone/pub/index.php) web-based view manager.  There are additional configuration options to make that experience more valuable.  Following is an example that shows what some of these additional options may look like:\n\n```\n\u003c?xml version=\"1.0\" encoding=\"UTF-8\" ?\u003e\n\u003cmagiumConfiguration xmlns=\"http://www.magiumlib.com/Configuration\"\u003e\n    \u003csection identifier=\"website\" label=\"Website\" font-awesome=\"home\"\u003e\n        \u003cgroup identifier=\"contact\" label=\"Contact\"\u003e\n            \u003celement identifier=\"title\" label=\"Title\" /\u003e\n            \u003celement identifier=\"address\" label=\"Address\" type=\"textarea\"/\u003e\n            \u003celement identifier=\"city\" label=\"City\" /\u003e\n            \u003celement identifier=\"state\" label=\"State\" source=\"Magium\\Configuration\\Source\\Political\\USStates\" type=\"select\"/\u003e\n            \u003celement identifier=\"phone\" label=\"Phone\" type=\"tel\"/\u003e\n        \u003c/group\u003e\n        \u003cgroup identifier=\"contact_form\" label=\"Contact Form\"\u003e\n            \u003celement identifier=\"title\" label=\"Title\" /\u003e\n            \u003celement identifier=\"sendto\" label=\"Send To\" type=\"email\"/\u003e\n            \u003celement identifier=\"permitted\" type=\"select\"\u003e\n                \u003cpermittedValues\u003e\n                    \u003cvalue\u003eyes\u003c/value\u003e\n                    \u003cvalue\u003eno\u003c/value\u003e\n                \u003c/permittedValues\u003e\n            \u003c/element\u003e\n        \u003c/group\u003e\n    \u003c/section\u003e\n\u003c/magiumConfiguration\u003e\n```\n\n`/website` shows the `label` and `font-awesome` attributes, which provides more user friendly configuration interactions.  The `font-awesome` (also `glyphicon` ) attribute decorates the section with an icon from either of those collections.  \n\nOn the element side, looking at `website/contact/address`, you can see that there are different types of form fields available.  They are:\n\n* multi\n* select\n* text\n* textarea\n* url\n* tel\n* email\n* date (for future use)\n* datetime (for future use)\n\n You can also see that the individual elements can be populated from a source when looking at `website/contact/state`.  These sources can be used to prepopulate text fields or provide select options.  See the [source code](lib/Source) for a full list.\n \n#### Environment Variable Overrides\n\nYou can also override the values in your `magium-configuration.xml` file by using environment variables. This allows you to change the base settings, such as the local cache adapter host name, based off of the environment that you are running in.  For example, your development environment might have a Redis adapter sitting on the `localhost` but in production it lives at `cache.myhost`.   To handle this, set the value for `cache/options/server` to `cache.myhost` in the source code (to default to production).  Then in your *development* environment add this to your webserver config (or something like it):\n\n```\nlocation ~ \\.php$ {\n    fastcgi_pass     unix:/your_sock_location/nginxFastCGI.sock;\n    fastcgi_param    SCRIPT_FILENAME $document_root$fastcgi_script_name;\n    fastcgi_param    MCM_CACHE_OPTIONS_SERVER=localhost;\n    include          fastcgi_params;\n}\n```\n\nAny value in the `magium-configuration.xml` file can be overridden and replaced with an environment variable by creating the variable with the prefix `MCM_` and appending the node path to the node that you want to change.  \n\nFor example, looking at what we did above, it was for the configuration node `cache/options/server` and so we named our environment variable `MCM_CACHE_OPTIONS_SERVER`.\n\n#### Configuring Your Application\n\nIf you are going to use the basic factory included with the package, wiring MCM is pretty easy.\n\n```\n$factory = new \\Magium\\Configuration\\MagiumConfigurationFactory();\n$config = $factory-\u003egetManager()-\u003egetConfiguration(getenv('ENVIRONMENT'));\n```\n\nThat's it.  Then, wherever you are using that configuration object and (presuming that you are using the previous XML files) retrieving a configuration value is as easy as:\n\n```\necho config-\u003egetValue('web/items/element1');\n```\n\nMore examples, both raw and for various frameworks, will be found at the [Configuration Manager Examples](https://github.com/magium/magium-configuration-manager-examples) page.\n\n### Setting Configuration Values\n\nConfiguration values are set via the command line using the `vendor/bin/magium-configuration` script using the `magium:configuration:set` command.\n\nFor example, considering the previous configuration file, you can set the value by calling:\n\n```\nphp vendor/bin/magium-configuration magium:configuration:set section/group/element1 \"some value\"\n```\n\nThen when you call \n\n```\n$config-\u003egetValue('web/items/element1')\n```\n\nYou will get the configured value.\n\nAdditionally, if you want to set the value for a particular context you append it to the end of the `set` command:\n\n```\nphp vendor/bin/magium-configuration magium:configuration:set section/group/element1 \"some value\" website1\n```\n\nAnd that's about it.\n\n### Third Party Integration\n\nIf you are building any third party modules that need to be hooked into the MCM the easiest way is to hook in with `Magium\\Configuration\\File\\Configuration\\ConfigurationFileRepository`.  It is used when building the configuration object, prior to storing it in the cache.  Do this via Composer autoloaders.\n\n```\n{\n    \"autoload\": {\n        \"files\": [\n            \"registration.php\"\n        ]\n    }\n}\n```\ncomposer.json\n\n```\n\n$instance = \\Magium\\Configuration\\File\\Configuration\\ConfigurationFileRepository::getInstance();\n$instance-\u003eaddSecureBase(realpath('etc'));\n$instance-\u003eregisterConfigurationFile(\n    new \\Magium\\Configuration\\File\\Configuration\\XmlFile(\n        realpath(\n            'etc/settings.xml'\n        )\n    )\n);\n\n\n```\nregistration.php\n\nYour configuration settings are now included with your customer's application.  Note, however, that you should not have a `magium-configuration.xml` file or your own contexts file.  That is for the primary application to manage.\n\n### Moving forward\n\nHere are a list of features that I want to have included\n\n* ~~An HTML based UI for making configuration changes~~\n  * Embeddable user restrictions\n  * ACL resources\n* ~~A local/remote cache system that caches the configuration locally, but synchronizes with a remote cache~~\n* ~~Integrations/adapters with multiple third party Dependency Injection Containers, allowing you to either manage DI configuration centrally, and/or, modify DI configuration on the fly without requiring a deployment.~~ (kind of)\n* ~~Oh yes, and integration with persistent storage~~\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmagium%2Fconfiguration-manager","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmagium%2Fconfiguration-manager","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmagium%2Fconfiguration-manager/lists"}