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

MigrationExecutor::sleep()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

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