Passed
Push — master ( 02118d...11fb63 )
by Petr
03:00
created

ALdap::readItem()   A

Complexity

Conditions 4
Paths 6

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 4
eloc 1
c 1
b 0
f 1
nc 6
nop 1
dl 0
loc 3
ccs 0
cts 3
cp 0
crap 20
rs 10
1
<?php
2
3
namespace kalanis\kw_mapper\Mappers\Database;
4
5
6
use kalanis\kw_mapper\Interfaces\ICanFill;
7
use kalanis\kw_mapper\Interfaces\IQueryBuilder;
8
use kalanis\kw_mapper\MapperException;
9
use kalanis\kw_mapper\Mappers\AMapper;
10
use kalanis\kw_mapper\Mappers\Shared\TEntityChanged;
11
use kalanis\kw_mapper\Records\ARecord;
12
use kalanis\kw_mapper\Records\TFill;
13
use kalanis\kw_mapper\Storage;
14
15
16
/**
17
 * Class ALdap
18
 * @package kalanis\kw_mapper\Mappers\Database
19
 * @codeCoverageIgnore for now - external source
20
 */
21
abstract class ALdap extends AMapper
22
{
23
    use TEntityChanged;
24
    use TFill;
25
    use TTable;
26
27
    /** @var Storage\Database\Raw\Ldap */
28
    protected $database = null;
29
    /** @var Storage\Shared\QueryBuilder */
30
    protected $queryBuilder = null;
31
    /** @var Storage\Database\Dialects\LdapQueries */
32
    protected $dialect = null;
33
34
    /**
35
     * @throws MapperException
36
     */
37
    public function __construct()
38
    {
39
        parent::__construct();
40
        $config = Storage\Database\ConfigStorage::getInstance()->getConfig($this->getSource());
41
        $this->database = Storage\Database\DatabaseSingleton::getInstance()->getDatabase($config);
42
        $this->dialect = new Storage\Database\Dialects\LdapQueries();
43
        $this->queryBuilder = new Storage\Shared\QueryBuilder();
44
    }
45
46
    public function getAlias(): string
47
    {
48
        return $this->getTable();
49
    }
50
51
    protected function insertRecord(ARecord $record): bool
52
    {
53
        $this->queryBuilder->clear();
54
        $this->queryBuilder->setBaseTable($record->getMapper()->getAlias());
55
        $relations = $record->getMapper()->getRelations();
56
57
        foreach ($record as $key => $item) {
58
            if (isset($relations[$key]) && $this->ifEntryChanged($record->getEntry($key))) {
59
                $this->queryBuilder->addProperty(
60
                    $record->getMapper()->getAlias(),
61
                    $relations[$key],
62
                    $item
63
                );
64
            }
65
        }
66
67
        if (empty($this->queryBuilder->getProperties())) {
68
            return false;
69
        }
70
71
        $this->database->connect();
72
        $connect = $this->database->getConnection();
73
        if (!(is_resource($connect) || is_object($connect))) {
74
            return false;
75
        }
76
77
        return ldap_add(
78
            $connect,
79
            $this->dialect->domainDn($this->database->getDomain()),
80
            $this->dialect->changed($this->queryBuilder)
81
        );
82
    }
83
84
    protected function updateRecord(ARecord $record): bool
85
    {
86
        $this->queryBuilder->clear();
87
        $this->queryBuilder->setBaseTable($record->getMapper()->getAlias());
88
        $relations = $record->getMapper()->getRelations();
89
90
        foreach ($record as $key => $item) {
91
            if (isset($relations[$key]) && $this->ifEntryChanged($record->getEntry($key))) {
92
                if ($record->getEntry($key)->isFromStorage()) {
93
                    $this->queryBuilder->addCondition(
94
                        $record->getMapper()->getAlias(),
95
                        $relations[$key],
96
                        IQueryBuilder::OPERATION_EQ,
97
                        $item
98
                    );
99
                } else {
100
                    $this->queryBuilder->addProperty(
101
                        $record->getMapper()->getAlias(),
102
                        $relations[$key],
103
                        $item
104
                    );
105
                }
106
            }
107
        }
108
109
        if (empty($this->queryBuilder->getConditions())) { /// this one is questionable - I really want to update everything?
110
            return false;
111
        }
112
        if (empty($this->queryBuilder->getProperties())) {
113
            return false;
114
        }
115
116
        $this->database->connect();
117
        $connect = $this->database->getConnection();
118
        if (!(is_resource($connect) || is_object($connect))) {
119
            return false;
120
        }
121
122
        return ldap_mod_replace(
123
            $connect,
124
            $this->dialect->userDn($this->database->getDomain(), $this->getPk($record)),
125
            $this->dialect->changed($this->queryBuilder)
126
        );
127
    }
128
129
    protected function deleteRecord(ARecord $record): bool
130
    {
131
        $this->database->connect();
132
        $connect = $this->database->getConnection();
133
        if (!(is_resource($connect) || is_object($connect))) {
134
            return false;
135
        }
136
137
        return ldap_delete(
138
            $connect,
139
            $this->dialect->userDn($this->database->getDomain(), $this->getPk($record))
140
        );
141
    }
142
143
    /**
144
     * @param ARecord $record
145
     * @throws MapperException
146
     * @return string
147
     */
148
    protected function getPk(ARecord $record)
149
    {
150
        $pks = $this->getPrimaryKeys();
151
        $pk = reset($pks);
152
        $off = $record->offsetGet($pk);
153
        return ($off instanceof ICanFill) ? strval($off->dumpData()) : strval($off);
154
    }
155
156
    protected function loadRecord(ARecord $record): bool
157
    {
158
        $this->fillConditions($record);
159
        $lines = $this->multiple();
160
        if (empty($lines) || empty($lines[0]) || !is_iterable($lines[0])) { // nothing found
161
            return false;
162
        }
163
164
        // fill entries in record
165
        $relations = $record->getMapper()->getRelations();
166
        $relationMap = array_flip($relations);
167
        foreach ($lines[0] as $index => $item) {
168
            $entry = $record->getEntry($relationMap[$index]);
169
            $entry->setData($this->typedFillSelection($entry, $this->readItem($item)), true);
170
        }
171
        return true;
172
    }
173
174
    public function countRecord(ARecord $record): int
175
    {
176
        $this->fillConditions($record);
177
        $entries = $this->multiple();
178
        if (empty($entries) || empty($entries['count'])) {
179
            return 0;
180
        }
181
        return intval($entries['count']);
182
    }
183
184
    public function loadMultiple(ARecord $record): array
185
    {
186
        $this->fillConditions($record);
187
        $lines = $this->multiple();
188
        if (empty($lines)) {
189
            return [];
190
        }
191
192
        $result = [];
193
        $relations = $record->getMapper()->getRelations();
194
        $relationMap = array_flip($relations);
195
        foreach ($lines as $key => $line) {
196
            if (is_numeric($key) && is_iterable($line)) {
197
                $rec = clone $record;
198
                foreach ($line as $index => $item) {
199
                    $entry = $rec->getEntry($relationMap[$index]);
200
                    $entry->setData($this->typedFillSelection($entry, $this->readItem($item)), true);
201
                }
202
                $result[] = $rec;
203
            }
204
        }
205
        return $result;
206
    }
207
208
    /**
209
     * @param mixed $item
210
     * @return string
211
     */
212
    protected function readItem($item)
213
    {
214
        return (empty($item) || empty($item[0]) || ('NULL' == $item[0])) ? '' : $item[0];
215
    }
216
217
    /**
218
     * @param ARecord $record
219
     * @throws MapperException
220
     */
221
    protected function fillConditions(ARecord $record): void
222
    {
223
        $this->queryBuilder->clear();
224
        $this->queryBuilder->setBaseTable($record->getMapper()->getAlias());
225
        $relations = $record->getMapper()->getRelations();
226
227
        foreach ($record as $key => $item) {
228
            if (isset($relations[$key]) && $this->ifEntryChanged($record->getEntry($key))) {
229
                $this->queryBuilder->addCondition(
230
                    $record->getMapper()->getAlias(),
231
                    $relations[$key],
232
                    IQueryBuilder::OPERATION_EQ,
233
                    $item
234
                );
235
            }
236
        }
237
    }
238
239
    /**
240
     * @throws MapperException
241
     * @return array<string|int, string|int|float|array<string|int|float>>
242
     */
243
    protected function multiple(): array
244
    {
245
        $this->database->connect();
246
        $connect = $this->database->getConnection();
247
        if (!(is_resource($connect) || is_object($connect))) {
248
            return [];
249
        }
250
251
        $result = ldap_search(
252
            $connect,
253
            $this->dialect->domainDn($this->database->getDomain()),
254
            $this->dialect->filter($this->queryBuilder)
255
        );
256
        if (false === $result) {
257
            return [];
258
        }
259
260
        $items = ldap_get_entries($connect, $result);
261
        return false !== $items ? $items : [];
262
    }
263
264
    /**
265
     * @param string[] $params
266
     * @throws MapperException
267
     * @return bool
268
     */
269
    public function authorize(array $params): bool
270
    {
271
        if (empty($params['user'])) {
272
            throw new MapperException('Cannot determine user!');
273
        }
274
        if (empty($params['password'])) {
275
            throw new MapperException('Password not set!');
276
        }
277
278
        $this->database->disconnect();
279
        $this->database->connect(false);
280
        $connect = $this->database->getConnection();
281
        if (!(is_resource($connect) || is_object($connect))) {
282
            return false;
283
        }
284
285
        $result = ldap_bind(
286
            $connect,
287
            $this->dialect->userDn($this->database->getDomain(), $params['user']),
288
            $params['password']
289
        );
290
        $this->database->disconnect();
291
292
        return $result;
293
    }
294
}
295