1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
use kalanis\kw_mapper\Interfaces\IDriverSources; |
4
|
|
|
use kalanis\kw_mapper\Interfaces\IEntryType; |
5
|
|
|
use kalanis\kw_mapper\MapperException; |
6
|
|
|
use kalanis\kw_mapper\Mappers; |
7
|
|
|
use kalanis\kw_mapper\Records; |
8
|
|
|
use kalanis\kw_mapper\Search; |
9
|
|
|
use kalanis\kw_mapper\Storage; |
10
|
|
|
|
11
|
|
|
|
12
|
|
|
# somewhere in bootstrap |
13
|
|
|
Storage\Database\ConfigStorage::getInstance()->addConfig( |
14
|
|
|
Storage\Database\Config::init()->setTarget( |
15
|
|
|
IDriverSources::TYPE_PDO_SQLITE, 'europe', '127.0.0.1', 8080, 'testing', 'testing', 'users' |
16
|
|
|
)); |
17
|
|
|
Storage\Database\ConfigStorage::getInstance()->addConfig( |
18
|
|
|
Storage\Database\Config::init()->setTarget( |
19
|
|
|
IDriverSources::TYPE_PDO_SQLITE, 'asia', '::1', 7293, 'testing', 'testing', 'external' |
20
|
|
|
)); |
21
|
|
|
Storage\Database\ConfigStorage::getInstance()->addConfig( |
22
|
|
|
Storage\Database\Config::init()->setTarget( |
23
|
|
|
IDriverSources::TYPE_RAW_LDAP, 'auth', '::1', 9215, 'testing', 'testing', 'tree' |
24
|
|
|
)); |
25
|
|
|
|
26
|
|
|
|
27
|
|
|
# then define records and mappers |
28
|
|
|
|
29
|
|
|
/** |
30
|
|
|
* Class UserRecord |
31
|
|
|
* @property int id |
32
|
|
|
* @property string name |
33
|
|
|
* @property string password |
34
|
|
|
* @property bool enabled |
35
|
|
|
*/ |
36
|
|
|
class UserRecord extends Records\AStrictRecord |
37
|
|
|
{ |
38
|
|
|
protected function addEntries(): void |
39
|
|
|
{ |
40
|
|
|
$this->addEntry('id', IEntryType::TYPE_INTEGER, 2048); |
41
|
|
|
$this->addEntry('name', IEntryType::TYPE_STRING, 128); |
42
|
|
|
$this->addEntry('password', IEntryType::TYPE_STRING, 128); |
43
|
|
|
$this->addEntry('enabled', IEntryType::TYPE_BOOLEAN); |
44
|
|
|
$this->setMapper('\UserDBMapper'); |
45
|
|
|
} |
46
|
|
|
} |
47
|
|
|
|
48
|
|
|
|
49
|
|
|
class UserDBMapper extends Mappers\Database\ADatabase |
50
|
|
|
{ |
51
|
|
|
protected function setMap(): void |
52
|
|
|
{ |
53
|
|
|
$this->setSource('europe'); |
54
|
|
|
$this->setTable('user'); |
55
|
|
|
$this->setRelation('id', 'u_id'); |
56
|
|
|
$this->setRelation('name', 'u_name'); |
57
|
|
|
$this->setRelation('password', 'u_pass'); |
58
|
|
|
$this->setRelation('enabled', 'u_enabled'); |
59
|
|
|
$this->addPrimaryKey('id'); |
60
|
|
|
} |
61
|
|
|
|
62
|
|
|
/** |
63
|
|
|
* Example of DAO and direct queries |
64
|
|
|
* Then you can create your own data records and fill them as extra |
65
|
|
|
* |
66
|
|
|
* @param string $id |
67
|
|
|
* @param string $pass |
68
|
|
|
* @throws MapperException |
69
|
|
|
* @return UserRecord[] |
70
|
|
|
*/ |
71
|
|
|
public function getRecordByIdAndPass(string $id, string $pass): array |
72
|
|
|
{ |
73
|
|
|
$query = 'SELECT `u_id` AS `id`, `u_pass` AS `password` FROM ' . $this->getTable() . ' WHERE `u_id` = :id AND `u_pass` = :pass'; |
74
|
|
|
$params = [':id' => $id, ':pass' => $pass]; |
75
|
|
|
$result = $this->database->query($query, $params); |
76
|
|
|
|
77
|
|
|
$items = []; |
78
|
|
|
foreach ($result as $line) { |
79
|
|
|
$item = new UserRecord(); |
80
|
|
|
$item->loadWithData($line); |
81
|
|
|
$items[] = $item; |
82
|
|
|
} |
83
|
|
|
return $items; |
84
|
|
|
} |
85
|
|
|
} |
86
|
|
|
|
87
|
|
|
|
88
|
|
|
class UserFileMapper extends Mappers\File\ATable |
89
|
|
|
{ |
90
|
|
|
protected function setMap(): void |
91
|
|
|
{ |
92
|
|
|
$this->setSource('users.txt'); |
93
|
|
|
$this->setFormat('\kalanis\kw_mapper\Storage\File\Formats\SeparatedElements'); |
94
|
|
|
$this->setRelation('id', 0); |
95
|
|
|
$this->setRelation('name', 1); |
96
|
|
|
$this->setRelation('password', 2); |
97
|
|
|
$this->setRelation('enabled', 3); |
98
|
|
|
$this->addPrimaryKey('id'); |
99
|
|
|
} |
100
|
|
|
} |
101
|
|
|
|
102
|
|
|
|
103
|
|
|
/** |
104
|
|
|
* Class EntryRecord |
105
|
|
|
* @property int id |
106
|
|
|
* @property string title |
107
|
|
|
* @property string content |
108
|
|
|
* @property kalanis\kw_mapper\Adapters\MappedStdClass details |
109
|
|
|
* @property int user |
110
|
|
|
* @property UserRecord[] users |
111
|
|
|
*/ |
112
|
|
|
class EntryRecord extends Records\AStrictRecord |
113
|
|
|
{ |
114
|
|
|
protected function addEntries(): void |
115
|
|
|
{ |
116
|
|
|
$this->addEntry('id', IEntryType::TYPE_INTEGER, 65536); |
117
|
|
|
$this->addEntry('title', IEntryType::TYPE_STRING, 128); |
118
|
|
|
$this->addEntry('content', IEntryType::TYPE_STRING, 65536); |
119
|
|
|
$this->addEntry('details', IEntryType::TYPE_OBJECT, '\kalanis\kw_mapper\Adapters\MappedStdClass'); |
120
|
|
|
$this->addEntry('user', IEntryType::TYPE_INTEGER, 2048); |
121
|
|
|
$this->addEntry('users', IEntryType::TYPE_ARRAY); // FK - makes the array of entries every time |
122
|
|
|
$this->setMapper('\EntryDBMapper'); |
123
|
|
|
} |
124
|
|
|
} |
125
|
|
|
|
126
|
|
|
|
127
|
|
|
class EntryDBMapper extends Mappers\Database\ADatabase |
128
|
|
|
{ |
129
|
|
|
protected function setMap(): void |
130
|
|
|
{ |
131
|
|
|
$this->setSource('asia'); // access to another db source |
132
|
|
|
$this->setTable('entry'); |
133
|
|
|
$this->setRelation('id', 'e_id'); |
134
|
|
|
$this->setRelation('title', 'e_title'); |
135
|
|
|
$this->setRelation('content', 'e_content'); |
136
|
|
|
$this->setRelation('details', 'e_details'); |
137
|
|
|
$this->setRelation('user', 'u_id'); |
138
|
|
|
$this->addPrimaryKey('id'); |
139
|
|
|
$this->addForeignKey('users', '\UserRecord', 'user', 'id'); |
140
|
|
|
} |
141
|
|
|
|
142
|
|
|
/** |
143
|
|
|
* @param Records\ARecord|EntryRecord $entry |
144
|
|
|
* @return bool |
145
|
|
|
*/ |
146
|
|
|
protected function beforeSave(Records\ARecord $entry): bool |
147
|
|
|
{ |
148
|
|
|
$entry->details = json_encode($entry->details); |
149
|
|
|
return true; |
150
|
|
|
} |
151
|
|
|
|
152
|
|
|
/** |
153
|
|
|
* @param Records\ARecord|EntryRecord $entry |
154
|
|
|
* @return bool |
155
|
|
|
*/ |
156
|
|
|
protected function afterLoad(Records\ARecord $entry): bool |
157
|
|
|
{ |
158
|
|
|
$entry->details = json_decode($entry->details); |
159
|
|
|
return true; |
160
|
|
|
} |
161
|
|
|
} |
162
|
|
|
|
163
|
|
|
|
164
|
|
|
try { |
165
|
|
|
// simple processing with record |
166
|
|
|
$record = new EntryRecord(); |
167
|
|
|
$record->title = 'qwertzui'; |
168
|
|
|
$record->content = 'asdfghjk'; |
169
|
|
|
$record->user = 55; // fk - user id number |
170
|
|
|
$record->save(); |
171
|
|
|
$record->load(); |
172
|
|
|
// now can be used |
173
|
|
|
|
174
|
|
|
// want multiple objects |
175
|
|
|
$record = new EntryRecord(); |
176
|
|
|
$record->title = 'mnbvcxy'; |
177
|
|
|
$records = $record->loadMultiple(); |
178
|
|
|
var_dump($records); |
179
|
|
|
|
180
|
|
|
} catch (MapperException $ex) { |
181
|
|
|
// nothing here |
182
|
|
|
} |
183
|
|
|
|
184
|
|
|
|
185
|
|
|
|
186
|
|
|
try { |
187
|
|
|
$search = new Search\Search(new EntryRecord()); |
188
|
|
|
$search->child('users'); |
189
|
|
|
$search->exact('users.name', 'foo'); |
190
|
|
|
//$search->like('users|name', 'foo%'); |
191
|
|
|
//$search->like('users|rights|allow', 'bar%'); |
192
|
|
|
|
193
|
|
|
$pager = new Pager(); // already done - kw_pager |
194
|
|
|
$pager->maxResults($search->getCount()); |
195
|
|
|
$pager->setPage(2); |
196
|
|
|
$search->offset($pager->getOffset()); |
197
|
|
|
$search->limit($pager->getLimit()); |
198
|
|
|
$search->setPager($pager); // in extension, base do not need that |
199
|
|
|
|
200
|
|
|
$results = $search->getResults(); |
201
|
|
|
} catch (MapperException $ex) { |
202
|
|
|
// nothing here |
203
|
|
|
} |
204
|
|
|
|
205
|
|
|
|
206
|
|
|
/// @todo: |
207
|
|
|
/// tri nastaveni - soubor, tabulka a soubor s tabulkou |
208
|
|
|
/// prvni ma pk jmeno souboru |
209
|
|
|
/// druhy ma pk definovane mimo |
210
|
|
|
/// treti ma pk jmeno ale pod contentem je dalsi objekt - pole entries |
211
|
|
|
/// |
212
|
|
|
/// Idea: Mam admin ucty, ktere maji lokalni nastaveni a overuji se pres ldap |
213
|
|
|
/// Lokalne je profilova fotka, ktera ale ma cestu definovanou v ldapu |
214
|
|
|
/// Pri schvaleni (nalezeni entry) se natahnou data z ldapu a pak se z remote stahne ta fotka jako dalsi entry vazana na ldap |
215
|
|
|
/// |
216
|
|
|
/// nahore (na abstrakci) bude jen setMap() a zakladni operace |
217
|
|
|
/// tedy veci jako beforeSave() a afterLoad() - to, co se ma s objektem pachat okolo (bezva pro audity) |
218
|
|
|
/// oddelovac typu v aplikaci (zatim tecka, dokazu si tam ale predstavit treba # nebo |) bude v searchi - do mapperu netreba, joiny resi builder |
219
|
|
|
/// |
220
|
|
|
/// V budoucnu udelat reprezentaci tabulek - vcetne ColumnType; bez toho se nebudou dat inteligentne delat migrace |
221
|
|
|
|