EntryAdapter::saveFamily()   A
last analyzed

Complexity

Conditions 5
Paths 8

Size

Total Lines 12
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 5

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 5
eloc 8
c 1
b 0
f 0
nc 8
nop 2
dl 0
loc 12
ccs 9
cts 9
cp 1
crap 5
rs 9.6111
1
<?php
2
3
namespace kalanis\kw_pedigree\Storage\MultiTable;
4
5
6
use kalanis\kw_mapper\MapperException;
7
use kalanis\kw_mapper\Mappers\Shared\ForeignKey;
8
use kalanis\kw_mapper\Search\Search;
9
use kalanis\kw_pedigree\Interfaces\ISex;
10
use kalanis\kw_pedigree\PedigreeException;
11
use kalanis\kw_pedigree\Storage\AEntryAdapter;
12
13
14
/**
15
 * Class EntryAdapter
16
 * @package kalanis\kw_pedigree\Storage\MultiTable
17
 */
18
class EntryAdapter extends AEntryAdapter
19
{
20
    /**
21
     * @param int|null $fatherId
22
     * @throws MapperException
23
     * @throws PedigreeException
24
     * @return bool|null
25
     */
26 2
    public function setFatherId(?int $fatherId): ?bool
27
    {
28 2
        return $this->setParentId($fatherId, ISex::MALE);
29
    }
30
31
    /**
32
     * @param int|null $motherId
33
     * @throws MapperException
34
     * @throws PedigreeException
35
     * @return bool|null
36
     */
37 2
    public function setMotherId(?int $motherId): ?bool
38
    {
39 2
        return $this->setParentId($motherId, ISex::FEMALE);
40
    }
41
42
    /**
43
     * @param int|null $parentId
44
     * @param string $sex
45
     * @throws MapperException
46
     * @throws PedigreeException
47
     * @return bool|null
48
     */
49 2
    protected function setParentId(?int $parentId, string $sex): ?bool
50
    {
51 2
        $result = $this->parentLookup($sex);
52 2
        if (!empty($result) && !empty($parentId)) {
53
            // rewrite record
54 1
            if ($result->parentId != $parentId) {
55 1
                $result->parentId = intval($parentId);
56 1
                return $result->save();
57
            }
58 1
            return null;
59 2
        } elseif (!empty($parentId)) {
60
            // new one
61 2
            $record = $this->getRelateRecord();
62 2
            $record->childId = intval($this->getId());
63 2
            $record->parentId = intval($parentId);
64 2
            return $record->save();
65 2
        } elseif (!empty($result) && empty($parentId)) {
66
            // remove current one
67 1
            return $result->delete();
68
        } else {
69 2
            return null;
70
        }
71
    }
72
73
    /**
74
     * @throws MapperException
75
     * @throws PedigreeException
76
     * @return int|null
77
     */
78 1
    public function getFatherId(): ?int
79
    {
80 1
        return $this->getParentId(ISex::MALE);
81
    }
82
83
    /**
84
     * @throws MapperException
85
     * @throws PedigreeException
86
     * @return int|null
87
     */
88 1
    public function getMotherId(): ?int
89
    {
90 1
        return $this->getParentId(ISex::FEMALE);
91
    }
92
93
    /**
94
     * @param string $sex
95
     * @throws MapperException
96
     * @throws PedigreeException
97
     * @return int|null
98
     */
99 1
    protected function getParentId(string $sex): ?int
100
    {
101 1
        $results = $this->parentLookup($sex);
102 1
        return empty($results) ? null : intval($results->parentId);
103
    }
104
105
    /**
106
     * @param string $sex
107
     * @throws MapperException
108
     * @throws PedigreeException
109
     * @return PedigreeRelateRecord|null
110
     */
111 2
    protected function parentLookup(string $sex): ?PedigreeRelateRecord
112
    {
113 2
        $search = new Search($this->getRelateRecord());
114 2
        $search->exact('childId', strval($this->getId()));
115 2
        $search->child('parents', '', '', 'par');
116 2
        $search->like('par.sex', $sex);
117 2
        $results = $search->getResults();
118
        /** @var PedigreeRelateRecord[] $results */
119 2
        return empty($results) ? null : reset($results);
120
    }
121
122 1
    public function getChildren(): array
123
    {
124 1
        $searchRelation = new Search($this->getRelateRecord());
125 1
        $searchRelation->exact('parentId', strval($this->getId()));
126 1
        $search = new Search($this->getLoadedRecord());
127 1
        $search->in('id', array_map([$this, 'mapChildren'], $searchRelation->getResults() ));
128 1
        return $search->getResults();
129
    }
130
131 1
    public function mapChildren(PedigreeRelateRecord $record): string
132
    {
133 1
        return strval($record->childId);
134
    }
135
136 2
    public function saveFamily(?int $fatherId, ?int $motherId): ?bool
137
    {
138 2
        $willSave = null;
139 2
        $action = $this->setFatherId($fatherId);
140 2
        if (is_bool($action)) {
141 2
            $willSave = $action;
142
        }
143 2
        $action = $this->setMotherId($motherId);
144 2
        if (is_bool($action)) {
145 2
            $willSave = (is_bool($willSave) ? $willSave : true) && $action;
146
        }
147 2
        return $willSave;
148
    }
149
150
    /**
151
     * Unhook the original class, use only its definition and create new clear copy
152
     * @throws MapperException
153
     * @throws PedigreeException
154
     * @return PedigreeRelateRecord
155
     */
156 3
    protected function getRelateRecord(): PedigreeRelateRecord
157
    {
158 3
        $fks = $this->getLoadedRecord()->getMapper()->getForeignKeys();
159
        /** @var array<string, ForeignKey> $fks */
160 3
        if (!isset($fks['children'])) {
161
            // @codeCoverageIgnoreStart
162
            throw new PedigreeException('Your mapper does not have children');
163
        }
164
        // @codeCoverageIgnoreEnd
165 3
        $record = $fks['children']->getRemoteRecord();
166 3
        return new $record();
167
    }
168
}
169