Passed
Push — dev_2x ( fb9ebe...5f9618 )
by Adrian
02:22
created

AttachEntities::revert()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 0

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 0
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 2
rs 10
1
<?php
2
declare(strict_types=1);
3
4
namespace Sirius\Orm\Action;
5
6
use Sirius\Orm\Contract\ActionInterface;
7
use Sirius\Orm\Contract\EntityInterface;
8
use Sirius\Orm\Mapper;
9
use Sirius\Orm\Relation\ManyToMany;
10
use Sirius\Orm\Relation\Relation;
11
use Sirius\Orm\Relation\RelationConfig;
12
13
class AttachEntities implements ActionInterface
14
{
15
    /**
16
     * @var EntityInterface
17
     */
18
    protected $nativeEntity;
19
    /**
20
     * @var EntityInterface
21
     */
22
    protected $foreignEntity;
23
    /**
24
     * @var Relation
25
     */
26
    protected $relation;
27
    /**
28
     * @var string
29
     */
30
    protected $actionType;
31
    /**
32
     * @var Mapper
33
     */
34
    protected $nativeMapper;
35
    /**
36
     * @var Mapper
37
     */
38
    protected $foreignMapper;
39
40
    public function __construct(
41
        Mapper $nativeMapper,
42
        EntityInterface $nativeEntity,
43
        Mapper $foreignMapper,
44
        EntityInterface $foreignEntity,
45
        Relation $relation,
46
        string $actionType
47
    ) {
48
        $this->nativeMapper  = $nativeMapper;
49
        $this->nativeEntity  = $nativeEntity;
50
        $this->foreignMapper = $foreignMapper;
51
        $this->foreignEntity = $foreignEntity;
52
        $this->relation      = $relation;
53
        $this->actionType    = $actionType;
54
    }
55
56
    public function run()
57
    {
58
        /**
59
         * @todo store current attribute values
60
         */
61
        $this->relation->attachEntities($this->nativeEntity, $this->foreignEntity);
62
        $this->maybeUpdatePivotRow();
63
    }
64
65
    public function onSuccess()
66
    {
67
    }
68
69
    protected function maybeUpdatePivotRow()
70
    {
71
        if (! $this->relation instanceof ManyToMany) {
72
            return;
73
        }
74
75
        $conn         = $this->relation->getNativeMapper()->getWriteConnection();
76
        $throughTable = (string)$this->relation->getOption(RelationConfig::THROUGH_TABLE);
77
78
        $throughNativeColumns  = (array)$this->relation->getOption(RelationConfig::THROUGH_NATIVE_COLUMN);
79
        $throughForeignColumns = (array)$this->relation->getOption(RelationConfig::THROUGH_FOREIGN_COLUMN);
80
        $nativeKey             = (array)$this->getNativeEntityHydrator()->getPk($this->nativeEntity);
81
        $foreignKey            = (array)$this->getForeignEntityHydrator()->getPk($this->foreignEntity);
82
83
        // first delete existing pivot row
84
        $delete = new \Sirius\Sql\Delete($conn);
85
        $delete->from($throughTable);
86
        foreach ($throughNativeColumns as $k => $col) {
87
            $delete->where($col, $nativeKey[$k]);
88
            $delete->where($throughForeignColumns[$k], $foreignKey[$k]);
89
        }
90
        foreach ((array)$this->relation->getOption(RelationConfig::THROUGH_GUARDS) as $col => $value) {
91
            if (! is_int($col)) {
92
                $delete->where($col, $value);
93
            } else {
94
                $delete->where($value);
95
            }
96
        }
97
        $delete->perform();
98
99
        $insertColumns = [];
100
        foreach ($throughNativeColumns as $k => $col) {
101
            $insertColumns[$col]                       = $nativeKey[$k];
102
            $insertColumns[$throughForeignColumns[$k]] = $foreignKey[$k];
103
        }
104
105
        foreach ((array)$this->relation->getOption(RelationConfig::THROUGH_COLUMNS) as $col => $alias) {
106
            $insertColumns[$col] = $this->getForeignEntityHydrator()
107
                                        ->get($this->foreignEntity, $alias);
108
        }
109
110
        foreach ((array)$this->relation->getOption(RelationConfig::THROUGH_GUARDS) as $col => $value) {
111
            if (! is_int($col)) {
112
                $insertColumns[$col] = $value;
113
            }
114
        }
115
116
        $insert = new \Sirius\Sql\Insert($conn);
117
        $insert->into($throughTable)
118
               ->columns($insertColumns)
119
               ->perform();
120
    }
121
122
    protected function getNativeEntityHydrator()
123
    {
124
        return $this->nativeMapper->getHydrator();
125
    }
126
127
    protected function getForeignEntityHydrator()
128
    {
129
        return $this->foreignMapper->getHydrator();
130
    }
131
}
132