Completed
Push — master ( 5980e7...b2c38b )
by Gaetano
05:32
created

MigrationDefinitionExecutor::generate()   C

Complexity

Conditions 15
Paths 36

Size

Total Lines 63

Duplication

Lines 14
Ratio 22.22 %

Code Coverage

Tests 0
CRAP Score 240

Importance

Changes 0
Metric Value
dl 14
loc 63
ccs 0
cts 36
cp 0
rs 5.9166
c 0
b 0
f 0
cc 15
nc 36
nop 2
crap 240

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Kaliop\eZMigrationBundle\Core\Executor;
4
5
use Kaliop\eZMigrationBundle\API\Value\MigrationStep;
6
use Kaliop\eZMigrationBundle\API\MatcherInterface;
7
use Kaliop\eZMigrationBundle\API\ReferenceResolverBagInterface;
8
use Kaliop\eZMigrationBundle\API\MigrationGeneratorInterface;
9
use JmesPath\Env as JmesPath;
10
use Symfony\Component\Yaml\Yaml;
11
12
class MigrationDefinitionExecutor extends AbstractExecutor
13
{
14
    protected $supportedStepTypes = array('migration_definition');
15
    protected $supportedActions = array('generate');
16
17
    /** @var \Kaliop\eZMigrationBundle\Core\MigrationService $migrationService */
18
    protected $migrationService;
19
    /** @var ReferenceBagInterface $referenceResolver */
20
    protected $referenceResolver;
21 80
22
    public function __construct($migrationService, ReferenceResolverBagInterface $referenceResolver)
23 80
    {
24 80
        $this->migrationService = $migrationService;
25 80
        $this->referenceResolver = $referenceResolver;
0 ignored issues
show
Documentation Bug introduced by
It seems like $referenceResolver of type object<Kaliop\eZMigratio...ceResolverBagInterface> is incompatible with the declared type object<Kaliop\eZMigratio...\ReferenceBagInterface> of property $referenceResolver.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
26
    }
27
28
    /**
29
     * @param MigrationStep $step
30
     * @return mixed
31
     * @throws \Exception
32
     */
33 View Code Duplication
    public function execute(MigrationStep $step)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
34
    {
35
        parent::execute($step);
36
37
        if (!isset($step->dsl['mode'])) {
38
            throw new \Exception("Invalid step definition: missing 'mode'");
39
        }
40
41
        $action = $step->dsl['mode'];
42
43
        if (!in_array($action, $this->supportedActions)) {
44
            throw new \Exception("Invalid step definition: value '$action' is not allowed for 'mode'");
45
        }
46
47
        return $this->$action($step->dsl, $step->context);
48
    }
49
50
    /**
51
     * @todo allow to save to disk
52
     * @param array $dsl
53
     * @param array $context
54
     * @return array
55
     * @throws \Exception
56
     */
57
    protected function generate($dsl, $context)
0 ignored issues
show
Unused Code introduced by
The parameter $context is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
58
    {
59
        if (!isset($dsl['migration_type'])) {
60
            throw new \Exception("Invalid step definition: miss 'migration_type'");
61
        }
62
        $migrationType = $this->referenceResolver->resolveReference($dsl['migration_type']);
63
        if (!isset($dsl['migration_mode'])) {
64
            throw new \Exception("Invalid step definition: miss 'migration_mode'");
65
        }
66
        $migrationMode = $this->referenceResolver->resolveReference($dsl['migration_mode']);
67 View Code Duplication
        if (!isset($dsl['match']) || !is_array($dsl['match'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
68
            throw new \Exception("Invalid step definition: miss 'match' to determine what to generate migration definition for");
69
        }
70
        $match = $dsl['match'];
71
72
        $executors = $this->getGeneratingExecutors();
73
        if (!in_array($migrationType, $executors)) {
74
            throw new \Exception("It is not possible to generate a migration of type '$migrationType': executor not found or not a generator");
75
        }
76
        $executor = $this->migrationService->getExecutor($migrationType);
77
78
        $context = array();
79
        if (isset($dsl['lang']) && $dsl['lang'] != '') {
80
            $context['defaultLanguageCode'] = $this->referenceResolver->resolveReference($dsl['lang']);
81
        }
82
83
        $matchCondition = array($this->referenceResolver->resolveReference($match['type']) => $this->referenceResolver->resolveReference($match['value']));
84
        if (isset($match['except']) && $match['except']) {
85
            $matchCondition = array(MatcherInterface::MATCH_NOT => $matchCondition);
86
        }
87
88
        $result = $executor->generateMigration($matchCondition, $migrationMode, $context);
89
90
        if (isset($dsl['file'])) {
91
92
            $fileName = $this->referenceResolver->resolveReference($dsl['file']);
93
94
            $ext = pathinfo(basename($fileName), PATHINFO_EXTENSION);
95
96 View Code Duplication
            switch ($ext) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
97
                case 'yml':
98
                case 'yaml':
99
                    $code = Yaml::dump($result, 5);
100
                    break;
101
                case 'json':
102
                    $code = json_encode($result, JSON_PRETTY_PRINT);
103
                    break;
104
                default:
105
                    throw new \Exception("Can not save generated migration to a file of type '$ext'");
106
            }
107
108
            $dir = dirname($fileName);
109
            if (!is_dir($dir)) {
110
                mkdir($dir, 0777, true);
111
            }
112
113
            file_put_contents($fileName, $code);
114
        }
115
116
        $this->setReferences($result, $dsl);
117
118
        return $result;
119
    }
120
121
    protected function setReferences($result, $dsl)
122
    {
123
        if (!array_key_exists('references', $dsl)) {
124
            return false;
125
        }
126
127
        foreach ($dsl['references'] as $reference) {
128
            if (!isset($reference['json_path'])) {
129
                throw new \InvalidArgumentException('MigrationDefinition Executor does not support setting references if not using a json_path expression');
130
            }
131
132
            $overwrite = false;
133
            if (isset($reference['overwrite'])) {
134
                $overwrite = $reference['overwrite'];
135
            }
136
            $value = JmesPath::search($reference['json_path'], $result);
137
            $this->referenceResolver->addReference($reference['identifier'], $value, $overwrite);
138
        }
139
    }
140
141
    /**
142
     * @todo cache this for faster access
143
     * @return array
144
     */
145 View Code Duplication
    protected function getGeneratingExecutors()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
146
    {
147
        $migrationService = $this->migrationService;
148
        $executors = $migrationService->listExecutors();
149
        foreach($executors as $key => $name) {
150
            $executor = $migrationService->getExecutor($name);
151
            if (!$executor instanceof MigrationGeneratorInterface) {
152
                unset($executors[$key]);
153
            }
154
        }
155
        return $executors;
156
    }
157
}
158