oddgreg/nine-loaders

Container-Agnostic Configuration Loaders and Sets.

dev-master 2016-08-27 17:29 UTC

This package is not auto-updated.

Last update: 2024-10-24 02:56:56 UTC


README

This repository is a collection of classes that manage configurations. Internally, the loader and configuration sets do not use nor require a dependency injector or service locator. A container may be passed into the LoaderSet, which passes it through the ConfigurationSet and on to the individual Configurators. The Configurator then populates the container as required.

The main repository classes are:

  1. LoaderSet -- A set of Configuration Sets.
  2. ConfigurationSet -- A set of Configurators.
  3. Configurator -- A configurator.
  4. ConfigFileReader and ConfigFileWriter -- Configuration File Reading and Writing.

Quick Overview

The diagram below reveals the class hierarchy of the core classes.

Relationship Diagram

  • A LoaderSet is a collection of ConfigurationSet objects. Each LoaderSet may pass a single container reference to a ConfigurationSet. Each loader set manages and initiates loading and applying configuration sets.

Subclass the LoaderSet class if you need a specific identifier (ie: AurynLoaderSet) or need to further initialize the environment.

  • A ConfigurationSet is a collection of Configurator objects. Each collection set manages inserting, loading and applying Configurator objects.

The ConfigurationSet class handles the insertion, selection, loading and applying of the Configurators it contains.

  • A Configurator class handles the configuration of a single scope. i.e.: a TwigConfigurator may handle the configuration required for Twig while DatabaseConfigurator or MiddlewareConfigurator and so on would handle their respective configuration scopes.

  • ConfigFileReader and ConfigFileWriter handle the reading and writing of configuration files. Files may be in .php, .yml or .json format. XML is not supported out of the box.

In some cases you may only require the ConfigFileReader for managing access to file-based configuration values.

Example Configuration Settings file.

return [
    // example use of a subclassed configuration set
    // which handles its own configurators etc. or
    // it may do something entirely different.
    ExampleConfigurationSet::class => [
        'name'        => 'example.config',
        'config_path' => __DIR__ . '/../config/examples/',
        'priority'    => 'high',
    ],
    // example of a labeled ConfigurationSet
    // note that the label isn't significant. The name
    // parameter defines the name given to the set.
    'views'                        => [
        'name'        => 'example.views',
        'config_path' => __DIR__ . '/../config/',
        'priority'    => 'low',
        'config'      => [
            BladeConfigurator::class    => ['name' => 'blade', 'dataset' => 'view.blade',],
            TwigConfigurator::class     => ['name' => 'twig', 'dataset' => 'view.twig'],
            MarkdownConfigurator::class => ['name' => 'markdown', 'dataset' => 'view.markdown'],
        ],
    ],
];

Configuration File Handling

The simplest of the classes deal with reading, accessing and writing directory-located config files.

Configuration and Loader Classes.

The Nine\Loaders package provides a method for configuring dependency injectors, service providers, and general classes. Mainly driven by one or more configuration files, the package also provides a configuration builder which can read and generate configuration files.

Because the package doesn't depend on any particular container or framework, it can be used in just about anything.

PHP, YAML and JSON are supported. PHP is the default.

Installation

Please note that this package is intended for PHP 7.

  1. Install Composer.
  2. type: composer require oddgreg/nine-config --no-dev

Optionally, if you want to run the tests, remove the --no-dev from the above.

Using ConfigFileReader Without Sets

The ConfigFileReader class can be used without any other of the configuration set classes. In a simple configuration case, there may be no need or desire to handle config files any other way.

Because ConfigFileReader caches configurations from a file the first time it is read, subsequent access is fast. You will only ever load what is needed at the time.

Instantiating and Using the ConfigFileReader Class

// instantiate the reader
$config = new ConfigFileReader(__DIR__ . '/../config/');

// nothing much else to do. The class will read config files on demand.
// this will read $basePath . 'view.php' then return the 'twig' index array.
$twigConfig = $config['view.twig'];

// -- or go deeper --
$twigEnabled = $config['view.twig.enabled'];

// multiple requests from the same config source (ie: view.php) do not 
// reload the file. The ConfigFileReader caches requests.

Using ConfigFileWriter to Modify and Write Config Files

ConfigFileReader cannot modify or write configuration files. Using it insures that nothing will change in the configuration files throughout the life of its use. Sometimes it is useful to modify one or more configuration files during certain stages of application execution. Where this is necessary, the ConfigFileWriter is provided.

