Passed
Push — master ( 63f0e8...02118d )
by Petr
02:59
created

ALdap::updateRecord()   B

Complexity

Conditions 7
Paths 8

Size

Total Lines 24
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 56

Importance

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