Passed
Push — master ( e013f9...e142c0 )
by Anton
01:40 queued 11s
created

Update::registerAppendix()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 2
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * Cycle DataMapper ORM
4
 *
5
 * @license   MIT
6
 * @author    Anton Titov (Wolfy-J)
7
 */
8
declare(strict_types=1);
9
10
namespace Cycle\ORM\Command\Database;
11
12
use Cycle\ORM\Command\ContextCarrierInterface;
13
use Cycle\ORM\Command\DatabaseCommand;
14
use Cycle\ORM\Command\ScopeCarrierInterface;
15
use Cycle\ORM\Command\Traits\ContextTrait;
16
use Cycle\ORM\Command\Traits\ErrorTrait;
17
use Cycle\ORM\Command\Traits\ScopeTrait;
18
use Cycle\ORM\Exception\CommandException;
19
use Spiral\Database\DatabaseInterface;
20
21
/**
22
 * Update data CAN be modified by parent commands using context.
23
 *
24
 * This is conditional command, it would not be executed when no fields are given!
25
 */
26
final class Update extends DatabaseCommand implements ContextCarrierInterface, ScopeCarrierInterface
27
{
28
    use ContextTrait, ScopeTrait, ErrorTrait;
29
30
    /** @var array */
31
    protected $data = [];
32
33
    /** @var array */
34
    protected $appendix = [];
35
36
    /**
37
     * @param DatabaseInterface $db
38
     * @param string            $table
39
     * @param array             $data
40
     * @param array             $where
41
     */
42
    public function __construct(DatabaseInterface $db, string $table, array $data = [], array $where = [])
43
    {
44
        parent::__construct($db, $table);
45
        $this->data = $data;
46
        $this->scope = $where;
47
    }
48
49
    /**
50
     * Avoid opening transaction when no changes are expected.
51
     *
52
     * @return null|DatabaseInterface
53
     */
54
    public function getDatabase(): ?DatabaseInterface
55
    {
56
        if ($this->isEmpty()) {
57
            return null;
58
        }
59
60
        return parent::getDatabase();
61
    }
62
63
    /**
64
     * @inheritdoc
65
     */
66
    public function isReady(): bool
67
    {
68
        return empty($this->waitContext) && empty($this->waitScope);
69
    }
70
71
    /**
72
     * Update values, context not included.
73
     *
74
     * @return array
75
     */
76
    public function getData(): array
77
    {
78
        return array_merge($this->data, $this->context, $this->appendix);
79
    }
80
81
    /**
82
     * Update data in associated table.
83
     */
84
    public function execute()
85
    {
86
        if (empty($this->scope)) {
87
            throw new CommandException("Unable to execute update command without a scope");
88
        }
89
90
        if (!$this->isEmpty()) {
91
            $this->db->update($this->table, $this->getData(), $this->scope)->run();
0 ignored issues
show
Bug introduced by
It seems like $this->table can also be of type null; however, parameter $table of Spiral\Database\DatabaseInterface::update() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

91
            $this->db->update(/** @scrutinizer ignore-type */ $this->table, $this->getData(), $this->scope)->run();
Loading history...
92
        }
93
94
        parent::execute();
95
    }
96
97
    /**
98
     * {@inheritdoc}
99
     */
100
    public function isEmpty(): bool
101
    {
102
        return (empty($this->data) && empty($this->context)) || empty($this->scope);
103
    }
104
105
    /**
106
     * @inheritdoc
107
     */
108
    public function register(string $key, $value, bool $fresh = false, int $stream = self::DATA)
109
    {
110
        if ($stream == self::SCOPE) {
111
            if (empty($value)) {
112
                return;
113
            }
114
115
            $this->freeScope($key);
116
            $this->setScope($key, $value);
117
118
            return;
119
        }
120
121
        if ($fresh || !is_null($value)) {
122
            $this->freeContext($key);
123
        }
124
125
        if ($fresh) {
126
            // we only accept context when context has changed to avoid un-necessary
127
            // update commands
128
            $this->setContext($key, $value);
129
        }
130
    }
131
132
    /**
133
     * Register optional value to store in database. Having this value would not cause command to be executed
134
     * if data or context is empty.
135
     *
136
     * Example: $update->registerAppendix("updated_at", new DateTime());
137
     *
138
     * @param string $key
139
     * @param mixed  $value
140
     */
141
    public function registerAppendix(string $key, $value)
142
    {
143
        $this->appendix[$key] = $value;
144
    }
145
}