ConfigFileWriter has ConfigFileReader as a dependency. The following provides a simple example:

// create and preload a collection of configurations.
$reader = (new ConfigFileReader(CONFIG))->preloadPath();

// create the writer containing pre-loaded configurations.
$writer = new ConfigFileWriter($reader);

// modify the configuration (both methods are equivalent.)
$writer->view_markdown_defaults_debug = false;
// -- or --
$writer['view.markdown.defaults.debug'] = false;

// extract an outer key array and write it to a new file
$writer->exportPHPFile(
    // the path to where the new file will be written
    CONFIG . '../temp/',
    
    // the outer key to extract and write (ie: ['view'] -> 'CONFIG/view.php')
    // optionally, this can be set to '*' to export the entire cache.
    'view',
    
    // optionally, force the filename to something other than the key
    'production.php'
    
    // note that the key to read the new configuration is 'production', and may be read as follows:
    $reader = (new ConfigFileReader(CONFIG . '../temp/'));
    $productionConfig = $reader->read('production');        
);

Note: The ConfigFileWriter class does not modify the ConfigFileReader dependency cache in any way.

The result will be a new config file ('production.php') that reflects the new state of the configuration.

Finally, the current ConfigFileWriter configuration state may be used to initialize the cache of a new ConfigFileReader:

$reader = new ConfigFileReader($writer);

Package Loader and Configuration Classes

The following classes are provided by the package:

And the following support classes are included:

How Loader Classes Work

Overview

  1. A LoaderSet is a repository of ConfigurationSets.
  2. A ConfigurationSet is a repository of Configurators.
  3. A Configurator is a repository of Configuration items, and provides a method for loading configuration data, and configuring services.

Common Loader Methods

Example LoaderSet Configuration File

i.e.: config/loaders/container.php

return [
    AurynConfigurationSet::class => [
        // the identifier given to this configuration set.
        'name'        => 'app.di',
        // the path to the folder that contains configuration files
        // for this set.
        'config_path' => CONFIG,
        // the loader priority.
        'priority'    => 'high', # 'high' | 'normal' | 'low' | int
        // the list of Configurators in this set.
        'config'      => [
            // the configurator
            BladeConfigurator::class    => [
                // the identifier for this Configurator
                'name'     => 'blade',
                // the data set loaded by the ConfigFileReader class
                // defaults to '' if not supplied.
                'dataset' => 'view.blade',
                // the set priority. Defaults to 'normal' if not supplied.
                'priority' => 'normal',
                // any settings to add or to override settings from the data set.
                // defaults to [] if not supplied.
                'config'   => ['cargo' => 'shamalam'],
            ],
            TwigConfigurator::class     => ['name' => 'twig', 'dataset' => 'view.twig'],
            MarkdownConfigurator::class => ['name' => 'markdown', 'dataset' => 'view.markdown'],
        ],
    ],
    IlluminateConfigurationSet::class => [
        'name' 			=> 'app.container',
        'config_path' 	=> CONFIG,
        'priority' 		=> 'high',
        'config' 		=> [
            BladeConfigurator::class    => [
                'name'     => 'blade',
                'dataset' => 'view.blade',
            ],
            TwigConfigurator::class     => ['name' => 'twig', 'dataset' => 'view.twig'],
            MarkdownConfigurator::class => ['name' => 'markdown', 'dataset' => 'view.markdown'],
        ],
    ],
];

A descriptive example:

$config = new ConfigFileReader(CONFIG . 'loaders/');
$reflector = new LoaderReflector;

// load the dependency injector
(new LoaderSet($reflector, 'container', $config->read('container')))
    ->loadAll()->configure;

// load the configuration for an application
(new LoaderSet($reflector, 'application', $config->read('app')))
    ->loadAll()->configure;

**-- or --**

// load the configuration for an api
(new LoaderSet($reflector, 'api', $config->read('api')))
    ->loadAll()->configure();

To get access to individual sets and configurators:

$loader['app.di'] returns an array containing the first set. (AurynConfigurationSet)

