Completed
Push — master ( b77c5c...4fbeac )
by Jeroen
10s
created

StrategyNode::prepareChildren()   B

Complexity

Conditions 6
Paths 9

Size

Total Lines 36
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 6.3357

Importance

Changes 1
Bugs 1 Features 0
Metric Value
dl 0
loc 36
ccs 15
cts 19
cp 0.7895
rs 8.439
c 1
b 1
f 0
cc 6
eloc 19
nc 9
nop 1
crap 6.3357
1
<?php
2
3
/*
4
 * This file is part of the Conveyor package.
5
 *
6
 * (c) Jeroen Fiege <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Webcreate\Conveyor\Config\Definition;
13
14
use Symfony\Component\Config\Definition\ArrayNode;
15
use Symfony\Component\Config\Definition\ConfigurationInterface;
16
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
17
use Symfony\Component\Config\Definition\Exception\InvalidTypeException;
18
use Symfony\Component\Config\Definition\NodeInterface;
19
use Webcreate\Conveyor\Factory\StrategyFactory;
20
21
class StrategyNode extends ArrayNode
22
{
23
    protected $prepared = false;
24
    protected $originalChildren = array();
25
26
    /**
27
     * @var StrategyFactory
28
     */
29
    protected $strategyFactory;
30
31
    /**
32
     * Constructor.
33
     *
34
     * @param string        $name
35
     * @param NodeInterface $parent
36
     */
37 2
    public function __construct($name, NodeInterface $parent = null)
38
    {
39 2
        parent::__construct($name, $parent);
40 2
    }
41
42
    /**
43
     * Set transporter factory
44
     *
45
     * @param StrategyFactory|null $factory
46
     */
47 2
    public function setStrategyFactory($factory)
48
    {
49 2
        $this->strategyFactory = $factory;
50 2
    }
51
52
    /**
53
     * Takes child nodes from a ConfigurtionInterface instance
54
     * and adds these to this node
55
     *
56
     * @param  string                        $type
57
     * @throws InvalidConfigurationException
58
     */
59 2
    protected function prepareChildren($type)
60
    {
61 2
        if (null === $this->strategyFactory) {
62 1
            return;
63
        }
64
65
        // when we hit this function for the first time,
66
        // we store the original children. Each time we
67
        // hit this function we reset the children to the
68
        // original ones.
69 1
        if (false === $this->prepared) {
70 1
            $this->originalChildren = $this->children;
71 1
            $this->prepared = true;
72
        }
73
74 1
        $strategies = $this->strategyFactory->getStrategies();
75
76 1
        $this->children = $this->originalChildren;
77
78 1
        if (isset($strategies[$type])) {
79 1
            $configuration = $this->strategyFactory->configuration($type);
80
81 1
            if ($configuration instanceof ConfigurationInterface) {
82 1
                $tree = $configuration->getConfigTreeBuilder()->buildTree();
83 1
                foreach ($tree->getChildren() as $child) {
84 1
                    $this->addChild($child);
85
                }
86
            }
87
        } else {
88
            throw new InvalidConfigurationException(sprintf(
89
                    'Strategy type "%s" does not exist at path "%s". Did you mean any of %s?', $type,
90
                    $this->getPath(),
91
                    implode(', ', array_keys($strategies))
92
            ));
93
        }
94 1
    }
95
96
    /**
97
     * We hook into the validateType method, this
98
     * gets called form the normalize method.
99
     *
100
     * @param mixed $value
101
     *
102
     * @throws InvalidTypeException
103
     */
104
    protected function validateType($value)
105
    {
106
        if (isset($value['type'])) {
107
            $this->prepareChildren($value['type']);
108
        } else {
109
            // ignore extra keys so the error message will be
110
            // focused on the missing type field
111
            $this->setIgnoreExtraKeys(true);
112
        }
113
114
        parent::validateType($value);
115
    }
116
117 2
    public function getDefaultValue()
118
    {
119 2
        if ($this->children['type']->getDefaultValue()) {
120 2
            $this->prepareChildren($this->children['type']->getDefaultValue());
121
        }
122
123 2
        return parent::getDefaultValue();
124
    }
125
}
126