Test Failed
Push — master ( 50dc03...2f2ddd )
by Petr
02:45
created

ALdap::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
eloc 5
c 1
b 0
f 1
dl 0
loc 7
rs 10
cc 1
nc 1
nop 0
1
<?php
2
3
namespace kalanis\kw_mapper\Mappers\Database;
4
5
6
use kalanis\kw_mapper\Interfaces\IQueryBuilder;
7
use kalanis\kw_mapper\MapperException;
8
use kalanis\kw_mapper\Mappers\AMapper;
9
use kalanis\kw_mapper\Records\ARecord;
10
use kalanis\kw_mapper\Records\TFill;
11
use kalanis\kw_mapper\Storage;
12
13
14
/**
15
 * Class ALdap
16
 * @package kalanis\kw_mapper\Mappers\Database
17
 * @codeCoverageIgnore for now - external source
18
 */
19
abstract class ALdap extends AMapper
20
{
21
    use TFill;
22
    use TTable;
23
24
    /** @var Storage\Database\Raw\Ldap */
25
    protected $database = null;
26
    /** @var Storage\Shared\QueryBuilder */
27
    protected $queryBuilder = null;
28
    /** @var Storage\Database\Dialects\LdapQueries */
29
    protected $dialect = null;
30
31
    /**
32
     * @throws MapperException
33
     */
34
    public function __construct()
35
    {
36
        parent::__construct();
37
        $config = Storage\Database\ConfigStorage::getInstance()->getConfig($this->getSource());
38
        $this->database = Storage\Database\DatabaseSingleton::getInstance()->getDatabase($config);
39
        $this->dialect = new Storage\Database\Dialects\LdapQueries();
40
        $this->queryBuilder = new Storage\Shared\QueryBuilder();
41
    }
42
43
    public function getAlias(): string
44
    {
45
        return $this->getTable();
46
    }
47
48
    protected function insertRecord(ARecord $record): bool
49
    {
50
        $this->queryBuilder->clear();
51
        $this->queryBuilder->setBaseTable($this->getTable());
52
        foreach ($record as $key => $item) {
53
            $this->queryBuilder->addProperty($this->getTable(), $this->relations[$key], $item);
54
        }
55
        $this->database->connect();
56
        $connect = $this->database->getConnection();
57
        if (!(is_resource($connect) || is_object($connect))) {
58
            return false;
59
        }
60
        return ldap_add(
61
            $connect,
62
            $this->dialect->domainDn($this->database->getDomain()),
63
            $this->dialect->changed($this->queryBuilder)
64
        );
65
    }
66
67
    protected function updateRecord(ARecord $record): bool
68
    {
69
        $this->queryBuilder->clear();
70
        $this->queryBuilder->setBaseTable($this->getTable());
71
        foreach ($record as $key => $item) {
72
            if (!$record->getEntry($key)->isFromStorage()) {
73
                $this->queryBuilder->addProperty($this->getTable(), $this->relations[$key], $item);
74
            }
75
        }
76
        $this->database->connect();
77
        $connect = $this->database->getConnection();
78
        if (!(is_resource($connect) || is_object($connect))) {
79
            return false;
80
        }
81
        return ldap_mod_replace(
82
            $connect,
83
            $this->dialect->userDn($this->database->getDomain(), $this->getPk($record)),
0 ignored issues
show
Bug introduced by
It seems like $this->getPk($record) can also be of type kalanis\kw_mapper\Interfaces\ICanFill and null; however, parameter $username of kalanis\kw_mapper\Storag...s\LdapQueries::userDn() 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

83
            $this->dialect->userDn($this->database->getDomain(), /** @scrutinizer ignore-type */ $this->getPk($record)),
Loading history...
84
            $this->dialect->changed($this->queryBuilder)
85
        );
86
    }
87
88
    protected function deleteRecord(ARecord $record): bool
89
    {
90
        $this->database->connect();
91
        $connect = $this->database->getConnection();
92
        if (!(is_resource($connect) || is_object($connect))) {
93
            return false;
94
        }
95
        return ldap_delete(
96
            $connect,
97
            $this->dialect->userDn($this->database->getDomain(), $this->getPk($record))
0 ignored issues
show
Bug introduced by
It seems like $this->getPk($record) can also be of type kalanis\kw_mapper\Interfaces\ICanFill and null; however, parameter $username of kalanis\kw_mapper\Storag...s\LdapQueries::userDn() 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

97
            $this->dialect->userDn($this->database->getDomain(), /** @scrutinizer ignore-type */ $this->getPk($record))
Loading history...
98
        );
99
    }
100
101
    /**
102
     * @param ARecord $record
103
     * @throws MapperException
104
     * @return mixed
105
     */
106
    protected function getPk(ARecord $record)
107
    {
108
        $pks = $this->getPrimaryKeys();
109
        $pk = reset($pks);
110
        return $record->offsetGet($pk);
111
    }
112
113
    protected function loadRecord(ARecord $record): bool
114
    {
115
        $this->fillConditions($record);
116
        $lines = $this->multiple();
117
        if (empty($lines) || empty($lines[0]) || !is_iterable($lines[0])) { // nothing found
118
            return false;
119
        }
120
121
        // fill entries in record
122
        $relationMap = array_flip($this->relations);
123
        foreach ($lines[0] as $index => $item) {
124
            $entry = $record->getEntry($relationMap[$index]);
125
            $entry->setData($this->typedFillSelection($entry, $this->readItem($item)), true);
126
        }
127
        return true;
128
    }
129
130
    public function countRecord(ARecord $record): int
131
    {
132
        $this->fillConditions($record);
133
        $entries = $this->multiple();
134
        if (empty($entries) || empty($entries['count'])) {
135
            return 0;
136
        }
137
        return intval($entries['count']);
138
    }
139
140
    public function loadMultiple(ARecord $record): array
141
    {
142
        $this->fillConditions($record);
143
        $lines = $this->multiple();
144
        if (empty($lines)) {
145
            return [];
146
        }
147
148
        $result = [];
149
        $relationMap = array_flip($this->relations);
150
        foreach ($lines as $key => $line) {
151
            if (is_numeric($key) && is_iterable($line)) {
152
                $rec = clone $record;
153
                foreach ($line as $index => $item) {
154
                    $entry = $rec->getEntry($relationMap[$index]);
155
                    $entry->setData($this->typedFillSelection($entry, $this->readItem($item)), true);
156
                }
157
                $result[] = $rec;
158
            }
159
        }
160
        return $result;
161
    }
162
163
    /**
164
     * @param mixed $item
165
     * @return string
166
     */
167
    protected function readItem($item)
168
    {
169
        return (empty($item) || empty($item[0]) || ('NULL' == $item[0])) ? '' : $item[0];
170
    }
171
172
    /**
173
     * @param ARecord $record
174
     * @throws MapperException
175
     */
176
    protected function fillConditions(ARecord $record): void
177
    {
178
        $this->queryBuilder->clear();
179
        $this->queryBuilder->setBaseTable($this->getTable());
180
        foreach ($record as $key => $item) {
181
            if (false !== $item) {
182
                $this->queryBuilder->addCondition($this->getTable(), $this->relations[$key], IQueryBuilder::OPERATION_EQ, $item);
183
            }
184
        }
185
    }
186
187
    /**
188
     * @throws MapperException
189
     * @return array<string|int, string|int|float|array<string|int|float>>
190
     */
191
    protected function multiple(): array
192
    {
193
        $this->database->connect();
194
        $connect = $this->database->getConnection();
195
        if (!(is_resource($connect) || is_object($connect))) {
196
            return [];
197
        }
198
        $result = ldap_search(
199
            $connect,
200
            $this->dialect->domainDn($this->database->getDomain()),
201
            $this->dialect->filter($this->queryBuilder)
202
        );
203
        if (false === $result) {
204
            return [];
205
        }
206
        $items = ldap_get_entries($connect, $result);
207
        return false !== $items ? $items : [];
208
    }
209
210
    /**
211
     * @param string[] $params
212
     * @throws MapperException
213
     * @return bool
214
     */
215
    public function authorize(array $params): bool
216
    {
217
        if (empty($params['user'])) {
218
            throw new MapperException('Cannot determine user!');
219
        }
220
        if (empty($params['password'])) {
221
            throw new MapperException('Password not set!');
222
        }
223
        $this->database->disconnect();
224
        $this->database->connect(false);
225
        $connect = $this->database->getConnection();
226
        if (!(is_resource($connect) || is_object($connect))) {
227
            return false;
228
        }
229
        $result = ldap_bind($connect, $this->dialect->userDn($this->database->getDomain(), $params['user']), $params['password']);
230
        $this->database->disconnect();
231
        return $result;
232
    }
233
}
234