Completed
Push — master ( 5a501b...3982a6 )
by Gaetano
08:04
created

MigrationExecutor::loadEntity()   B

Complexity

Conditions 8
Paths 9

Size

Total Lines 24

Duplication

Lines 3
Ratio 12.5 %

Code Coverage

Tests 0
CRAP Score 72

Importance

Changes 0
Metric Value
dl 3
loc 24
ccs 0
cts 21
cp 0
rs 8.4444
c 0
b 0
f 0
cc 8
nc 9
nop 2
crap 72
1
<?php
2
3
namespace Kaliop\eZMigrationBundle\Core\Executor;
4
5
use Kaliop\eZMigrationBundle\API\Value\MigrationStep;
6
use Kaliop\eZMigrationBundle\API\ExecutorInterface;
7
use Kaliop\eZMigrationBundle\API\Exception\MigrationAbortedException;
8
use Kaliop\eZMigrationBundle\API\Exception\MigrationSuspendedException;
9
use Kaliop\eZMigrationBundle\API\ReferenceResolverInterface;
10
11
class MigrationExecutor extends AbstractExecutor
12
{
13
    protected $supportedStepTypes = array('migration');
14
    protected $supportedActions = array('cancel', 'suspend', 'sleep');
15
16
    protected $referenceMatcher;
17
    protected $referenceResolver;
18
    protected $contentManager;
19
    protected $locationManager;
20
    protected $contentTypeManager;
21
22
    public function __construct($referenceMatcher, ReferenceResolverInterface $referenceResolver, ExecutorInterface $contentManager, ExecutorInterface $locationManager, ExecutorInterface $contentTypeManager)
23
    {
24
        $this->referenceMatcher = $referenceMatcher;
25
        $this->referenceResolver = $referenceResolver;
26
        $this->contentManager = $contentManager;
27
        $this->locationManager = $locationManager;
28
        $this->contentTypeManager = $contentTypeManager;
29
    }
30
31
    /**
32
     * @param MigrationStep $step
33
     * @return mixed
34
     * @throws \Exception
35
     */
36 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...
37
    {
38
        parent::execute($step);
39
40
        if (!isset($step->dsl['mode'])) {
41
            throw new \Exception("Invalid step definition: missing 'mode'");
42
        }
43
44
        $action = $step->dsl['mode'];
45
46
        if (!in_array($action, $this->supportedActions)) {
47
            throw new \Exception("Invalid step definition: value '$action' is not allowed for 'mode'");
48
        }
49
50
        return $this->$action($step->dsl, $step->context);
51
    }
52
53
    /**
54
     * @param array $dsl
55
     * @param array $context
56
     * @return true
57
     * @throws \Exception
58
     */
59
    protected function cancel($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...
60
    {
61
        $message = isset($dsl['message']) ? $dsl['message'] : '';
62
63
        if (isset($dsl['if'])) {
64
            if (!$this->matchConditions($dsl['if'])) {
65
                // q: return timestamp, matched condition or ... ?
66
                return true;
67
            }
68
        }
69
70
        throw new MigrationAbortedException($message);
71
    }
72
73
    /**
74
     * @param array $dsl
75
     * @param array $context
76
     * @return true
77
     * @throws \Exception
78
     */
79
    protected function suspend($dsl, $context)
80
    {
81
        $message = isset($dsl['message']) ? $dsl['message'] : '';
82
83
        if (!isset($dsl['until'])) {
84
            throw new \Exception("An until condition is required to suspend a migration");
85
        }
86
87
        if (isset($dsl['load'])) {
88
            $this->loadEntity($dsl['load'], $context);
89
        }
90
91
        if ($this->matchSuspend($dsl['until'])) {
92
            // the time has come to resume!
93
            // q: return timestamp, matched condition or ... ?
94
            return true;
95
        }
96
97
        throw new MigrationSuspendedException($message);
98
    }
99
100
    protected function sleep($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...
101
    {
102
        if (!isset($dsl['seconds'])) {
103
            throw new \Exception("A 'seconds' element is required when putting a migration to sleep");
104
        }
105
106
        sleep($dsl['seconds']);
107
        return true;
108
    }
109
110
    protected function loadEntity($dsl, $context)
111
    {
112 View Code Duplication
        if (!isset($dsl['type']) || !isset($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...
113
            throw new \Exception("A 'type' and a 'match' are required to load entities when suspending a migration");
114
        }
115
116
        $dsl['mode'] = 'load';
117
        // be kind to users and allow them not to specify this explicitly
118
        if (isset($dsl['references'])) {
119
            foreach($dsl['references'] as &$refDef) {
0 ignored issues
show
Bug introduced by
The expression $dsl['references'] of type string is not traversable.
Loading history...
120
                $refDef['overwrite'] = true;
121
            }
122
        }
123
        $step = new MigrationStep($dsl['type'], $dsl, $context);
124
125
        switch($dsl['type']) {
126
            case 'content':
127
                return $this->contentManager->execute($step);
128
            case 'location':
129
                return $this->locationManager->execute($step);
130
            case 'content_type':
131
                return $this->contentTypeManager->execute($step);
132
        }
133
    }
134
135
    protected function matchConditions($conditions)
136
    {
137
        $match = $this->referenceMatcher->match($conditions);
138
        return reset($match);
139
    }
140
141
    protected function matchSuspend($conditions)
142
    {
143
        foreach ($conditions as $key => $values) {
144
145
            switch ($key) {
146
                case 'date':
147
                    return time() >= $this->referenceResolver->resolveReference($values);
148
149
                case 'match':
150
                    return $this->matchConditions($values);
151
152
                default:
153
                    throw new \Exception("Unknown until condition: '$key' when suspending a migration ".var_export($conditions, true));
154
            }
155
        }
156
    }
157
}
158