Subversion Repositories oidplus

Rev

Rev 730 | Rev 800 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 daniel-mar 1
<?php
2
 
3
/*
4
 * OIDplus 2.0
511 daniel-mar 5
 * Copyright 2019 - 2021 Daniel Marschall, ViaThinkSoft
2 daniel-mar 6
 *
7
 * Licensed under the Apache License, Version 2.0 (the "License");
8
 * you may not use this file except in compliance with the License.
9
 * You may obtain a copy of the License at
10
 *
11
 *     http://www.apache.org/licenses/LICENSE-2.0
12
 *
13
 * Unless required by applicable law or agreed to in writing, software
14
 * distributed under the License is distributed on an "AS IS" BASIS,
15
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
 * See the License for the specific language governing permissions and
17
 * limitations under the License.
18
 */
19
 
511 daniel-mar 20
if (!defined('INSIDE_OIDPLUS')) die();
21
 
730 daniel-mar 22
abstract class OIDplusObject extends OIDplusBaseClass {
261 daniel-mar 23
        const UUID_NAMEBASED_NS_OidPlusMisc = 'ad1654e6-7e15-11e4-9ef6-78e3b5fc7f22';
150 daniel-mar 24
 
2 daniel-mar 25
        public static function parse($node_id) { // please overwrite this function!
26
                // TODO: in case we are not calling this class directly, check if function is overwritten and throw exception otherwise
227 daniel-mar 27
                foreach (OIDplus::getEnabledObjectTypes() as $ot) {
2 daniel-mar 28
                        if ($obj = $ot::parse($node_id)) return $obj;
29
                }
30
                return null;
31
        }
32
 
228 daniel-mar 33
        public function /*OIDplusAltId[]*/ getAltIds() {
193 daniel-mar 34
                if ($this->isRoot()) return array();
35
 
36
                $ids = array();
37
                if ($this->ns() != 'oid') {
38
                        // Creates an OIDplus-Hash-OID
39
                        // If the object type has a better way of defining an OID, please override this method!
227 daniel-mar 40
                        $sid = OIDplus::getSystemId(true);
193 daniel-mar 41
                        if (!empty($sid)) {
42
                                $oid = $sid . '.' . smallhash($this->nodeId());
360 daniel-mar 43
                                $ids[] = new OIDplusAltId('oid', $oid, _L('OIDplus Information Object ID'));
193 daniel-mar 44
                        }
45
                }
46
                if ($this->ns() != 'guid') {
360 daniel-mar 47
                        $ids[] = new OIDplusAltId('guid', gen_uuid_md5_namebased(self::UUID_NAMEBASED_NS_OidPlusMisc, $this->nodeId()), _L('Name based version 3 / MD5 UUID with namespace %1','UUID_NAMEBASED_NS_OidPlusMisc'));
48
                        $ids[] = new OIDplusAltId('guid', gen_uuid_sha1_namebased(self::UUID_NAMEBASED_NS_OidPlusMisc, $this->nodeId()), _L('Name based version 5 / SHA1 UUID with namespace %1','UUID_NAMEBASED_NS_OidPlusMisc'));
193 daniel-mar 49
                }
50
                return $ids;
83 daniel-mar 51
        }
52
 
2 daniel-mar 53
        public abstract static function objectTypeTitle();
54
 
55
        public abstract static function objectTypeTitleShort();
56
 
57
        public abstract static function ns();
58
 
59
        public abstract static function root();
60
 
61
        public abstract function isRoot();
62
 
247 daniel-mar 63
        public abstract function nodeId($with_ns=true);
2 daniel-mar 64
 
65
        public abstract function addString($str);
66
 
67
        public abstract function crudShowId(OIDplusObject $parent);
68
 
707 daniel-mar 69
        public function crudInsertPrefix() {
70
                return '';
71
        }
2 daniel-mar 72
 
707 daniel-mar 73
        public function crudInsertSuffix() {
74
                return '';
75
        }
76
 
2 daniel-mar 77
        public abstract function jsTreeNodeName(OIDplusObject $parent = null);
78
 
79
        public abstract function defaultTitle();
80
 
16 daniel-mar 81
        public abstract function isLeafNode();
82
 
34 daniel-mar 83
        public abstract function getContentPage(&$title, &$content, &$icon);
2 daniel-mar 84
 
27 daniel-mar 85
        public static function getRaRoots($ra_email=null) {
115 daniel-mar 86
                if ($ra_email instanceof OIDplusRA) $ra_email = $ra_email->raEmail();
87
 
27 daniel-mar 88
                $out = array();
150 daniel-mar 89
 
261 daniel-mar 90
                if (!OIDplus::baseConfig()->getValue('OBJECT_CACHING', true)) {
150 daniel-mar 91
                        if (is_null($ra_email)) {
261 daniel-mar 92
                                $res = OIDplus::db()->query("select oChild.id as id, oChild.ra_email as child_mail, oParent.ra_email as parent_mail from ###objects as oChild ".
93
                                                            "left join ###objects as oParent on oChild.parent = oParent.id ".
150 daniel-mar 94
                                                            "order by ".OIDplus::db()->natOrder('oChild.id'));
236 daniel-mar 95
                                while ($row = $res->fetch_array()) {
549 daniel-mar 96
                                        if (!OIDplus::authUtils()->isRaLoggedIn($row['parent_mail']) && OIDplus::authUtils()->isRaLoggedIn($row['child_mail'])) {
150 daniel-mar 97
                                                $x = self::parse($row['id']); // can be FALSE if namespace was disabled
98
                                                if ($x) $out[] = $x;
99
                                        }
100
                                }
101
                        } else {
261 daniel-mar 102
                                $res = OIDplus::db()->query("select oChild.id as id from ###objects as oChild ".
103
                                                            "left join ###objects as oParent on oChild.parent = oParent.id ".
433 daniel-mar 104
                                                            "where (".OIDplus::db()->getSlang()->isNullFunction('oParent.ra_email',"''")." <> ? and ".
105
                                                            OIDplus::db()->getSlang()->isNullFunction('oChild.ra_email',"''")." = ?) or ".
106
                                                            "      (oParent.ra_email is null and ".OIDplus::db()->getSlang()->isNullFunction('oChild.ra_email',"''")." = ?) ".
150 daniel-mar 107
                                                            "order by ".OIDplus::db()->natOrder('oChild.id'), array($ra_email, $ra_email, $ra_email));
236 daniel-mar 108
                                while ($row = $res->fetch_array()) {
68 daniel-mar 109
                                        $x = self::parse($row['id']); // can be FALSE if namespace was disabled
150 daniel-mar 110
                                        if ($x) $out[] = self::parse($row['id']);
27 daniel-mar 111
                                }
2 daniel-mar 112
                        }
113
                } else {
150 daniel-mar 114
                        if (is_null($ra_email)) {
415 daniel-mar 115
                                $ra_mails_to_check = OIDplus::authUtils()->loggedInRaList();
150 daniel-mar 116
                                if (count($ra_mails_to_check) == 0) return $out;
117
                        } else {
118
                                $ra_mails_to_check = array($ra_email);
2 daniel-mar 119
                        }
150 daniel-mar 120
 
121
                        self::buildObjectInformationCache();
122
 
123
                        foreach ($ra_mails_to_check as $check_ra_mail) {
193 daniel-mar 124
                                $out_part = array();
150 daniel-mar 125
 
193 daniel-mar 126
                                foreach (self::$object_info_cache as $id => list($confidential, $parent, $ra_email, $title)) {
127
                                        // If the OID RA is the RA we are searching, then add the object to the choice list
128
                                        if ($ra_email == $check_ra_mail) $out_part[] = $id;
150 daniel-mar 129
                                }
130
 
193 daniel-mar 131
                                foreach (self::$object_info_cache as $id => list($confidential, $parent, $ra_email, $title)) {
132
                                        if (isset(self::$object_info_cache[$parent])) {
133
                                                if (self::$object_info_cache[$parent][self::CACHE_RA_EMAIL] == $ra_email) {
134
                                                        // if the parent has the same RA, then this OID cannot be a root => remove the element from the choice list
135
                                                        foreach (array_keys($out_part, $id) as $key) unset($out_part[$key]);
150 daniel-mar 136
                                                }
137
                                        }
138
                                }
139
 
140
                                natsort($out_part);
141
 
142
                                foreach ($out_part as $id) {
143
                                        $obj = self::parse($id);
144
                                        if ($obj) $out[] = $obj;
145
                                }
146
                        }
2 daniel-mar 147
                }
150 daniel-mar 148
 
2 daniel-mar 149
                return $out;
150
        }
151
 
150 daniel-mar 152
        public static function getAllNonConfidential() {
153
                $out = array();
154
 
261 daniel-mar 155
                if (!OIDplus::baseConfig()->getValue('OBJECT_CACHING', true)) {
443 daniel-mar 156
                        $res = OIDplus::db()->query("select id from ###objects where confidential = ? order by ".OIDplus::db()->natOrder('id'), array(false));
150 daniel-mar 157
 
236 daniel-mar 158
                        while ($row = $res->fetch_array()) {
150 daniel-mar 159
                                $obj = self::parse($row['id']); // will be NULL if the object type is not registered
169 daniel-mar 160
                                if ($obj && (!$obj->isConfidential())) {
150 daniel-mar 161
                                        $out[] = $row['id'];
162
                                }
2 daniel-mar 163
                        }
164
                } else {
150 daniel-mar 165
                        self::buildObjectInformationCache();
2 daniel-mar 166
 
193 daniel-mar 167
                        foreach (self::$object_info_cache as $id => list($confidential, $parent, $ra_email, $title)) {
150 daniel-mar 168
                                if (!$confidential) {
169
                                        $obj = self::parse($id); // will be NULL if the object type is not registered
169 daniel-mar 170
                                        if ($obj && (!$obj->isConfidential())) {
150 daniel-mar 171
                                                $out[] = $id;
172
                                        }
173
                                }
2 daniel-mar 174
                        }
175
                }
176
 
177
                return $out;
178
        }
179
 
180
        public function isConfidential() {
261 daniel-mar 181
                if (!OIDplus::baseConfig()->getValue('OBJECT_CACHING', true)) {
426 daniel-mar 182
                        //static $confidential_cache = array();
150 daniel-mar 183
                        $curid = $this->nodeId();
426 daniel-mar 184
                        //$orig_curid = $curid;
185
                        //if (isset($confidential_cache[$curid])) return $confidential_cache[$curid];
150 daniel-mar 186
                        // Recursively search for the confidential flag in the parents
790 daniel-mar 187
                        while (($res = OIDplus::db()->query("select parent, confidential from ###objects where id = ?", array($curid)))->any()) {
236 daniel-mar 188
                                $row = $res->fetch_array();
150 daniel-mar 189
                                if ($row['confidential']) {
426 daniel-mar 190
                                        //$confidential_cache[$curid] = true;
191
                                        //$confidential_cache[$orig_curid] = true;
150 daniel-mar 192
                                        return true;
193
                                } else {
426 daniel-mar 194
                                        //$confidential_cache[$curid] = false;
150 daniel-mar 195
                                }
196
                                $curid = $row['parent'];
426 daniel-mar 197
                                //if (isset($confidential_cache[$curid])) {
198
                                        //$confidential_cache[$orig_curid] = $confidential_cache[$curid];
199
                                        //return $confidential_cache[$curid];
200
                                //}
150 daniel-mar 201
                        }
202
 
426 daniel-mar 203
                        //$confidential_cache[$orig_curid] = false;
150 daniel-mar 204
                        return false;
205
                } else {
206
                        self::buildObjectInformationCache();
207
 
208
                        $curid = $this->nodeId();
209
                        // Recursively search for the confidential flag in the parents
169 daniel-mar 210
                        while (isset(self::$object_info_cache[$curid])) {
150 daniel-mar 211
                                if (self::$object_info_cache[$curid][self::CACHE_CONFIDENTIAL]) return true;
212
                                $curid = self::$object_info_cache[$curid][self::CACHE_PARENT];
213
                        }
214
                        return false;
2 daniel-mar 215
                }
216
        }
217
 
218
        public function isChildOf(OIDplusObject $obj) {
261 daniel-mar 219
                if (!OIDplus::baseConfig()->getValue('OBJECT_CACHING', true)) {
150 daniel-mar 220
                        $curid = $this->nodeId();
790 daniel-mar 221
                        while (($res = OIDplus::db()->query("select parent from ###objects where id = ?", array($curid)))->any()) {
236 daniel-mar 222
                                $row = $res->fetch_array();
150 daniel-mar 223
                                if ($curid == $obj->nodeId()) return true;
224
                                $curid = $row['parent'];
225
                        }
226
                        return false;
227
                } else {
228
                        self::buildObjectInformationCache();
229
 
230
                        $curid = $this->nodeId();
169 daniel-mar 231
                        while (isset(self::$object_info_cache[$curid])) {
150 daniel-mar 232
                                if ($curid == $obj->nodeId()) return true;
233
                                $curid = self::$object_info_cache[$curid][self::CACHE_PARENT];
234
                        }
235
                        return false;
2 daniel-mar 236
                }
150 daniel-mar 237
        }
2 daniel-mar 238
 
150 daniel-mar 239
        public function getChildren() {
240
                $out = array();
261 daniel-mar 241
                if (!OIDplus::baseConfig()->getValue('OBJECT_CACHING', true)) {
242
                        $res = OIDplus::db()->query("select id from ###objects where parent = ?", array($this->nodeId()));
236 daniel-mar 243
                        while ($row = $res->fetch_array()) {
150 daniel-mar 244
                                $obj = self::parse($row['id']);
245
                                if (!$obj) continue;
246
                                $out[] = $obj;
247
                        }
248
                } else {
249
                        self::buildObjectInformationCache();
250
 
193 daniel-mar 251
                        foreach (self::$object_info_cache as $id => list($confidential, $parent, $ra_email, $title)) {
150 daniel-mar 252
                                if ($parent == $this->nodeId()) {
253
                                        $obj = self::parse($id);
254
                                        if (!$obj) continue;
255
                                        $out[] = $obj;
256
                                }
257
                        }
258
                }
259
                return $out;
2 daniel-mar 260
        }
261
 
115 daniel-mar 262
        public function getRa() {
150 daniel-mar 263
                return new OIDplusRA($this->getRaMail());
115 daniel-mar 264
        }
265
 
2 daniel-mar 266
        public function userHasReadRights($ra_email=null) {
115 daniel-mar 267
                if ($ra_email instanceof OIDplusRA) $ra_email = $ra_email->raEmail();
268
 
2 daniel-mar 269
                // If it is not confidential, everybody can read/see it.
416 daniel-mar 270
                // Note: This also checks if superior OIDs are confidential.
2 daniel-mar 271
                if (!$this->isConfidential()) return true;
272
 
273
                if (is_null($ra_email)) {
416 daniel-mar 274
                        // Admin may do everything
549 daniel-mar 275
                        if (OIDplus::authUtils()->isAdminLoggedIn()) return true;
416 daniel-mar 276
 
277
                        // If the RA is logged in, then they can see the OID.
549 daniel-mar 278
                        if (OIDplus::authUtils()->isRaLoggedIn($this->getRaMail())) return true;
2 daniel-mar 279
                } else {
416 daniel-mar 280
                        // If this OID belongs to the requested RA, then they may see it.
150 daniel-mar 281
                        if ($this->getRaMail() == $ra_email) return true;
2 daniel-mar 282
                }
283
 
284
                // If someone has rights to an object below our confidential node,
285
                // we let him see the confidential node,
286
                // Otherwise he could not browse through to his own node.
287
                $roots = $this->getRaRoots($ra_email);
288
                foreach ($roots as $root) {
289
                        if ($root->isChildOf($this)) return true;
290
                }
291
 
292
                return false;
293
        }
294
 
295
        public function getIcon($row=null) {
20 daniel-mar 296
                $namespace = $this->ns(); // must use $this, not self::, otherwise the virtual method will not be called
2 daniel-mar 297
 
298
                if (is_null($row)) {
150 daniel-mar 299
                        $ra_email = $this->getRaMail();
300
                } else {
301
                        $ra_email = $row['ra_email'];
2 daniel-mar 302
                }
303
                // TODO: have different icons for Leaf-Nodes
632 daniel-mar 304
 
635 daniel-mar 305
                $dirs = glob(OIDplus::localpath().'plugins/'.'*'.'/objectTypes/'.$namespace.'/');
632 daniel-mar 306
 
307
                if (count($dirs) == 0) return null; // default icon (folder)
308
 
309
                $dir = substr($dirs[0], strlen(OIDplus::localpath()));
310
 
549 daniel-mar 311
                if (OIDplus::authUtils()->isRaLoggedIn($ra_email)) {
632 daniel-mar 312
                        $icon = $dir.'/img/treeicon_own.png';
2 daniel-mar 313
                } else {
632 daniel-mar 314
                        $icon = $dir.'/img/treeicon_general.png';
2 daniel-mar 315
                }
632 daniel-mar 316
 
317
                if (!file_exists($icon)) return null; // default icon (folder)
318
 
2 daniel-mar 319
                return $icon;
320
        }
321
 
12 daniel-mar 322
        public static function exists($id) {
261 daniel-mar 323
                if (!OIDplus::baseConfig()->getValue('OBJECT_CACHING', true)) {
324
                        $res = OIDplus::db()->query("select id from ###objects where id = ?", array($id));
790 daniel-mar 325
                        return $res->any();
150 daniel-mar 326
                } else {
327
                        self::buildObjectInformationCache();
328
                        return isset(self::$object_info_cache[$id]);
329
                }
12 daniel-mar 330
        }
331
 
415 daniel-mar 332
        // Get parent gives the next possible parent which is EXISTING in OIDplus
333
        // It does not give the immediate parent
2 daniel-mar 334
        public function getParent() {
261 daniel-mar 335
                if (!OIDplus::baseConfig()->getValue('OBJECT_CACHING', true)) {
336
                        $res = OIDplus::db()->query("select parent from ###objects where id = ?", array($this->nodeId()));
790 daniel-mar 337
                        if (!$res->any()) return null;
236 daniel-mar 338
                        $row = $res->fetch_array();
150 daniel-mar 339
                        $parent = $row['parent'];
340
                        $obj = OIDplusObject::parse($parent);
341
                        if ($obj) return $obj;
415 daniel-mar 342
                        // TODO: Also implement one_up() like below
150 daniel-mar 343
                } else {
344
                        self::buildObjectInformationCache();
345
                        if (isset(self::$object_info_cache[$this->nodeId()])) {
346
                                $parent = self::$object_info_cache[$this->nodeId()][self::CACHE_PARENT];
347
                                $obj = OIDplusObject::parse($parent);
348
                                if ($obj) return $obj;
349
                        }
20 daniel-mar 350
 
150 daniel-mar 351
                        // If this OID does not exist, the SQL query "select parent from ..." does not work. So we try to find the next possible parent using one_up()
352
                        $cur = $this->one_up();
418 daniel-mar 353
                        if (!$cur) return null;
150 daniel-mar 354
                        do {
415 daniel-mar 355
                                // findFitting() checks if that OID exists
150 daniel-mar 356
                                if ($fitting = self::findFitting($cur->nodeId())) return $fitting;
20 daniel-mar 357
 
150 daniel-mar 358
                                $prev = $cur;
359
                                $cur = $cur->one_up();
418 daniel-mar 360
                                if (!$cur) return null;
150 daniel-mar 361
                        } while ($prev != $cur);
362
 
418 daniel-mar 363
                        return null;
150 daniel-mar 364
                }
2 daniel-mar 365
        }
366
 
367
        public function getRaMail() {
261 daniel-mar 368
                if (!OIDplus::baseConfig()->getValue('OBJECT_CACHING', true)) {
369
                        $res = OIDplus::db()->query("select ra_email from ###objects where id = ?", array($this->nodeId()));
790 daniel-mar 370
                        if (!$res->any()) return null;
236 daniel-mar 371
                        $row = $res->fetch_array();
150 daniel-mar 372
                        return $row['ra_email'];
373
                } else {
374
                        self::buildObjectInformationCache();
375
                        if (isset(self::$object_info_cache[$this->nodeId()])) {
376
                                return self::$object_info_cache[$this->nodeId()][self::CACHE_RA_EMAIL];
377
                        }
378
                        return false;
379
                }
2 daniel-mar 380
        }
381
 
192 daniel-mar 382
        public function getTitle() {
261 daniel-mar 383
                if (!OIDplus::baseConfig()->getValue('OBJECT_CACHING', true)) {
384
                        $res = OIDplus::db()->query("select title from ###objects where id = ?", array($this->nodeId()));
790 daniel-mar 385
                        if (!$res->any()) return null;
236 daniel-mar 386
                        $row = $res->fetch_array();
192 daniel-mar 387
                        return $row['title'];
388
                } else {
389
                        self::buildObjectInformationCache();
390
                        if (isset(self::$object_info_cache[$this->nodeId()])) {
391
                                return self::$object_info_cache[$this->nodeId()][self::CACHE_TITLE];
392
                        }
393
                        return false;
394
                }
395
        }
396
 
2 daniel-mar 397
        public function userHasParentalWriteRights($ra_email=null) {
115 daniel-mar 398
                if ($ra_email instanceof OIDplusRA) $ra_email = $ra_email->raEmail();
399
 
2 daniel-mar 400
                if (is_null($ra_email)) {
549 daniel-mar 401
                        if (OIDplus::authUtils()->isAdminLoggedIn()) return true;
2 daniel-mar 402
                }
403
 
404
                $objParent = $this->getParent();
419 daniel-mar 405
                if (!$objParent) return false;
2 daniel-mar 406
                return $objParent->userHasWriteRights($ra_email);
407
        }
408
 
409
        public function userHasWriteRights($ra_email=null) {
115 daniel-mar 410
                if ($ra_email instanceof OIDplusRA) $ra_email = $ra_email->raEmail();
411
 
2 daniel-mar 412
                if (is_null($ra_email)) {
549 daniel-mar 413
                        if (OIDplus::authUtils()->isAdminLoggedIn()) return true;
414
                        return OIDplus::authUtils()->isRaLoggedIn($this->getRaMail());
2 daniel-mar 415
                } else {
416
                        return $this->getRaMail() == $ra_email;
417
                }
418
        }
12 daniel-mar 419
 
420
        public function distance($to) {
421
                return null; // not implemented
422
        }
20 daniel-mar 423
 
424
        public function equals($obj) {
425
                if (!is_object($obj)) $obj = OIDplusObject::parse($obj);
28 daniel-mar 426
                if (!($obj instanceof $this)) return false;
427
 
20 daniel-mar 428
                $distance = $this->distance($obj);
429
                if (is_numeric($distance)) return $distance === 0; // if the distance function is implemented, use it
430
 
431
                return $this->nodeId() == $obj->nodeId(); // otherwise compare the node id case-sensitive
432
        }
433
 
434
        public static function findFitting($id) {
435
                $obj = OIDplusObject::parse($id);
360 daniel-mar 436
                if (!$obj) throw new OIDplusException(_L('findFitting: Parse failed'));
20 daniel-mar 437
 
261 daniel-mar 438
                if (!OIDplus::baseConfig()->getValue('OBJECT_CACHING', true)) {
439
                        $res = OIDplus::db()->query("select id from ###objects where id like ?", array($obj->ns().':%'));
236 daniel-mar 440
                        while ($row = $res->fetch_object()) {
150 daniel-mar 441
                                $test = OIDplusObject::parse($row->id);
442
                                if ($obj->equals($test)) return $test;
443
                        }
444
                        return false;
445
                } else {
446
                        self::buildObjectInformationCache();
193 daniel-mar 447
                        foreach (self::$object_info_cache as $id => list($confidential, $parent, $ra_email, $title)) {
150 daniel-mar 448
                                if (strpos($id, $obj->ns().':') === 0) {
449
                                        $test = OIDplusObject::parse($id);
450
                                        if ($obj->equals($test)) return $test;
451
                                }
452
                        }
453
                        return false;
20 daniel-mar 454
                }
455
        }
456
 
457
        public function one_up() {
458
                return null; // not implemented
459
        }
150 daniel-mar 460
 
461
        // Caching stuff
462
 
463
        protected static $object_info_cache = null;
464
 
465
        public static function resetObjectInformationCache() {
466
                self::$object_info_cache = null;
467
        }
468
 
193 daniel-mar 469
        const CACHE_CONFIDENTIAL = 0; // TODO: An object would be better so you can use $cacheitem->isConfidential() etc.
150 daniel-mar 470
        const CACHE_PARENT = 1;
471
        const CACHE_RA_EMAIL = 2;
192 daniel-mar 472
        const CACHE_TITLE = 3;
150 daniel-mar 473
 
474
        private static function buildObjectInformationCache() {
475
                if (is_null(self::$object_info_cache)) {
476
                        self::$object_info_cache = array();
261 daniel-mar 477
                        $res = OIDplus::db()->query("select id, parent, confidential, ra_email, title from ###objects");
236 daniel-mar 478
                        while ($row = $res->fetch_array()) {
192 daniel-mar 479
                                self::$object_info_cache[$row['id']] = array($row['confidential'], $row['parent'], $row['ra_email'], $row['title']);
150 daniel-mar 480
                        }
481
                }
482
        }
513 daniel-mar 483
 
484
        // override this function if you want your object type to save
485
        // attachments in directories with easy names.
486
        // Take care that your custom directory name will not allow jailbreaks (../) !
487
        public function getDirectoryName() {
514 daniel-mar 488
                if ($this->isRoot()) return $this->ns();
489
                return $this->getLegacyDirectoryName();
513 daniel-mar 490
        }
491
 
514 daniel-mar 492
        public final function getLegacyDirectoryName() {
513 daniel-mar 493
                if ($this::ns() == 'oid') {
494
                        $oid = $this->nodeId(false);
495
                } else {
496
                        $oid = null;
497
                        $alt_ids = $this->getAltIds();
498
                        foreach ($alt_ids as $alt_id) {
499
                                if ($alt_id->getNamespace() == 'oid') {
500
                                        $oid = $alt_id->getId();
501
                                        break; // we prefer the first OID (for GUIDs, the first OID is the OIDplus-OID, and the second OID is the UUID OID)
502
                                }
503
                        }
504
                }
505
 
506
                if (!is_null($oid) && ($oid != '')) {
507
                        // For OIDs, it is the OID, for other identifiers
508
                        // it it the OID alt ID (generated using the SystemID)
509
                        return str_replace('.', '_', $oid);
510
                } else {
511
                        // Can happen if you don't have a system ID (due to missing OpenSSL plugin)
512
                        return md5($this->nodeId(true)); // we don't use $id, because $this->nodeId(true) is possibly more canonical than $id
513
                }
514
        }
415 daniel-mar 515
}