Completed
Push — master ( a7b476...58257b )
by Adrian
01:51
created

ManyToOne::joinSubselect()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 13
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 8
c 0
b 0
f 0
nc 1
nop 2
dl 0
loc 13
rs 10
1
<?php
2
3
namespace Sirius\Orm\Relation;
4
5
use Sirius\Orm\Action\BaseAction;
6
use Sirius\Orm\Collection\Collection;
7
use Sirius\Orm\Entity\EntityInterface;
8
use Sirius\Orm\Entity\StateEnum;
9
use Sirius\Orm\Query;
10
11
class ManyToOne extends Relation
12
{
13
    protected function applyDefaults(): void
14
    {
15
        parent::applyDefaults();
16
17
        $foreignKey = $this->foreignMapper->getPrimaryKey();
18
        if (! isset($this->options[RelationConfig::FOREIGN_KEY])) {
19
            $this->options[RelationConfig::FOREIGN_KEY] = $foreignKey;
20
        }
21
22
        if (! isset($this->options[RelationConfig::NATIVE_KEY])) {
23
            $nativeKey                                 = $this->getKeyColumn($this->name, $foreignKey);
24
            $this->options[RelationConfig::NATIVE_KEY] = $nativeKey;
25
        }
26
    }
27
28
    public function joinSubselect(Query $query, string $reference)
29
    {
30
        $tableRef = $this->foreignMapper->getTableAlias(true);
0 ignored issues
show
Unused Code introduced by
The assignment to $tableRef is dead and can be removed.
Loading history...
31
        $subselect = $query->subSelectForJoinWith()
32
                           ->from($this->foreignMapper->getTable())
33
                           ->columns($this->foreignMapper->getTable() . '.*')
34
                           ->as($reference);
35
36
        $subselect = $this->applyQueryCallback($subselect);
37
38
        $subselect = $this->applyForeignGuards($subselect);
39
40
        return $query->join('INNER', $subselect->getStatement(), $this->getJoinOnForSubselect());
41
    }
42
43
    public function attachMatchesToEntity(EntityInterface $nativeEntity, array $result)
44
    {
45
        $found = null;
46
        foreach ($result as $foreignEntity) {
47
            if ($this->entitiesBelongTogether($nativeEntity, $foreignEntity)) {
48
                $found = $foreignEntity;
49
                break;
50
            }
51
        }
52
53
        $this->attachEntities($nativeEntity, $found);
54
    }
55
56
    /**
57
     * @param EntityInterface $nativeEntity
58
     * @param EntityInterface $foreignEntity
59
     */
60
    public function attachEntities(EntityInterface $nativeEntity, EntityInterface $foreignEntity = null): void
61
    {
62
        // no point in linking entities if the native one is deleted
63
        if ($nativeEntity->getPersistenceState() == StateEnum::DELETED) {
64
            return;
65
        }
66
67
        $nativeKey  = (array)$this->getOption(RelationConfig::NATIVE_KEY);
68
        $foreignKey = (array)$this->getOption(RelationConfig::FOREIGN_KEY);
69
70
        foreach ($nativeKey as $k => $col) {
71
            $this->nativeMapper->setEntityAttribute(
72
                $nativeEntity,
73
                $col,
74
                $foreignEntity ? $this->foreignMapper->getEntityAttribute($foreignEntity, $foreignKey[$k]) : null
75
            );
76
        }
77
78
        $this->nativeMapper->setEntityAttribute($nativeEntity, $this->name, $foreignEntity);
79
    }
80
81
    public function detachEntities(EntityInterface $nativeEntity, EntityInterface $foreignEntity)
82
    {
83
        if ($nativeEntity->getPersistenceState() == StateEnum::DELETED) {
84
            return;
85
        }
86
87
        // required for DELETED entities that throw errors if they are changed
88
        $state = $foreignEntity->getPersistenceState();
0 ignored issues
show
Unused Code introduced by
The assignment to $state is dead and can be removed.
Loading history...
89
        $foreignEntity->setPersistenceState(StateEnum::SYNCHRONIZED);
90
91
        $nativeKey  = (array)$this->getOption(RelationConfig::NATIVE_KEY);
92
        $foreignKey = (array)$this->getOption(RelationConfig::FOREIGN_KEY);
0 ignored issues
show
Unused Code introduced by
The assignment to $foreignKey is dead and can be removed.
Loading history...
93
94
        foreach ($nativeKey as $k => $col) {
95
            $this->nativeMapper->setEntityAttribute(
96
                $nativeEntity,
97
                $col,
98
                null
99
            );
100
        }
101
102
        $this->nativeMapper->setEntityAttribute($nativeEntity, $this->name, null);
103
        $state = $foreignEntity->getPersistenceState();
104
    }
105
106
    protected function addActionOnDelete(BaseAction $action)
107
    {
108
        // no cascade delete? treat it as a save
109
        if (! $this->isCascade()) {
110
            $this->addActionOnSave($action);
111
        } else {
112
            $nativeEntity  = $action->getEntity();
113
            $foreignEntity = $nativeEntity->get($this->name);
0 ignored issues
show
Bug introduced by
The method get() does not exist on Sirius\Orm\Entity\EntityInterface. Did you maybe mean getPk()? ( Ignorable by Annotation )

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

113
            /** @scrutinizer ignore-call */ 
114
            $foreignEntity = $nativeEntity->get($this->name);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
114
115
            if ($foreignEntity) {
116
                $remainingRelations = $this->getRemainingRelations($action->getOption('relations'));
117
                $deleteAction       = $this->foreignMapper
118
                    ->newDeleteAction($foreignEntity, ['relations' => $remainingRelations]);
119
                $action->prepend($deleteAction);
120
                $action->prepend($this->newSyncAction($action->getEntity(), $foreignEntity, 'delete'));
121
            }
122
        }
123
    }
124
125
    protected function addActionOnSave(BaseAction $action)
126
    {
127
        if (!$this->relationWasChanged($action->getEntity())) {
128
            return;
129
        }
130
        $foreignEntity = $this->nativeMapper->getEntityAttribute($action->getEntity(), $this->name);
131
        if ($foreignEntity) {
132
            $remainingRelations = $this->getRemainingRelations($action->getOption('relations'));
133
            $saveAction         = $this->foreignMapper
134
                ->newSaveAction($foreignEntity, ['relations' => $remainingRelations]);
135
            $saveAction->addColumns($this->getExtraColumnsForAction());
0 ignored issues
show
Bug introduced by
The method addColumns() does not exist on Sirius\Orm\Action\BaseAction. It seems like you code against a sub-type of Sirius\Orm\Action\BaseAction such as Sirius\Orm\Action\Update. ( Ignorable by Annotation )

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

135
            $saveAction->/** @scrutinizer ignore-call */ 
136
                         addColumns($this->getExtraColumnsForAction());
Loading history...
136
            $action->prepend($saveAction);
137
            $action->prepend($this->newSyncAction($action->getEntity(), $foreignEntity, 'save'));
138
        }
139
    }
140
}
141