<?php

namespace Spark\Configuration;

use Auryn\Injector;

class ConfigurationSet implements ConfigurationInterface
{
    /**
     * @var array
     */
    protected $classes;

    /**
     * @param array $classes
     */
    public function __construct(array $classes)
    {
        $this->validateClasses($classes);

        $this->classes = $classes;
    }

    /**
     * @inheritDoc
     */
    public function apply(Injector $injector)
    {
        foreach ($this->classes as $class) {
            $configuration = $injector->make($class);
            $configuration->apply($injector);
        }
    }

    /**
     * @param array $classes
     * @throws \DomainException if any classes cannot be loaded
     */
    protected function validateClasses(array $classes)
    {
        $invalid = array_filter(
            $classes,
            function ($class) {
                return !is_subclass_of($class, ConfigurationInterface::class);
            }
        );
        if ($invalid) {
            $message = 'Classes cannot be loaded or do not implement ConfigurationInterface: ' . implode(', ', $invalid);
            throw new \DomainException($message);
        }
    }
}

<?php

namespace Spark\Configuration;

use Auryn\Injector;

class ConfigurationSet implements ConfigurationInterface
{
    /**
     * @var array
     */
    protected $classes = [];

    /**
     * @param array $classes
     */
    public function __construct(array $classes = [])
    {
        foreach ($classes as $class) {
            $this->add($class);
        }
    }

    /**
     * Add a new configuration class to the set
     *
     * @param string $class
     *
     * @return self
     */
    public function add($class)
    {
        $this->validate($class);

        $this->classes[] = $class;

        return $this;
    }

    /**
     * @inheritDoc
     */
    public function apply(Injector $injector)
    {
        foreach ($this->classes as $class) {
            $configuration = $injector->make($class);
            $configuration->apply($injector);
        }
    }

    /**
     * Checks that the given class is valid for configuration
     *
     * @param string $class
     *
     * @return void
     *
     * @throws \DomainException If the class is not of the expected type
     */
    protected function validate($class)
    {
        if (!is_subclass_of($class, ConfigurationInterface::class)) {
            throw new \DomainException(sprintf(
                'Configuration class `%s` must implement ConfigurationInterface',
                $class
            ));
        }
    }
}

Modify configuration set to allow additions
Modify configuration set to allow additions

Enables the user to add custom config to the default set.
