AttachEntities   A
last analyzed

Complexity

Total Complexity 13

Size/Duplication

Total Lines 115
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 13
eloc 50
c 1
b 0
f 0
dl 0
loc 115
rs 10

5 Methods

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