Completed
Branch feature/pre-split (67216b)
by Anton
03:28
created

ColumnOperation::declareColumn()   B

Complexity

Conditions 5
Paths 3

Size

Total Lines 31
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 19
nc 3
nop 1
dl 0
loc 31
rs 8.439
c 0
b 0
f 0
1
<?php
2
/**
3
 * Spiral Framework.
4
 *
5
 * @license   MIT
6
 * @author    Anton Titov (Wolfy-J)
7
 */
8
namespace Spiral\Migrations\Operations;
9
10
use Spiral\Database\Schemas\Prototypes\AbstractColumn;
11
use Spiral\Database\Schemas\Prototypes\AbstractTable;
12
use Spiral\Migrations\Exceptions\Operations\ColumnException;
13
use Spiral\Migrations\Operations\Traits\OptionsTrait;
14
15
/**
16
 * Generic column related operation.
17
 */
18
abstract class ColumnOperation extends TableOperation
19
{
20
    use OptionsTrait;
21
22
    /**
23
     * Some options has set of aliases.
24
     *
25
     * @var array
26
     */
27
    private $aliases = [
28
        'size'     => ['length', 'limit'],
29
        'default'  => ['defaultValue'],
30
        'nullable' => ['null']
31
    ];
32
33
    /**
34
     * @var string
35
     */
36
    protected $name = '';
37
38
    /**
39
     * @var string
40
     */
41
    protected $type = '';
42
43
    /**
44
     * @param string|null $database
45
     * @param string      $table
46
     * @param string      $column
47
     * @param string      $type
48
     * @param array       $options
49
     */
50
    public function __construct(
51
        $database,
52
        string $table,
53
        string $column,
54
        string $type = 'string',
55
        array $options = []
56
    ) {
57
        parent::__construct($database, $table);
58
59
        $this->name = $column;
60
        $this->type = $type;
61
        $this->options = $options;
62
    }
63
64
    /**
65
     * @param AbstractTable $schema
66
     *
67
     * @return AbstractColumn
68
     * @throws ColumnException
69
     */
70
    protected function declareColumn(AbstractTable $schema): AbstractColumn
71
    {
72
        $column = $schema->column($this->name);
73
74
        //Type configuring
75
        if (method_exists($column, $this->type)) {
76
            $arguments = [];
77
78
            $method = new \ReflectionMethod($column, $this->type);
79
            foreach ($method->getParameters() as $parameter) {
80
                if ($this->hasOption($parameter->getName())) {
81
                    $arguments[] = $this->getOption($parameter->getName());
82
                } elseif (!$parameter->isOptional()) {
83
                    throw new ColumnException(
84
                        "Option '{$parameter->getName()}' are required to define column with type '{$this->type}'"
85
                    );
86
                } else {
87
                    $arguments[] = $parameter->getDefaultValue();
88
                }
89
            }
90
91
            call_user_func_array([$column, $this->type], $arguments);
92
        } else {
93
            $column->setType($this->type);
94
        }
95
96
        $column->nullable($this->getOption('nullable', false));
97
        $column->defaultValue($this->getOption('default', null));
98
99
        return $column;
100
    }
101
}