Completed
Pull Request — master (#1753)
by
unknown
07:27
created

ActionSplitter::split()   B

Complexity

Conditions 8
Paths 5

Size

Total Lines 42

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 42
rs 8.0035
c 0
b 0
f 0
cc 8
nc 5
nop 1
1
<?php
2
3
/**
4
 * MIT License
5
 * For full license information, please view the LICENSE file that was distributed with this source code.
6
 */
7
8
namespace Phinx\Db\Plan\Solver;
9
10
use Phinx\Db\Plan\AlterTable;
11
12
/**
13
 * A Plan takes an Intent and transforms it into a sequence of
14
 * instructions that can be correctly executed by an AdapterInterface.
15
 *
16
 * The main focus of Plan is to arrange the actions in the most efficient
17
 * way possible for the database.
18
 */
19
class ActionSplitter
20
{
21
    /**
22
     * The fully qualified class name of the Action class to match for conflicts
23
     *
24
     * @var string
25
     */
26
    protected $conflictClass;
27
28
    /**
29
     * The fully qualified class name of the Action class to match for conflicts, which
30
     * is the dual of $conflictClass. For example `AddColumn` and `DropColumn` are duals.
31
     *
32
     * @var string
33
     */
34
    protected $conflictClassDual;
35
36
    /**
37
     * A callback used to signal the actual presence of a conflict, that will be used to
38
     * partition the AlterTable into non-conflicting parts.
39
     *
40
     * The callback receives as first argument amn instance of $conflictClass and as second
41
     * argument an instance of $conflictClassDual
42
     *
43
     * @var callable
44
     */
45
    protected $conflictFilter;
46
47
    /**
48
     * Comstructor
49
     *
50
     * @param string $conflictClass The fully qualified class name of the Action class to match for conflicts
51
     * @param string $conflictClassDual The fully qualified class name of the Action class to match for conflicts,
52
     * which is the dual of $conflictClass. For example `AddColumn` and `DropColumn` are duals.
53
     * @param callable $conflictFilter The collection of actions to inspect
54
     */
55
    public function __construct($conflictClass, $conflictClassDual, callable $conflictFilter)
56
    {
57
        $this->conflictClass = $conflictClass;
58
        $this->conflictClassDual = $conflictClassDual;
59
        $this->conflictFilter = $conflictFilter;
60
    }
61
62
    /**
63
     * Returs a sequence of AlterTable instructions that are non conflicting
64
     * based on the constructor parameters.
65
     *
66
     * @param \Phinx\Db\Plan\AlterTable $alter The collection of actions to inspect
67
     *
68
     * @return \Phinx\Db\Plan\AlterTable[] A list of AlterTable that can be executed without
69
     * this type of conflict
70
     */
71
    public function split(AlterTable $alter)
72
    {
73
        $conflictActions = array_filter($alter->getActions(), function ($action) {
74
            return $action instanceof $this->conflictClass;
75
        });
76
77
        $originalAlter = new AlterTable($alter->getTable());
78
        $newAlter = new AlterTable($alter->getTable());
79
80
        $actions = array_map(function ($action) use ($conflictActions) {
81
            if (!$action instanceof $this->conflictClassDual) {
82
                return [$action, null];
83
            }
84
85
            $found = false;
86
            $matches = $this->conflictFilter;
87
            foreach ($conflictActions as $ca) {
88
                if ($matches($ca, $action)) {
89
                    $found = true;
90
                    break;
91
                }
92
            }
93
94
            if ($found) {
95
                return [null, $action];
96
            }
97
98
            return [$action, null];
99
        }, $alter->getActions());
100
101
        foreach ($actions as $pair) {
102
            [$original, $new] = $pair;
0 ignored issues
show
Bug introduced by
The variable $original does not exist. Did you mean $originalAlter?

This check looks for variables that are accessed but have not been defined. It raises an issue if it finds another variable that has a similar name.

The variable may have been renamed without also renaming all references.

Loading history...
Bug introduced by
The variable $new does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
103
            if ($original) {
0 ignored issues
show
Bug introduced by
The variable $original does not exist. Did you mean $originalAlter?

This check looks for variables that are accessed but have not been defined. It raises an issue if it finds another variable that has a similar name.

The variable may have been renamed without also renaming all references.

Loading history...
104
                $originalAlter->addAction($original);
0 ignored issues
show
Bug introduced by
The variable $original does not exist. Did you mean $originalAlter?

This check looks for variables that are accessed but have not been defined. It raises an issue if it finds another variable that has a similar name.

The variable may have been renamed without also renaming all references.

Loading history...
105
            }
106
            if ($new) {
107
                $newAlter->addAction($new);
108
            }
109
        }
110
111
        return [$originalAlter, $newAlter];
112
    }
113
}
114