$loader['app.di]['set'] returns the instance of AurynConfigurationSet.

$loader['app.di]['set']['blade'] returns the instance of the BladeConfigurator.

$loader['app.di]['set']['blade']->getSettings() returns the loaded settings of BladeConfigurator.

$loader['app.di']['set']->getConfigurators() returns an array of Configurators containing meta information. Below is a sample of results based on the example above:

   |  blade => array (4)
   |  |  configurator => BladeConfigurator #c6f0
   |  |  |  dataset protected => "view.blade" (10)
   |  |  |  key protected => "blade" (5)
   |  |  |  priority protected => 100
   |  |  |  settings protected => array (2)
   |  |  |  |  enabled => TRUE
   |  |  |  |  defaults => array (2)
   |  |  |  |  |  cache => ".../cache/blade" (42)
   |  |  |  |  |  template_paths => array (7)
   |  |  |  |  |  |  0 => ".../views/" (51)
   |  |  |  |  |  |  1 => ".../views/assets/" (58)
   |  |  |  |  |  |  2 => ".../views/templates/default/" (69)
   |  |  |  |  |  |  3 => ".../views/templates/default/forms/" (75)
   |  |  |  |  |  |  4 => ".../views/templates/default/pages/" (75)
   |  |  |  |  |  |  5 => ".../views/templates/" (61)
   |  |  |  |  |  |  6 => ".../views/debug/" (57)
   |  |  configured => TRUE
   |  |  loaded => TRUE
   |  |  profile => array (3)
   |  |  |  added => 1469154406.5784
   |  |  |  loaded => 1469154423.0254
   |  |  |  configured => 1469154423.0259
   |  twig => array (4)
   |  |  configurator => TwigConfigurator #f348
   |  |  |  dataset protected => "view.twig" (9)
   |  |  |  key protected => "twig" (4)
   |  |  |  priority protected => 100
   |  |  |  settings protected => array (2)
   |  |  |  |  enabled => TRUE
   |  |  |  |  defaults => array (5)
   |  |  |  |  |  type => 4
   |  |  |  |  |  filesystem => array (7)
   |  |  |  |  |  |  0 => ".../views/" (51)
   |  |  |  |  |  |  1 => ".../views/assets/" (58)
   |  |  |  |  |  |  2 => ".../views/templates/default/" (69)
   |  |  |  |  |  |  3 => ".../views/templates/default/forms/" (75)
   |  |  |  |  |  |  4 => ".../views/templates/default/pages/" (75)
   |  |  |  |  |  |  5 => ".../views/templates/" (61)
   |  |  |  |  |  |  6 => ".../views/debug/" (57)
   |  |  |  |  |  options => array (4)
   |  |  |  |  |  |  cache => ".../cache/twig" (41)
   |  |  |  |  |  |  debug => NULL
   |  |  |  |  |  |  auto_reload => NULL
   |  |  |  |  |  |  strict_variables => NULL
   |  |  |  |  |  templates => array ()
   |  |  |  |  |  form => array (1)
   |  |  |  |  |  |  templates => array (1)
   |  |  |  |  |  |  |  0 => "bootstrap_3_horizontal_layout.html.twig" (39)
   |  |  configured => TRUE
   |  |  loaded => TRUE
   |  |  profile => array (3)
   |  |  |  added => 1469154406.5786
   |  |  |  loaded => 1469154423.0255
   |  |  |  configured => 1469154423.0259
   |  markdown => array (4)
   |  |  configurator => MarkdownConfigurator #4e55
   |  |  |  dataset protected => "view.markdown" (13)
   |  |  |  key protected => "markdown" (8)
   |  |  |  priority protected => 100
   |  |  |  settings protected => array (1)
   |  |  |  |  defaults => array (5)
   |  |  |  |  |  class => "MarkdownExtra" (13)
   |  |  |  |  |  template_paths => array (4)
   |  |  |  |  |  |  0 => ".../views/templates" (60)
   |  |  |  |  |  |  1 => ".../views/templates/forms" (66)
   |  |  |  |  |  |  2 => ".../views/templates/default" (68)
   |  |  |  |  |  |  3 => ".../views/templates/default/hello" (74)
   |  |  |  |  |  debug => TRUE
   |  |  |  |  |  html5 => TRUE
   |  |  |  |  |  keepListStartNumber => TRUE
   |  |  configured => TRUE
   |  |  loaded => TRUE
   |  |  profile => array (3)
   |  |  |  added => 1469154406.5787
   |  |  |  loaded => 1469154423.0255
   |  |  |  configured => 1469154423.0259

LoaderSet Configuration Definition

The structure of the LoaderSet configuration file is as follows:

[ <class name of ConfigurationSet> => [ <name>, <config_path>, <priority>, <config> ]
    where priority is optional.

ConfigurationSet Configuration Definition (<config>)

License: MIT

Copyright © 2016, Greg Truesdell - Part of the Formula Nine Framework.