Passed
Push — master ( 03dfdf...d55943 )
by Gaetano
10:43
created

ReferenceExecutor::execute()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 17
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 3.1406

Importance

Changes 0
Metric Value
cc 3
eloc 8
c 0
b 0
f 0
nc 3
nop 1
dl 0
loc 17
ccs 6
cts 8
cp 0.75
crap 3.1406
rs 10
1
<?php
2
3
4
namespace Kaliop\eZMigrationBundle\Core\Executor;
5
6
use Kaliop\eZMigrationBundle\API\Exception\InvalidStepDefinitionException;
7
use Symfony\Component\DependencyInjection\ContainerInterface;
8
use Symfony\Component\Yaml\Yaml;
9
use Symfony\Component\VarDumper\VarDumper;
10
use Kaliop\eZMigrationBundle\API\Value\MigrationStep;
11
use Kaliop\eZMigrationBundle\API\ReferenceResolverBagInterface;
12
use Kaliop\eZMigrationBundle\API\EnumerableReferenceResolverInterface;
13
14
class ReferenceExecutor extends AbstractExecutor
15
{
16
    use IgnorableStepExecutorTrait;
0 ignored issues
show
Bug introduced by
The trait Kaliop\eZMigrationBundle...orableStepExecutorTrait requires the property $dsl which is not provided by Kaliop\eZMigrationBundle...cutor\ReferenceExecutor.
Loading history...
17
18
    protected $supportedStepTypes = array('reference');
19
    protected $supportedActions = array('set', 'load', 'save', 'dump');
20
21
    protected $container;
22
    /** @var ReferenceResolverBagInterface $referenceResolver */
23
    protected $referenceResolver;
24 96
25
    public function __construct(ContainerInterface $container, ReferenceResolverBagInterface $referenceResolver)
26 96
    {
27 96
        $this->container = $container;
28 96
        $this->referenceResolver = $referenceResolver;
29
    }
30
31
    /**
32
     * @param MigrationStep $step
33
     * @return mixed
34
     * @throws \Exception
35 18
     */
36
    public function execute(MigrationStep $step)
37 18
    {
38
        parent::execute($step);
39 18
40
        if (!isset($step->dsl['mode'])) {
41
            throw new InvalidStepDefinitionException("Invalid step definition: missing 'mode'");
42
        }
43 18
44
        $action = $step->dsl['mode'];
45 18
46
        if (!in_array($action, $this->supportedActions)) {
47
            throw new InvalidStepDefinitionException("Invalid step definition: value '$action' is not allowed for 'mode'");
48
        }
49 18
50
        $this->skipStepIfNeeded($step);
51 18
52
        return $this->$action($step->dsl, $step->context);
53
    }
54 18
55
    protected function set($dsl, $context)
56 18
    {
57
        if (!isset($dsl['identifier'])) {
58
            throw new InvalidStepDefinitionException("Invalid step definition: miss 'identifier' for setting reference");
59 18
        }
60
        if (!isset($dsl['value'])) {
61
            throw new InvalidStepDefinitionException("Invalid step definition: miss 'value' for setting reference");
62
        }
63 18
64
        // this makes sense since we started supporting embedded refs...
65 18
        $value = $this->referenceResolver->resolveReference($dsl['value']);
66
67 1
        if (0 === strpos($value, '%env(') && ')%' === substr($value, -2) && '%env()%' !== $value) {
68
            /// @todo find out how to use Sf components to resolve this value instead of doing it by ourselves...
69
            $env = substr($value, 5, -2);
70 18
            // we use getenv because $_ENV gets cleaned up (by whom?)
71 18
            $val = getenv($env);
72
            if ($val === false) {
73 18
                throw new \Exception("Env var $env seems not to be defined");
74
            }
75
            $value = $val;
76 1
        } else {
77
            /// @todo add support for eZ dynamic parameters too
78 1
79
            if (preg_match('/.*%.+%.*$/', $value)) {
80
                // we use the same parameter resolving rule as symfony, even though this means abusing the ContainerInterface
81 1
                $value = $this->container->getParameterBag()->resolveString($value);
0 ignored issues
show
Bug introduced by
The method getParameterBag() does not exist on Symfony\Component\Depend...tion\ContainerInterface. Did you maybe mean getParameter()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

81
                $value = $this->container->/** @scrutinizer ignore-call */ getParameterBag()->resolveString($value);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
82 1
            }
83
        }
84 1
85
        $overwrite = isset($dsl['overwrite']) ? $overwrite = $dsl['overwrite'] : false;
0 ignored issues
show
Unused Code introduced by
The assignment to $overwrite is dead and can be removed.
Loading history...
86 1
        $this->referenceResolver->addReference($dsl['identifier'], $value, $overwrite);
87 1
88
        return $value;
89
    }
90 1
91
    protected function load($dsl, $context)
92
    {
93 1
        if (!isset($dsl['file'])) {
94
            throw new InvalidStepDefinitionException("Invalid step definition: miss 'file' for loading references");
95 1
        }
96
        $fileName = $this->referenceResolver->resolveReference($dsl['file']);
97 1
        $fileName = str_replace('{ENV}', $this->container->get('kernel')->getEnvironment(), $fileName);
98
99
        $overwrite = isset($dsl['overwrite']) ? $overwrite = $dsl['overwrite'] : false;
0 ignored issues
show
Unused Code introduced by
The assignment to $overwrite is dead and can be removed.
Loading history...
100 1
101
        if (!is_file($fileName) && is_file(dirname($context['path']) . '/references/' . $fileName)) {
102 1
            $fileName = dirname($context['path']) . '/references/' . $fileName;
103 1
        }
104
105
        if (!is_file($fileName)) {
106
            throw new InvalidStepDefinitionException("Invalid step definition: invalid file '$fileName' for loading references");
107
        }
108 1
        $data = file_get_contents($fileName);
109
110
        $ext = pathinfo($fileName, PATHINFO_EXTENSION);
111
        switch ($ext) {
112 1
            case 'json':
113 1
                $data = json_decode($data, true);
114
                break;
115
            case 'yml':
116
            case 'yaml':
117 1
                $data = Yaml::parse($data);
118 1
                break;
119
            default:
120
                throw new InvalidStepDefinitionException("Invalid step definition: unsupported file extension '$ext' for loading references from");
121
        }
122 1
123
        if (!is_array($data)) {
124
            throw new \Exception("Invalid step definition: file does not contain an array of key/value pairs");
125
        }
126
127
        foreach ($data as $refName => $value) {
128 1
            if (preg_match('/%.+%$/', $value)) {
129
                $value = $this->container->getParameter(trim($value, '%'));
130 1
            }
131
132
            if (!$this->referenceResolver->addReference($refName, $value, $overwrite)) {
133 1
                throw new \Exception("Failed adding to Reference Resolver the reference: $refName");
134 1
            }
135
        }
136 1
137
        return $data;
138 1
    }
139
140
    /**
141
     * @todo find a smart way to allow saving the references file next to the current migration
142 1
     */
143
    protected function save($dsl, $context)
144
    {
145
        if (!isset($dsl['file'])) {
146 1
            throw new InvalidStepDefinitionException("Invalid step definition: miss 'file' for saving references");
147
        }
148 1
        $fileName = $this->referenceResolver->resolveReference($dsl['file']);
149
        $fileName = str_replace('{ENV}', $this->container->get('kernel')->getEnvironment(), $fileName);
150 1
151
        $overwrite = isset($dsl['overwrite']) ? $overwrite = $dsl['overwrite'] : false;
0 ignored issues
show
Unused Code introduced by
The assignment to $overwrite is dead and can be removed.
Loading history...
152
153 1
        if (is_file($fileName) && !$overwrite) {
154
            throw new \Exception("Invalid step definition: file '$fileName' for saving references already exists");
155 1
        }
156 1
157
        if (! $this->referenceResolver instanceof EnumerableReferenceResolverInterface) {
158
            throw new \Exception("Can not save references as resolver is not enumerable");
159
        }
160
161 1
        $data = $this->referenceResolver->listReferences();
162
163 1
        $ext = pathinfo($fileName, PATHINFO_EXTENSION);
164
        switch ($ext) {
165
            case 'json':
166 10
                $data = json_encode($data, JSON_PRETTY_PRINT);
167
                break;
168 10
            case 'yml':
169
            case 'yaml':
170
            /// @todo use Yaml::DUMP_EMPTY_ARRAY_AS_SEQUENCE option if it is supported
171 10
                $data = Yaml::dump($data);
172
                break;
173
            default:
174 10
                throw new InvalidStepDefinitionException("Invalid step definition: unsupported file extension '$ext' for saving references to");
175 1
        }
176
177 10
        file_put_contents($fileName, $data);
178
179 10
        return $data;
180 10
    }
181
182 10
    protected function dump($dsl, $context)
183
    {
184
        if (!isset($dsl['identifier'])) {
185
            throw new InvalidStepDefinitionException("Invalid step definition: miss 'identifier' for dumping reference");
186
        }
187
        if (!$this->referenceResolver->isReference($dsl['identifier'])) {
188
            throw new \Exception("Invalid step definition: identifier '{$dsl['identifier']}' is not a reference");
189
        }
190
        /// @todo if $context['output'] is set, use that for writing output instead of doing it directly
191
        if (isset($dsl['label'])) {
192
            echo $dsl['label'];
193
        } else {
194
            VarDumper::dump($dsl['identifier']);
195
        }
196
        $value = $this->referenceResolver->resolveReference($dsl['identifier']);
197
        VarDumper::dump($value);
198
199
        return $value;
200
    }
201
}
202