Scheme   A
last analyzed

Complexity

Total Complexity 15

Size/Duplication

Total Lines 169
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

Changes 0
Metric Value
wmc 15
lcom 1
cbo 2
dl 0
loc 169
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 11 2
A load() 0 20 4
A identifier() 0 10 2
A entity() 0 14 2
A handleConfigure() 0 10 2
A configure() 0 21 3
1
<?php
2
namespace samsonphp\config;
3
4
use samsonphp\event\Event;
5
6
/**
7
 * Generic SamsonPHP core configuration system
8
 * @author Vitaly Egorov <[email protected]>
9
 * @copyright 2014 SamsonOS
10
 */
11
class Scheme
12
{
13
    /** Global/Default scheme marker */
14
    const BASE = 'global';
15
16
    /** Entity configuration file pattern */
17
    const ENTITY_PATTERN = '*Config.php';
18
19
    /** @var array Collection of file path -> class loaded */
20
    protected static $classes = array();
21
22
    /** @var string Current configuration environment */
23
    protected $environment;
24
25
    /** @var array Configuration folder path array */
26
    protected $path = array();
27
28
    /** @var array Collection of module identifier => configurator class */
29
    public $entities = array();
30
31
    /**
32
     * Create configuration instance.
33
     *
34
     * All module configurators must be stored within configuration base path,
35
     * by default this is stored in __SAMSON_CONFIG_PATH constant.
36
     *
37
     * Every environment configuration must be stored in sub-folder with the name of this
38
     * environment within base configuration folder.
39
     *
40
     * Configurators located at base root configuration folder considered as generic
41
     * module configurators.
42
     *
43
     * @param string $path    Base path to configuration root folder
44
     * @param string $environment Configuration environment name
45
     */
46
    public function __construct($path, $environment)
47
    {
48
        // Store current configuration environment
49
        $this->environment = $environment;
50
51
        // Check scheme folder existence
52
        if (file_exists($path)) {
53
            // Load scheme entities
54
            $this->load($path);
55
        }
56
    }
57
58
    /**
59
     * Load entity configuration classes for this scheme.
60
     * Function scans all required classes and matches them by
61
     * specified scheme path.
62
     */
63
    public function load($path = null)
64
    {
65
        // Build path to environment configuration folder
66
        $this->path[] = $path;
67
68
        // Iterate all loaded classes matching class name pattern
69
        foreach (preg_grep(Entity::CLASS_PATTERN, get_declared_classes()) as $class) {
70
            // If this is a entity configuration class ancestor
71
            if (in_array(__NAMESPACE__.'\Entity', class_parents($class))) {
72
                // Get class reflection object
73
                $reflector = new \ReflectionClass($class);
74
75
                // If path to class file is in scheme paths collection
76
                if (in_array(dirname($reflector->getFileName()), $this->path)) {
77
                    // Store module identifier - entity configuration object
78
                    $this->entities[$this->identifier($class)] = new $class();
79
                }
80
            }
81
        }
82
    }
83
84
    /**
85
     * Convert entity configuration or object class name to identifier
86
     * @param string $class Entity configuration class name
87
     * @return string Entity real class name
88
     */
89
    public function identifier($class)
90
    {
91
        // If namespace is present
92
        if (($classNamePos = strrpos($class, '\\')) !== false) {
93
            $class = substr($class, $classNamePos+1);
94
        }
95
96
        // Remove only last occurrence of pattern
97
        return preg_replace(Entity::CLASS_PATTERN, '', strtolower($class));
98
    }
99
100
    /**
101
     * Retrieve entity configuration by identifier.
102
     * If entity configuration not found null will be
103
     * returned.
104
     *
105
     * @param string $identifier Entity identifier
106
     * @param mixed $entity Return found entity configuration pointer
107
     * @return Entity|boolean Entity configuration pointer or bool
108
     */
109
    public function & entity($identifier, & $entity = null)
110
    {
111
        // Convert identifier of entity configuration name is passed
112
        $pointer = & $this->entities[$this->identifier($identifier)];
113
114
        // PHP bugs =) We cannot assign referenced value pointer to array element
115
        $entity = $pointer;
116
117
        // Prepare return value - pointer or bool
118
        $return = (func_num_args() == 2) ? isset($pointer) : $pointer;
119
120
        // Also PHP bugs - we cannot return reference from ternary operator
121
        return $return;
122
    }
123
124
    /**
125
     * Perform object configuration with specific entity
126
     * @param mixed $object Object instance pointer
127
     * @param Entity $entity Entity configuration pointer
128
     * @param mixed $params Collection of parameters
129
     * @return bool True if everything went fine, otherwise false
130
     */
131
    protected function handleConfigure(& $object, Entity & $entity, $params = null)
132
    {
133
        // If this class knows how to configure it self
134
        if (method_exists($object, 'configure')) {
135
            // Call custom configuration implementation
136
            return $object->configure($entity);
137
        } else { // Generic logic - implement entity configuration to object
138
            return $entity->configure($object, $params);
139
        }
140
    }
141
142
    /**
143
     * Configure object with configuration entity parameters.
144
     *
145
     * If now $identifier is passed - automatic identifier generation
146
     * will take place from object class name.
147
     *
148
     * If additional parameters key=>value collection is passed, they
149
     * will be used to configure object instead of entity configuration
150
     * class.
151
     *
152
     * @param mixed $object Object for configuration with entity
153
     * @param string $identifier Configuration entity name
154
     * @param array|null $params Collection of configuration parameters
155
     *
156
     * @return boolean True if we have successfully configured object
157
     */
158
    public function configure(& $object, $identifier = null, $params = null)
159
    {
160
        /** @var Entity $pointer Pointer to entity instance */
161
        $pointer = null;
162
163
        // If we have found this entity configuration, If no entity identifier is passed get it from object class
164
        if ($this->entity(isset($identifier) ? $identifier : get_class($object), $pointer)) {
165
            return $this->handleConfigure($object, $pointer, $params);
166
        } else { // Signal error
167
            Event::fire(
168
                'error',
169
                array(
170
                    $this,
171
                    'Cannot configure entity[' . $identifier . '] - Entity configuration does not exists'
172
                )
173
            );
174
175
            // We have failed
176
            return false;
177
        }
178
    }
179
}
180