Completed
Push — master ( dde077...2d5a04 )
by Gaetano
09:15
created

MigrationExecutor::matchConditions()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 5
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 1
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
        if (!isset($dsl['type']) || !isset($dsl['match'])) {
112
            throw new \Exception("A 'type' and a 'match' are required to load entities when suspending a migration");
113
        }
114
115
        $dsl['mode'] = 'load';
116
        // be kind to users and allow them not to specify this explicitly
117
        if (isset($dsl['references'])) {
118
            foreach($dsl['references'] as &$refDef) {
0 ignored issues
show
Bug introduced by
The expression $dsl['references'] of type string is not traversable.
Loading history...
119
                $refDef['overwrite'] = true;
120
            }
121
        }
122
        $step = new MigrationStep($dsl['type'], $dsl, $context);
123
124
        switch($dsl['type']) {
125
            case 'content':
126
                return $this->contentManager->execute($step);
127
            case 'location':
128
                return $this->locationManager->execute($step);
129
            case 'content_type':
130
                return $this->contentTypeManager->execute($step);
131
        }
132
    }
133
134
    protected function matchConditions($conditions)
135
    {
136
        $match = $this->referenceMatcher->match($conditions);
137
        return reset($match);
138
    }
139
140
    protected function matchSuspend($conditions)
141
    {
142
        foreach ($conditions as $key => $values) {
143
144
            switch ($key) {
145
                case 'date':
146
                    return time() >= $this->referenceResolver->resolveReference($values);
147
148
                case 'match':
149
                    return $this->matchConditions($values);
150
151
                default:
152
                    throw new \Exception("Unknown until condition: '$key' when suspending a migration ".var_export($conditions, true));
153
            }
154
        }
155
    }
156
}
157