Completed
Push — develop ( 346ce9...ffa440 )
by
unknown
31:53 queued 20:25
created

OptionsAbstractFactory::getOptionsConfig()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 12
rs 9.4286
cc 3
eloc 6
nc 3
nop 2
1
<?php
2
/**
3
 * YAWIK
4
 *
5
 * @filesource
6
 * @license MIT
7
 * @copyright  2013 - 2015 Cross Solution <http://cross-solution.de>
8
 */
9
  
10
/** */
11
namespace Core\Factory;
12
13
use Zend\ServiceManager\AbstractFactoryInterface;
14
use Zend\ServiceManager\ServiceLocatorInterface;
15
16
/**
17
 * ${CARET}
18
 * 
19
 * @author Mathias Gelhausen <[email protected]>
20
 * @todo write test 
21
 */
22
class OptionsAbstractFactory implements AbstractFactoryInterface
23
{
24
25
    const MODE_SIMPLE = 'simple';
26
    const MODE_NESTED = 'nested';
27
28
    protected $optionsConfig;
29
30
    /**
31
     * Determine if we can create a service with name
32
     *
33
     * @param ServiceLocatorInterface $serviceLocator
34
     * @param                         $name
35
     * @param                         $requestedName
36
     *
37
     * @return bool
38
     */
39
    public function canCreateServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName)
40
    {
41
        // Load options config specifications the first time this method is called.
42
        if (null === $this->optionsConfig) {
43
            $mainConfig = $serviceLocator->get('config');
44
            $this->optionsConfig = isset($mainConfig['options']) ? $mainConfig['options'] : [];
45
        }
46
47
        return false !== $this->getOptionsConfig($requestedName, $name);
48
    }
49
50
    /**
51
     * Create service with name
52
     *
53
     * @param ServiceLocatorInterface $serviceLocator
54
     * @param                         $name
55
     * @param                         $requestedName
56
     *
57
     * @return mixed
58
     * @throws \InvalidArgumentException
59
     */
60
    public function createServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName)
61
    {
62
        $config = $this->getOptionsConfig($requestedName, $name);
63
64
        if (!isset($config['class'])) {
65
            throw new \InvalidArgumentException(sprintf(
66
                'Missing index "class" from the config array for options "%s"',
67
                $requestedName
68
            ));
69
        }
70
71
        $className = $config['class'];
72
        $mode      = isset($config['mode']) ? $config['mode'] : self::MODE_SIMPLE;
73
        $options   = isset($config['options']) ? $config['options'] : [];
74
75
        if (self::MODE_SIMPLE == $mode) {
76
            return new $className($options);
77
        }
78
79
        if (self::MODE_NESTED == $mode) {
80
            return $this->createNestedOptions($className, $options);
81
82
        }
83
84
        throw new \InvalidArgumentException(sprintf('Unknown mode "%s".', $mode));
85
    }
86
87
88
    protected function createNestedOptions($className, $options)
89
    {
90
        $class = new $className();
91
92
        foreach ($options as $key => $spec) {
93
            if (is_array($spec) && array_key_exists('__class__', $spec)) {
94
                $nestedClassName = $spec['__class__'];
95
                unset($spec['__class__']);
96
                $spec = $this->createNestedOptions($nestedClassName, $spec);
97
            }
98
99
            $class->{$key} = $spec;
100
        }
101
102
        return $class;
103
    }
104
105
    protected function getOptionsConfig($fullName, $normalizedName)
106
    {
107
        if (array_key_exists($fullName, $this->optionsConfig)) {
108
            return $this->optionsConfig[$fullName];
109
        }
110
111
        if (array_key_exists($normalizedName, $this->optionsConfig)) {
112
            return $this->optionsConfig[$normalizedName];
113
        }
114
115
        return false;
116
    }
117
}