Rev 1454 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1454 | Rev 1461 | ||
---|---|---|---|
1 | <?php |
1 | <?php |
2 | 2 | ||
3 | /* |
3 | /* |
4 | * OIDplus 2.0 |
4 | * OIDplus 2.0 |
5 | * Copyright 2019 - 2023 Daniel Marschall, ViaThinkSoft |
5 | * Copyright 2019 - 2023 Daniel Marschall, ViaThinkSoft |
6 | * |
6 | * |
7 | * Licensed under the Apache License, Version 2.0 (the "License"); |
7 | * Licensed under the Apache License, Version 2.0 (the "License"); |
8 | * you may not use this file except in compliance with 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 |
9 | * You may obtain a copy of the License at |
10 | * |
10 | * |
11 | * http://www.apache.org/licenses/LICENSE-2.0 |
11 | * http://www.apache.org/licenses/LICENSE-2.0 |
12 | * |
12 | * |
13 | * Unless required by applicable law or agreed to in writing, software |
13 | * Unless required by applicable law or agreed to in writing, software |
14 | * distributed under the License is distributed on an "AS IS" BASIS, |
14 | * distributed under the License is distributed on an "AS IS" BASIS, |
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
16 | * See the License for the specific language governing permissions and |
16 | * See the License for the specific language governing permissions and |
17 | * limitations under the License. |
17 | * limitations under the License. |
18 | */ |
18 | */ |
19 | 19 | ||
20 | namespace ViaThinkSoft\OIDplus; |
20 | namespace ViaThinkSoft\OIDplus; |
21 | 21 | ||
22 | // phpcs:disable PSR1.Files.SideEffects |
22 | // phpcs:disable PSR1.Files.SideEffects |
23 | \defined('INSIDE_OIDPLUS') or die; |
23 | \defined('INSIDE_OIDPLUS') or die; |
24 | // phpcs:enable PSR1.Files.SideEffects |
24 | // phpcs:enable PSR1.Files.SideEffects |
25 | 25 | ||
26 | abstract class OIDplusObject extends OIDplusBaseClass { |
26 | abstract class OIDplusObject extends OIDplusBaseClass { |
27 | 27 | ||
28 | /** |
28 | /** |
29 | * |
29 | * |
30 | */ |
30 | */ |
31 | //const UUID_NAMEBASED_NS_OidPlusMisc = 'ad1654e6-7e15-11e4-9ef6-78e3b5fc7f22'; |
31 | //const UUID_NAMEBASED_NS_OidPlusMisc = 'ad1654e6-7e15-11e4-9ef6-78e3b5fc7f22'; |
32 | 32 | ||
33 | /** |
33 | /** |
34 | * Please overwrite this function! |
34 | * Please overwrite this function! |
35 | * @param string $node_id |
35 | * @param string $node_id |
36 | * @return OIDplusObject|null |
36 | * @return OIDplusObject|null |
37 | */ |
37 | */ |
38 | public static function parse(string $node_id)/*: ?OIDplusObject*/ { |
38 | public static function parse(string $node_id)/*: ?OIDplusObject*/ { |
39 | foreach (OIDplus::getEnabledObjectTypes() as $ot) { |
39 | foreach (OIDplus::getEnabledObjectTypes() as $ot) { |
40 | try { |
40 | try { |
41 | $good = false; |
41 | $good = false; |
42 | if (get_parent_class($ot) == OIDplusObject::class) { |
42 | if (get_parent_class($ot) == OIDplusObject::class) { |
43 | $reflector = new \ReflectionMethod($ot, 'parse'); |
43 | $reflector = new \ReflectionMethod($ot, 'parse'); |
44 | $isImplemented = ($reflector->getDeclaringClass()->getName() === $ot); |
44 | $isImplemented = ($reflector->getDeclaringClass()->getName() === $ot); |
45 | if ($isImplemented) { // avoid endless loop if parse is not overriden |
45 | if ($isImplemented) { // avoid endless loop if parse is not overriden |
46 | $good = true; |
46 | $good = true; |
47 | } |
47 | } |
48 | } |
48 | } |
49 | // We need to do the workaround with "$good", otherwise PHPstan shows |
49 | // We need to do the workaround with "$good", otherwise PHPstan shows |
50 | // "Call to an undefined static method object::parse()" |
50 | // "Call to an undefined static method object::parse()" |
51 | if ($good && $obj = $ot::parse($node_id)) return $obj; |
51 | if ($good && $obj = $ot::parse($node_id)) return $obj; |
52 | } catch (\Exception $e) {} |
52 | } catch (\Exception $e) {} |
53 | } |
53 | } |
54 | return null; |
54 | return null; |
55 | } |
55 | } |
56 | 56 | ||
57 | /** |
57 | /** |
58 | * @return OIDplusAltId[] |
58 | * @return OIDplusAltId[] |
59 | * @throws OIDplusException |
59 | * @throws OIDplusException |
60 | */ |
60 | */ |
61 | public function getAltIds(): array { |
61 | public function getAltIds(): array { |
62 | if ($this->isRoot()) return array(); |
62 | if ($this->isRoot()) return array(); |
63 | 63 | ||
64 | $ids = array(); |
64 | $ids = array(); |
65 | 65 | ||
66 | // Create Information Object OID/AID/UUID |
66 | // Create Information Object OID/AID/UUID |
67 | // ... but not for OIDs below oid:1.3.6.1.4.1.37476.30.9, because these are the definition of these Information Object AID/OID/UUID (which will be decoded in the OID object type plugin) |
67 | // ... but not for OIDs below oid:1.3.6.1.4.1.37476.30.9, because these are the definition of these Information Object AID/OID/UUID (which will be decoded in the OID object type plugin) |
68 | if (!str_starts_with($this->nodeId(true), 'oid:1.3.6.1.4.1.37476.30.9.')) { |
68 | if (!str_starts_with($this->nodeId(true), 'oid:1.3.6.1.4.1.37476.30.9.')) { |
69 | // Creates an OIDplus-Hash-OID |
69 | // Creates an OIDplus-Hash-OID |
70 | // ... exclude OIDs, because an OID is already an OID |
70 | // ... exclude OIDs, because an OID is already an OID |
71 | if ($this->ns() != 'oid') { |
71 | if ($this->ns() != 'oid') { |
72 | $sid = OIDplus::getSystemId(true); |
72 | $sid = OIDplus::getSystemId(true); |
73 | if (!empty($sid)) { |
73 | if (!empty($sid)) { |
74 | $ns_oid = $this->getPlugin()->getManifest()->getOid(); |
74 | $ns_oid = $this->getPlugin()->getManifest()->getOid(); |
75 | $hash_payload = $ns_oid.':'.$this->nodeId(false); |
75 | $hash_payload = $ns_oid.':'.$this->nodeId(false); |
76 | $oid = $sid . '.' . smallhash($hash_payload); |
76 | $oid = $sid . '.' . smallhash($hash_payload); |
77 | $ids[] = new OIDplusAltId('oid', $oid, _L('OIDplus Information Object OID')); |
77 | $ids[] = new OIDplusAltId('oid', $oid, _L('OIDplus Information Object OID')); |
78 | } |
78 | } |
79 | } |
79 | } |
80 | 80 | ||
81 | // Make a OIDplus-UUID, but... |
81 | // Make a OIDplus-UUID, but... |
82 | // ... exclude GUID, because a GUID is already a GUID |
82 | // ... exclude GUID, because a GUID is already a GUID |
83 | // ... exclude OIDs which are 2.25, because these are basically GUIDs (but 2nd, 3rd, 4th, ... level is OK) |
83 | // ... exclude OIDs which are 2.25, because these are basically GUIDs (but 2nd, 3rd, 4th, ... level is OK) |
84 | // Previously, we excluded OID, because an OID already has a record UUID_NAMEBASED_NS_OID (defined by IETF) set by class OIDplusOid |
84 | // Previously, we excluded OID, because an OID already has a record UUID_NAMEBASED_NS_OID (defined by IETF) set by class OIDplusOid |
85 | if (($this->ns() != 'guid') && ($this->ns() != 'oid' || $this->one_up()->nodeId(true) != 'oid:2.25') /*&& ($this->ns() != 'oid')*/) { |
85 | if (($this->ns() != 'guid') && ($this->ns() != 'oid' || $this->one_up()->nodeId(true) != 'oid:2.25') /*&& ($this->ns() != 'oid')*/) { |
86 | // Obsolete custom namespace for UUIDv3 and UUIDv5: |
86 | // Obsolete custom namespace for UUIDv3 and UUIDv5: |
87 | //$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')); |
87 | //$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')); |
88 | //$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')); |
88 | //$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')); |
89 | // New custom UUIDv8: |
89 | // New custom UUIDv8: |
90 | $sysid = OIDplus::getSystemId(false); |
90 | $sysid = OIDplus::getSystemId(false); |
91 | $sysid_int = $sysid ? $sysid : 0; |
91 | $sysid_int = $sysid ? $sysid : 0; |
92 | $unix_ts = $this->getCreatedTime() ? strtotime($this->getCreatedTime()) : 0; |
92 | $unix_ts = $this->getCreatedTime() ? strtotime($this->getCreatedTime()) : 0; |
93 | $ns_oid = $this->getPlugin()->getManifest()->getOid(); |
93 | $ns_oid = $this->getPlugin()->getManifest()->getOid(); |
94 | $obj_name = $this->nodeId(false); |
94 | $obj_name = $this->nodeId(false); |
95 | $ids[] = new OIDplusAltId('guid', |
95 | $ids[] = new OIDplusAltId('guid', |
96 | gen_uuid_v8( |
96 | gen_uuid_v8( |
97 | dechex($sysid_int), |
97 | dechex($sysid_int), |
98 | dechex((int)round($unix_ts/60/60/24)), |
98 | dechex((int)round($unix_ts/60/60/24)), |
99 | dechex(0), |
99 | dechex(0), |
100 | sha1($ns_oid), // Note: No 14bit collission between 1.3.6.1.4.1.37476.2.5.2.4.8.[0-185] |
100 | sha1($ns_oid), // Note: No 14bit collission between 1.3.6.1.4.1.37476.2.5.2.4.8.[0-185] |
101 | sha1($obj_name) |
101 | sha1($obj_name) |
102 | ), |
102 | ), |
103 | _L('OIDplus Information Object Custom UUID (RFC4122bis)'), |
103 | _L('OIDplus Information Object Custom UUID (RFC4122bis)'), |
104 | '', |
104 | '', |
105 | 'https://github.com/danielmarschall/oidplus/blob/master/doc/oidplus_custom_guid.md' |
105 | 'https://github.com/danielmarschall/oidplus/blob/master/doc/oidplus_custom_guid.md' |
106 | ); |
106 | ); |
107 | } |
107 | } |
108 | 108 | ||
109 | // Make a AID based on ViaThinkSoft schema |
109 | // Make a AID based on ViaThinkSoft schema |
110 | // ... exclude AIDs, because an AID is already an AID |
110 | // ... exclude AIDs, because an AID is already an AID |
111 | if ($this->ns() != 'aid') { |
111 | if ($this->ns() != 'aid') { |
112 | $sid = OIDplus::getSystemId(false); |
112 | $sid = OIDplus::getSystemId(false); |
113 | if ($sid !== false) { |
113 | if ($sid !== false) { |
114 | $ns_oid = $this->getPlugin()->getManifest()->getOid(); |
114 | $ns_oid = $this->getPlugin()->getManifest()->getOid(); |
115 | $hash_payload = $ns_oid.':'.$this->nodeId(false); |
115 | $hash_payload = $ns_oid.':'.$this->nodeId(false); |
116 | $sid_hex = strtoupper(str_pad(dechex((int)$sid),8,'0',STR_PAD_LEFT)); |
116 | $sid_hex = strtoupper(str_pad(dechex((int)$sid),8,'0',STR_PAD_LEFT)); |
117 | $obj_hex = strtoupper(str_pad(dechex(smallhash($hash_payload)),8,'0',STR_PAD_LEFT)); |
117 | $obj_hex = strtoupper(str_pad(dechex(smallhash($hash_payload)),8,'0',STR_PAD_LEFT)); |
118 | $aid = 'D276000186B20005'.$sid_hex.$obj_hex; |
118 | $aid = 'D276000186B20005'.$sid_hex.$obj_hex; |
119 | $ids[] = new OIDplusAltId('aid', $aid, |
119 | $ids[] = new OIDplusAltId('aid', $aid, |
120 | _L('OIDplus Information Object Application Identifier (ISO/IEC 7816)'), |
120 | _L('OIDplus Information Object Application Identifier (ISO/IEC 7816)'), |
121 | ' ('._L('No PIX allowed').')', |
121 | ' ('._L('No PIX allowed').')', |
122 | 'https://hosted.oidplus.com/viathinksoft/?goto=aid%3AD276000186B20005'); |
122 | 'https://hosted.oidplus.com/viathinksoft/?goto=aid%3AD276000186B20005'); |
123 | } |
123 | } |
124 | } |
124 | } |
125 | 125 | ||
126 | // Make a MAC based on AAI (not 100% worldwide unique!) |
126 | // Make a MAC based on AAI (not 100% worldwide unique!) |
127 | // ... exclude MACs, because an MAC is already a MAC |
127 | // ... exclude MACs, because an MAC is already a MAC |
128 | if ($this->ns() != 'mac') { |
128 | if ($this->ns() != 'mac') { |
129 | $ns_oid = $this->getPlugin()->getManifest()->getOid(); |
129 | $ns_oid = $this->getPlugin()->getManifest()->getOid(); |
130 | $obj_name = $this->nodeId(false); |
130 | $obj_name = $this->nodeId(false); |
131 | $mac = strtoupper(substr(sha1($ns_oid.':'.$obj_name),-12)); |
131 | $mac = strtoupper(substr(sha1($ns_oid.':'.$obj_name),-12)); |
132 | $mac = rtrim(chunk_split($mac, 2, '-'),'-'); |
132 | $mac = rtrim(chunk_split($mac, 2, '-'),'-'); |
133 | 133 | ||
134 | $mac[1] = '2'; // 2=AAI Unicast |
134 | $mac[1] = '2'; // 2=AAI Unicast |
135 | $ids[] = new OIDplusAltId('mac', $mac, _L('OIDplus Information Object MAC address, Unicast (AAI)')); |
135 | $ids[] = new OIDplusAltId('mac', $mac, _L('OIDplus Information Object MAC address, Unicast (AAI)')); |
136 | 136 | ||
137 | $mac[1] = '3'; // 3=AAI Multicast |
137 | $mac[1] = '3'; // 3=AAI Multicast |
138 | $ids[] = new OIDplusAltId('mac', $mac, _L('OIDplus Information Object MAC address, Multicast (AAI)')); |
138 | $ids[] = new OIDplusAltId('mac', $mac, _L('OIDplus Information Object MAC address, Multicast (AAI)')); |
139 | } |
139 | } |
140 | 140 | ||
141 | // Make a DN based on DN |
141 | // Make a DN based on DN |
142 | // ... exclude DN, because an DN is already a DN |
142 | // ... exclude DN, because an DN is already a DN |
143 | if ($this->ns() != 'x500dn') { |
143 | if ($this->ns() != 'x500dn') { |
144 | $sysid = OIDplus::getSystemId(false); |
144 | $sysid = OIDplus::getSystemId(false); |
145 | if ($sysid !== false) { |
145 | if ($sysid !== false) { |
146 | $ns_oid = $this->getPlugin()->getManifest()->getOid(); |
146 | $ns_oid = $this->getPlugin()->getManifest()->getOid(); |
147 | $hash_payload = $ns_oid.':'.$this->nodeId(false); |
147 | $hash_payload = $ns_oid.':'.$this->nodeId(false); |
148 | $objhash = smallhash($hash_payload); |
148 | $objhash = smallhash($hash_payload); |
149 | 149 | ||
150 | $oid_at_sysid = '1.3.6.1.4.1.37476.2.5.2.9.4.1'; |
150 | $oid_at_sysid = '1.3.6.1.4.1.37476.2.5.2.9.4.1'; |
151 | $oid_at_objhash = '1.3.6.1.4.1.37476.2.5.2.9.4.2'; |
151 | $oid_at_objhash = '1.3.6.1.4.1.37476.2.5.2.9.4.2'; |
152 | $dn = '/dc=com/dc=example/cn=oidplus/'.$oid_at_sysid.'='.$sysid.'/'.$oid_at_objhash.'='.$objhash; |
152 | $dn = '/dc=com/dc=example/cn=oidplus/'.$oid_at_sysid.'='.$sysid.'/'.$oid_at_objhash.'='.$objhash; |
153 | 153 | ||
154 | $ids[] = new OIDplusAltId('x500dn', $dn, _L('OIDplus Information Object X.500 DN')); |
154 | $ids[] = new OIDplusAltId('x500dn', $dn, _L('OIDplus Information Object X.500 DN')); |
155 | } |
155 | } |
156 | } |
156 | } |
157 | } |
157 | } |
158 | 158 | ||
159 | return $ids; |
159 | return $ids; |
160 | } |
160 | } |
161 | 161 | ||
162 | /** |
162 | /** |
163 | * @return string |
163 | * @return string |
164 | */ |
164 | */ |
165 | public abstract static function objectTypeTitle(): string; |
165 | public abstract static function objectTypeTitle(): string; |
166 | 166 | ||
167 | /** |
167 | /** |
168 | * @return string |
168 | * @return string |
169 | */ |
169 | */ |
170 | public abstract static function objectTypeTitleShort(): string; |
170 | public abstract static function objectTypeTitleShort(): string; |
171 | 171 | ||
172 | /** |
172 | /** |
173 | * @return OIDplusObjectTypePlugin|null |
173 | * @return OIDplusObjectTypePlugin|null |
174 | */ |
174 | */ |
175 | public function getPlugin()/*: ?OIDplusObjectTypePlugin */ { |
175 | public function getPlugin()/*: ?OIDplusObjectTypePlugin */ { |
176 | $plugins = OIDplus::getObjectTypePlugins(); |
176 | $plugins = OIDplus::getObjectTypePlugins(); |
177 | foreach ($plugins as $plugin) { |
177 | foreach ($plugins as $plugin) { |
178 | if (get_class($this) == $plugin::getObjectTypeClassName()) { |
178 | if (get_class($this) == $plugin::getObjectTypeClassName()) { |
179 | return $plugin; |
179 | return $plugin; |
180 | } |
180 | } |
181 | } |
181 | } |
182 | return null; |
182 | return null; |
183 | } |
183 | } |
184 | 184 | ||
185 | /** |
185 | /** |
186 | * @return string |
186 | * @return string |
187 | */ |
187 | */ |
188 | public abstract static function ns(): string; |
188 | public abstract static function ns(): string; |
189 | 189 | ||
190 | /** |
190 | /** |
191 | * @return string |
191 | * @return string |
192 | */ |
192 | */ |
193 | public abstract static function root(): string; |
193 | public abstract static function root(): string; |
194 | 194 | ||
195 | /** |
195 | /** |
196 | * @return bool |
196 | * @return bool |
197 | */ |
197 | */ |
198 | public abstract function isRoot(): bool; |
198 | public abstract function isRoot(): bool; |
199 | 199 | ||
200 | /** |
200 | /** |
201 | * @param bool $with_ns |
201 | * @param bool $with_ns |
202 | * @return string |
202 | * @return string |
203 | */ |
203 | */ |
204 | public abstract function nodeId(bool $with_ns=true): string; |
204 | public abstract function nodeId(bool $with_ns=true): string; |
205 | 205 | ||
206 | /** |
206 | /** |
207 | * @param string $str |
207 | * @param string $str |
208 | * @return string mixed |
208 | * @return string mixed |
209 | * @throws OIDplusException |
209 | * @throws OIDplusException |
210 | */ |
210 | */ |
211 | public abstract function addString(string $str): string; |
211 | public abstract function addString(string $str): string; |
212 | 212 | ||
213 | /** |
213 | /** |
214 | * @param OIDplusObject $parent |
214 | * @param OIDplusObject $parent |
215 | * @return string |
215 | * @return string |
216 | */ |
216 | */ |
217 | public abstract function crudShowId(OIDplusObject $parent): string; |
217 | public abstract function crudShowId(OIDplusObject $parent): string; |
218 | 218 | ||
219 | /** |
219 | /** |
220 | * @return string |
220 | * @return string |
221 | */ |
221 | */ |
222 | public function crudInsertPrefix(): string { |
222 | public function crudInsertPrefix(): string { |
223 | return ''; |
223 | return ''; |
224 | } |
224 | } |
225 | 225 | ||
226 | /** |
226 | /** |
227 | * @return string |
227 | * @return string |
228 | */ |
228 | */ |
229 | public function crudInsertSuffix(): string { |
229 | public function crudInsertSuffix(): string { |
230 | return ''; |
230 | return ''; |
231 | } |
231 | } |
232 | 232 | ||
233 | /** |
233 | /** |
234 | * @param OIDplusObject|null $parent |
234 | * @param OIDplusObject|null $parent |
235 | * @return string |
235 | * @return string |
236 | */ |
236 | */ |
237 | public abstract function jsTreeNodeName(OIDplusObject $parent = null): string; |
237 | public abstract function jsTreeNodeName(OIDplusObject $parent = null): string; |
238 | 238 | ||
239 | /** |
239 | /** |
240 | * @return string |
240 | * @return string |
241 | */ |
241 | */ |
242 | public abstract function defaultTitle(): string; |
242 | public abstract function defaultTitle(): string; |
243 | 243 | ||
244 | /** |
244 | /** |
245 | * @return bool |
245 | * @return bool |
246 | */ |
246 | */ |
247 | public abstract function isLeafNode(): bool; |
247 | public abstract function isLeafNode(): bool; |
248 | 248 | ||
249 | /** |
249 | /** |
250 | * @param string $title |
250 | * @param string $title |
251 | * @param string $content |
251 | * @param string $content |
252 | * @param string $icon |
252 | * @param string $icon |
253 | * @return void |
253 | * @return void |
254 | */ |
254 | */ |
255 | public abstract function getContentPage(string &$title, string &$content, string &$icon); |
255 | public abstract function getContentPage(string &$title, string &$content, string &$icon); |
256 | 256 | ||
257 | /** |
257 | /** |
258 | * @param OIDplusRA|string|null $ra |
258 | * @param OIDplusRA|string|null $ra |
259 | * @return array |
259 | * @return array |
260 | * @throws OIDplusConfigInitializationException |
260 | * @throws OIDplusConfigInitializationException |
261 | * @throws OIDplusException |
261 | * @throws OIDplusException |
262 | */ |
262 | */ |
263 | public static function getRaRoots($ra=null) : array{ |
263 | public static function getRaRoots($ra=null) : array{ |
264 | if ($ra instanceof OIDplusRA) $ra = $ra->raEmail(); |
264 | if ($ra instanceof OIDplusRA) $ra = $ra->raEmail(); |
265 | 265 | ||
266 | $out = array(); |
266 | $out = array(); |
267 | 267 | ||
268 | if (!OIDplus::baseConfig()->getValue('OBJECT_CACHING', true)) { |
268 | if (!OIDplus::baseConfig()->getValue('OBJECT_CACHING', true)) { |
269 | if (!$ra) { |
269 | if (!$ra) { |
270 | $res = OIDplus::db()->query("select oChild.id as child_id, oChild.ra_email as child_mail, oParent.ra_email as parent_mail from ###objects as oChild ". |
270 | $res = OIDplus::db()->query("select oChild.id as child_id, oChild.ra_email as child_mail, oParent.ra_email as parent_mail from ###objects as oChild ". |
271 | "left join ###objects as oParent on oChild.parent = oParent.id"); |
271 | "left join ###objects as oParent on oChild.parent = oParent.id"); |
272 | $res->naturalSortByField('child_id'); |
272 | $res->naturalSortByField('child_id'); |
273 | while ($row = $res->fetch_array()) { |
273 | while ($row = $res->fetch_array()) { |
274 | if (!OIDplus::authUtils()->isRaLoggedIn($row['parent_mail']) && OIDplus::authUtils()->isRaLoggedIn($row['child_mail'])) { |
274 | if (!OIDplus::authUtils()->isRaLoggedIn($row['parent_mail']) && OIDplus::authUtils()->isRaLoggedIn($row['child_mail'])) { |
275 | $x = self::parse($row['child_id']); // can be NULL if namespace was disabled |
275 | $x = self::parse($row['child_id']); // can be NULL if namespace was disabled |
276 | if ($x) $out[] = $x; |
276 | if ($x) $out[] = $x; |
277 | } |
277 | } |
278 | } |
278 | } |
279 | } else { |
279 | } else { |
280 | $res = OIDplus::db()->query("select oChild.id as child_id from ###objects as oChild ". |
280 | $res = OIDplus::db()->query("select oChild.id as child_id from ###objects as oChild ". |
281 | "left join ###objects as oParent on oChild.parent = oParent.id ". |
281 | "left join ###objects as oParent on oChild.parent = oParent.id ". |
282 | "where (".OIDplus::db()->getSlang()->isNullFunction('oParent.ra_email',"''")." <> ? and ". |
282 | "where (".OIDplus::db()->getSlang()->isNullFunction('oParent.ra_email',"''")." <> ? and ". |
283 | OIDplus::db()->getSlang()->isNullFunction('oChild.ra_email',"''")." = ?) or ". |
283 | OIDplus::db()->getSlang()->isNullFunction('oChild.ra_email',"''")." = ?) or ". |
284 | " (oParent.ra_email is null and ".OIDplus::db()->getSlang()->isNullFunction('oChild.ra_email',"''")." = ?) ", |
284 | " (oParent.ra_email is null and ".OIDplus::db()->getSlang()->isNullFunction('oChild.ra_email',"''")." = ?) ", |
285 | array($ra, $ra, $ra)); |
285 | array($ra, $ra, $ra)); |
286 | $res->naturalSortByField('child_id'); |
286 | $res->naturalSortByField('child_id'); |
287 | while ($row = $res->fetch_array()) { |
287 | while ($row = $res->fetch_array()) { |
288 | $x = self::parse($row['child_id']); // can be NULL if namespace was disabled |
288 | $x = self::parse($row['child_id']); // can be NULL if namespace was disabled |
289 | if ($x) $out[] = $x; |
289 | if ($x) $out[] = $x; |
290 | } |
290 | } |
291 | } |
291 | } |
292 | } else { |
292 | } else { |
293 | if (!$ra) { |
293 | if (!$ra) { |
294 | $ra_mails_to_check = OIDplus::authUtils()->loggedInRaList(); |
294 | $ra_mails_to_check = OIDplus::authUtils()->loggedInRaList(); |
295 | if (count($ra_mails_to_check) == 0) return $out; |
295 | if (count($ra_mails_to_check) == 0) return $out; |
296 | } else { |
296 | } else { |
297 | $ra_mails_to_check = array($ra); |
297 | $ra_mails_to_check = array($ra); |
298 | } |
298 | } |
299 | 299 | ||
300 | self::buildObjectInformationCache(); |
300 | self::buildObjectInformationCache(); |
301 | 301 | ||
302 | foreach ($ra_mails_to_check as $check_ra_mail) { |
302 | foreach ($ra_mails_to_check as $check_ra_mail) { |
303 | $out_part = array(); |
303 | $out_part = array(); |
304 | 304 | ||
305 | foreach (self::$object_info_cache as $id => $cacheitem) { |
305 | foreach (self::$object_info_cache as $id => $cacheitem) { |
306 | if ($cacheitem[self::CACHE_RA_EMAIL] == $check_ra_mail) { |
306 | if ($cacheitem[self::CACHE_RA_EMAIL] == $check_ra_mail) { |
307 | $parent = $cacheitem[self::CACHE_PARENT]; |
307 | $parent = $cacheitem[self::CACHE_PARENT]; |
308 | if (!isset(self::$object_info_cache[$parent]) || (self::$object_info_cache[$parent][self::CACHE_RA_EMAIL] != $check_ra_mail)) { |
308 | if (!isset(self::$object_info_cache[$parent]) || (self::$object_info_cache[$parent][self::CACHE_RA_EMAIL] != $check_ra_mail)) { |
309 | $out_part[] = $id; |
309 | $out_part[] = $id; |
310 | } |
310 | } |
311 | } |
311 | } |
312 | } |
312 | } |
313 | 313 | ||
314 | natsort($out_part); |
314 | natsort($out_part); |
315 | 315 | ||
316 | foreach ($out_part as $id) { |
316 | foreach ($out_part as $id) { |
317 | $obj = self::parse($id); |
317 | $obj = self::parse($id); |
318 | if ($obj) $out[] = $obj; |
318 | if ($obj) $out[] = $obj; |
319 | } |
319 | } |
320 | } |
320 | } |
321 | } |
321 | } |
322 | 322 | ||
323 | return $out; |
323 | return $out; |
324 | } |
324 | } |
325 | 325 | ||
326 | /** |
326 | /** |
327 | * @return array |
327 | * @return array |
328 | * @throws OIDplusException |
328 | * @throws OIDplusException |
329 | */ |
329 | */ |
330 | public static function getAllNonConfidential(): array { |
330 | public static function getAllNonConfidential(): array { |
331 | $out = array(); |
331 | $out = array(); |
332 | 332 | ||
333 | if (!OIDplus::baseConfig()->getValue('OBJECT_CACHING', true)) { |
333 | if (!OIDplus::baseConfig()->getValue('OBJECT_CACHING', true)) { |
334 | $res = OIDplus::db()->query("select id from ###objects where confidential = ?", array(false)); |
334 | $res = OIDplus::db()->query("select id from ###objects where confidential = ?", array(false)); |
335 | $res->naturalSortByField('id'); |
335 | $res->naturalSortByField('id'); |
336 | while ($row = $res->fetch_array()) { |
336 | while ($row = $res->fetch_array()) { |
337 | $obj = self::parse($row['id']); // will be NULL if the object type is not registered |
337 | $obj = self::parse($row['id']); // will be NULL if the object type is not registered |
338 | if ($obj && (!$obj->isConfidential())) { |
338 | if ($obj && (!$obj->isConfidential())) { |
339 | $out[] = $row['id']; |
339 | $out[] = $row['id']; |
340 | } |
340 | } |
341 | } |
341 | } |
342 | } else { |
342 | } else { |
343 | self::buildObjectInformationCache(); |
343 | self::buildObjectInformationCache(); |
344 | 344 | ||
345 | foreach (self::$object_info_cache as $id => $cacheitem) { |
345 | foreach (self::$object_info_cache as $id => $cacheitem) { |
346 | $confidential = $cacheitem[self::CACHE_CONFIDENTIAL]; |
346 | $confidential = $cacheitem[self::CACHE_CONFIDENTIAL]; |
347 | if (!$confidential) { |
347 | if (!$confidential) { |
348 | $obj = self::parse($id); // will be NULL if the object type is not registered |
348 | $obj = self::parse($id); // will be NULL if the object type is not registered |
349 | if ($obj && (!$obj->isConfidential())) { |
349 | if ($obj && (!$obj->isConfidential())) { |
350 | $out[] = $id; |
350 | $out[] = $id; |
351 | } |
351 | } |
352 | } |
352 | } |
353 | } |
353 | } |
354 | } |
354 | } |
355 | 355 | ||
356 | return $out; |
356 | return $out; |
357 | } |
357 | } |
358 | 358 | ||
359 | /** |
359 | /** |
360 | * @return bool |
360 | * @return bool |
361 | * @throws OIDplusException |
361 | * @throws OIDplusException |
362 | */ |
362 | */ |
363 | public function isConfidential(): bool { |
363 | public function isConfidential(): bool { |
364 | if (!OIDplus::baseConfig()->getValue('OBJECT_CACHING', true)) { |
364 | if (!OIDplus::baseConfig()->getValue('OBJECT_CACHING', true)) { |
365 | //static $confidential_cache = array(); |
365 | //static $confidential_cache = array(); |
366 | $curid = $this->nodeId(); |
366 | $curid = $this->nodeId(); |
367 | //$orig_curid = $curid; |
367 | //$orig_curid = $curid; |
368 | //if (isset($confidential_cache[$curid])) return $confidential_cache[$curid]; |
368 | //if (isset($confidential_cache[$curid])) return $confidential_cache[$curid]; |
369 | // Recursively search for the confidential flag in the parents |
369 | // Recursively search for the confidential flag in the parents |
370 | while (($res = OIDplus::db()->query("select parent, confidential from ###objects where id = ?", array($curid)))->any()) { |
370 | while (($res = OIDplus::db()->query("select parent, confidential from ###objects where id = ?", array($curid)))->any()) { |
371 | $row = $res->fetch_array(); |
371 | $row = $res->fetch_array(); |
372 | if ($row['confidential']) { |
372 | if ($row['confidential']) { |
373 | //$confidential_cache[$curid] = true; |
373 | //$confidential_cache[$curid] = true; |
374 | //$confidential_cache[$orig_curid] = true; |
374 | //$confidential_cache[$orig_curid] = true; |
375 | return true; |
375 | return true; |
376 | } else { |
376 | } else { |
377 | //$confidential_cache[$curid] = false; |
377 | //$confidential_cache[$curid] = false; |
378 | } |
378 | } |
379 | $curid = $row['parent']; |
379 | $curid = $row['parent']; |
380 | //if (isset($confidential_cache[$curid])) { |
380 | //if (isset($confidential_cache[$curid])) { |
381 | //$confidential_cache[$orig_curid] = $confidential_cache[$curid]; |
381 | //$confidential_cache[$orig_curid] = $confidential_cache[$curid]; |
382 | //return $confidential_cache[$curid]; |
382 | //return $confidential_cache[$curid]; |
383 | //} |
383 | //} |
384 | } |
384 | } |
385 | 385 | ||
386 | //$confidential_cache[$orig_curid] = false; |
386 | //$confidential_cache[$orig_curid] = false; |
387 | return false; |
387 | return false; |
388 | } else { |
388 | } else { |
389 | self::buildObjectInformationCache(); |
389 | self::buildObjectInformationCache(); |
390 | 390 | ||
391 | $curid = $this->nodeId(); |
391 | $curid = $this->nodeId(); |
392 | // Recursively search for the confidential flag in the parents |
392 | // Recursively search for the confidential flag in the parents |
393 | while (isset(self::$object_info_cache[$curid])) { |
393 | while (isset(self::$object_info_cache[$curid])) { |
394 | if (self::$object_info_cache[$curid][self::CACHE_CONFIDENTIAL]) return true; |
394 | if (self::$object_info_cache[$curid][self::CACHE_CONFIDENTIAL]) return true; |
395 | $curid = self::$object_info_cache[$curid][self::CACHE_PARENT]; |
395 | $curid = self::$object_info_cache[$curid][self::CACHE_PARENT]; |
396 | } |
396 | } |
397 | return false; |
397 | return false; |
398 | } |
398 | } |
399 | } |
399 | } |
400 | 400 | ||
401 | /** |
401 | /** |
402 | * @param OIDplusObject $obj |
402 | * @param OIDplusObject $obj |
403 | * @return bool |
403 | * @return bool |
404 | * @throws OIDplusException |
404 | * @throws OIDplusException |
405 | */ |
405 | */ |
406 | public function isChildOf(OIDplusObject $obj): bool { |
406 | public function isChildOf(OIDplusObject $obj): bool { |
407 | if (!OIDplus::baseConfig()->getValue('OBJECT_CACHING', true)) { |
407 | if (!OIDplus::baseConfig()->getValue('OBJECT_CACHING', true)) { |
408 | $curid = $this->nodeId(); |
408 | $curid = $this->nodeId(); |
409 | while (($res = OIDplus::db()->query("select parent from ###objects where id = ?", array($curid)))->any()) { |
409 | while (($res = OIDplus::db()->query("select parent from ###objects where id = ?", array($curid)))->any()) { |
410 | $row = $res->fetch_array(); |
410 | $row = $res->fetch_array(); |
411 | if ($curid == $obj->nodeId()) return true; |
411 | if ($curid == $obj->nodeId()) return true; |
412 | $curid = $row['parent']; |
412 | $curid = $row['parent']; |
413 | } |
413 | } |
414 | return false; |
414 | return false; |
415 | } else { |
415 | } else { |
416 | self::buildObjectInformationCache(); |
416 | self::buildObjectInformationCache(); |
417 | 417 | ||
418 | $curid = $this->nodeId(); |
418 | $curid = $this->nodeId(); |
419 | while (isset(self::$object_info_cache[$curid])) { |
419 | while (isset(self::$object_info_cache[$curid])) { |
420 | if ($curid == $obj->nodeId()) return true; |
420 | if ($curid == $obj->nodeId()) return true; |
421 | $curid = self::$object_info_cache[$curid][self::CACHE_PARENT]; |
421 | $curid = self::$object_info_cache[$curid][self::CACHE_PARENT]; |
422 | } |
422 | } |
423 | return false; |
423 | return false; |
424 | } |
424 | } |
425 | } |
425 | } |
426 | 426 | ||
427 | /** |
427 | /** |
428 | * @return array |
428 | * @return array |
429 | * @throws OIDplusException |
429 | * @throws OIDplusException |
430 | */ |
430 | */ |
431 | public function getChildren(): array { |
431 | public function getChildren(): array { |
432 | $out = array(); |
432 | $out = array(); |
433 | if (!OIDplus::baseConfig()->getValue('OBJECT_CACHING', true)) { |
433 | if (!OIDplus::baseConfig()->getValue('OBJECT_CACHING', true)) { |
434 | $res = OIDplus::db()->query("select id from ###objects where parent = ?", array($this->nodeId())); |
434 | $res = OIDplus::db()->query("select id from ###objects where parent = ?", array($this->nodeId())); |
435 | while ($row = $res->fetch_array()) { |
435 | while ($row = $res->fetch_array()) { |
436 | $obj = self::parse($row['id']); |
436 | $obj = self::parse($row['id']); |
437 | if (!$obj) continue; |
437 | if (!$obj) continue; |
438 | $out[] = $obj; |
438 | $out[] = $obj; |
439 | } |
439 | } |
440 | } else { |
440 | } else { |
441 | self::buildObjectInformationCache(); |
441 | self::buildObjectInformationCache(); |
442 | 442 | ||
443 | foreach (self::$object_info_cache as $id => $cacheitem) { |
443 | foreach (self::$object_info_cache as $id => $cacheitem) { |
444 | $parent = $cacheitem[self::CACHE_PARENT]; |
444 | $parent = $cacheitem[self::CACHE_PARENT]; |
445 | if ($parent == $this->nodeId()) { |
445 | if ($parent == $this->nodeId()) { |
446 | $obj = self::parse($id); |
446 | $obj = self::parse($id); |
447 | if (!$obj) continue; |
447 | if (!$obj) continue; |
448 | $out[] = $obj; |
448 | $out[] = $obj; |
449 | } |
449 | } |
450 | } |
450 | } |
451 | } |
451 | } |
452 | return $out; |
452 | return $out; |
453 | } |
453 | } |
454 | 454 | ||
455 | /** |
455 | /** |
456 | * @return OIDplusRA|null |
456 | * @return OIDplusRA|null |
457 | * @throws OIDplusException |
457 | * @throws OIDplusException |
458 | */ |
458 | */ |
459 | public function getRa()/*: ?OIDplusRA*/ { |
459 | public function getRa()/*: ?OIDplusRA*/ { |
460 | $ra = $this->getRaMail(); |
460 | $ra = $this->getRaMail(); |
461 | return $ra ? new OIDplusRA($ra) : null; |
461 | return $ra ? new OIDplusRA($ra) : null; |
462 | } |
462 | } |
463 | 463 | ||
464 | /** |
464 | /** |
465 | * @param OIDplusRA|string|null $ra |
465 | * @param OIDplusRA|string|null $ra |
466 | * @return bool |
466 | * @return bool |
467 | * @throws OIDplusConfigInitializationException |
467 | * @throws OIDplusConfigInitializationException |
468 | * @throws OIDplusException |
468 | * @throws OIDplusException |
469 | */ |
469 | */ |
470 | public function userHasReadRights($ra=null): bool { |
470 | public function userHasReadRights($ra=null): bool { |
471 | if ($ra instanceof OIDplusRA) $ra = $ra->raEmail(); |
471 | if ($ra instanceof OIDplusRA) $ra = $ra->raEmail(); |
472 | 472 | ||
473 | // If it is not confidential, everybody can read/see it. |
473 | // If it is not confidential, everybody can read/see it. |
474 | // Note: This also checks if superior OIDs are confidential. |
474 | // Note: This also checks if superior OIDs are confidential. |
475 | if (!$this->isConfidential()) return true; |
475 | if (!$this->isConfidential()) return true; |
476 | 476 | ||
477 | if (!$ra) { |
477 | if (!$ra) { |
478 | // Admin may do everything |
478 | // Admin may do everything |
479 | if (OIDplus::authUtils()->isAdminLoggedIn()) return true; |
479 | if (OIDplus::authUtils()->isAdminLoggedIn()) return true; |
480 | 480 | ||
481 | // If the RA is logged in, then they can see the OID. |
481 | // If the RA is logged in, then they can see the OID. |
482 | $ownRa = $this->getRaMail(); |
482 | $ownRa = $this->getRaMail(); |
483 | if ($ownRa && OIDplus::authUtils()->isRaLoggedIn($ownRa)) return true; |
483 | if ($ownRa && OIDplus::authUtils()->isRaLoggedIn($ownRa)) return true; |
484 | } else { |
484 | } else { |
485 | // If this OID belongs to the requested RA, then they may see it. |
485 | // If this OID belongs to the requested RA, then they may see it. |
486 | if ($this->getRaMail() == $ra) return true; |
486 | if ($this->getRaMail() == $ra) return true; |
487 | } |
487 | } |
488 | 488 | ||
489 | // If someone has rights to an object below our confidential node, |
489 | // If someone has rights to an object below our confidential node, |
490 | // we let him see the confidential node, |
490 | // we let him see the confidential node, |
491 | // Otherwise he could not browse through to his own node. |
491 | // Otherwise he could not browse through to his own node. |
492 | $roots = $this->getRaRoots($ra); |
492 | $roots = $this->getRaRoots($ra); |
493 | foreach ($roots as $root) { |
493 | foreach ($roots as $root) { |
494 | if ($root->isChildOf($this)) return true; |
494 | if ($root->isChildOf($this)) return true; |
495 | } |
495 | } |
496 | 496 | ||
497 | return false; |
497 | return false; |
498 | } |
498 | } |
499 | 499 | ||
500 | /** |
500 | /** |
501 | * @param array|null $row |
501 | * @param array|null $row |
502 | * @return string|null |
502 | * @return string|null |
503 | * @throws OIDplusException |
503 | * @throws OIDplusException |
504 | */ |
504 | */ |
505 | public function getIcon(array $row=null) { |
505 | public function getIcon(array $row=null) { |
506 | $namespace = $this->ns(); // must use $this, not self::, otherwise the virtual method will not be called |
506 | $namespace = $this->ns(); // must use $this, not self::, otherwise the virtual method will not be called |
507 | 507 | ||
508 | if (is_null($row)) { |
508 | if (is_null($row)) { |
509 | $ra_email = $this->getRaMail(); |
509 | $ra_email = $this->getRaMail(); |
510 | } else { |
510 | } else { |
511 | $ra_email = $row['ra_email']; |
511 | $ra_email = $row['ra_email']; |
512 | } |
512 | } |
513 | 513 | ||
514 | // $dirs = glob(OIDplus::localpath().'plugins/'.'*'.'/objectTypes/'.$namespace.'/'); |
514 | // $dirs = glob(OIDplus::localpath().'plugins/'.'*'.'/objectTypes/'.$namespace.'/'); |
515 | // if (count($dirs) == 0) return null; // default icon (folder) |
515 | // if (count($dirs) == 0) return null; // default icon (folder) |
516 | // $dir = substr($dirs[0], strlen(OIDplus::localpath())); |
516 | // $dir = substr($dirs[0], strlen(OIDplus::localpath())); |
517 | $reflection = new \ReflectionClass($this); |
517 | $reflection = new \ReflectionClass($this); |
518 | $dir = dirname($reflection->getFilename()); |
518 | $dir = dirname($reflection->getFilename()); |
519 | $dir = substr($dir, strlen(OIDplus::localpath())); |
519 | $dir = substr($dir, strlen(OIDplus::localpath())); |
520 | $dir = str_replace('\\', '/', $dir); |
520 | $dir = str_replace('\\', '/', $dir); |
521 | 521 | ||
522 | if ($this->isRoot()) { |
522 | if ($this->isRoot()) { |
523 | $icon = $dir . '/' . $this::treeIconFilename('root'); |
523 | $icon = $dir . '/' . $this::treeIconFilename('root'); |
524 | } else { |
524 | } else { |
525 | // We use $this:: instead of self:: , because we want to call the overridden methods |
525 | // We use $this:: instead of self:: , because we want to call the overridden methods |
526 | if ($ra_email && OIDplus::authUtils()->isRaLoggedIn($ra_email)) { |
526 | if ($ra_email && OIDplus::authUtils()->isRaLoggedIn($ra_email)) { |
527 | if ($this->isLeafNode()) { |
527 | if ($this->isLeafNode()) { |
528 | $icon = $dir . '/' . $this::treeIconFilename('own_leaf'); |
528 | $icon = $dir . '/' . $this::treeIconFilename('own_leaf'); |
529 | if (!file_exists($icon)) $icon = $dir . '/' . $this::treeIconFilename('own'); |
529 | if (!file_exists($icon)) $icon = $dir . '/' . $this::treeIconFilename('own'); |
530 | } else { |
530 | } else { |
531 | $icon = $dir . '/' . $this::treeIconFilename('own'); |
531 | $icon = $dir . '/' . $this::treeIconFilename('own'); |
532 | } |
532 | } |
533 | } else { |
533 | } else { |
534 | if ($this->isLeafNode()) { |
534 | if ($this->isLeafNode()) { |
535 | $icon = $dir . '/' . $this::treeIconFilename('general_leaf'); |
535 | $icon = $dir . '/' . $this::treeIconFilename('general_leaf'); |
536 | if (!file_exists($icon)) $icon = $dir . '/' . $this::treeIconFilename('general'); |
536 | if (!file_exists($icon)) $icon = $dir . '/' . $this::treeIconFilename('general'); |
537 | } else { |
537 | } else { |
538 | $icon = $dir . '/' . $this::treeIconFilename('general'); |
538 | $icon = $dir . '/' . $this::treeIconFilename('general'); |
539 | } |
539 | } |
540 | } |
540 | } |
541 | } |
541 | } |
542 | 542 | ||
543 | if (!file_exists($icon)) return null; // default icon (folder) |
543 | if (!file_exists($icon)) return null; // default icon (folder) |
544 | 544 | ||
545 | return $icon; |
545 | return $icon; |
546 | } |
546 | } |
547 | 547 | ||
548 | /** |
548 | /** |
549 | * @param string $id |
549 | * @param string $id |
550 | * @return bool |
550 | * @return bool |
551 | * @throws OIDplusException |
551 | * @throws OIDplusException |
552 | */ |
552 | */ |
553 | public static function exists(string $id): bool { |
553 | public static function exists(string $id): bool { |
554 | if (!OIDplus::baseConfig()->getValue('OBJECT_CACHING', true)) { |
554 | if (!OIDplus::baseConfig()->getValue('OBJECT_CACHING', true)) { |
555 | $res = OIDplus::db()->query("select id from ###objects where id = ?", array($id)); |
555 | $res = OIDplus::db()->query("select id from ###objects where id = ?", array($id)); |
556 | return $res->any(); |
556 | return $res->any(); |
557 | } else { |
557 | } else { |
558 | self::buildObjectInformationCache(); |
558 | self::buildObjectInformationCache(); |
559 | return isset(self::$object_info_cache[$id]); |
559 | return isset(self::$object_info_cache[$id]); |
560 | } |
560 | } |
561 | } |
561 | } |
562 | 562 | ||
563 | /** |
563 | /** |
564 | * Get parent gives the next possible parent which is EXISTING in OIDplus |
564 | * Get parent gives the next possible parent which is EXISTING in OIDplus |
565 | * It does not give the immediate parent |
565 | * It does not give the immediate parent |
566 | * @return OIDplusObject|null |
566 | * @return OIDplusObject|null |
567 | * @throws OIDplusException |
567 | * @throws OIDplusException |
568 | */ |
568 | */ |
569 | public function getParent()/*: ?OIDplusObject*/ { |
569 | public function getParent()/*: ?OIDplusObject*/ { |
570 | if (!OIDplus::baseConfig()->getValue('OBJECT_CACHING', true)) { |
570 | if (!OIDplus::baseConfig()->getValue('OBJECT_CACHING', true)) { |
571 | $res = OIDplus::db()->query("select parent from ###objects where id = ?", array($this->nodeId())); |
571 | $res = OIDplus::db()->query("select parent from ###objects where id = ?", array($this->nodeId())); |
572 | if ($res->any()) { |
572 | if ($res->any()) { |
573 | $row = $res->fetch_array(); |
573 | $row = $res->fetch_array(); |
574 | $parent = $row['parent']; |
574 | $parent = $row['parent']; |
575 | $obj = OIDplusObject::parse($parent); |
575 | $obj = OIDplusObject::parse($parent); |
576 | if ($obj) return $obj; |
576 | if ($obj) return $obj; |
577 | } |
577 | } |
578 | } else { |
578 | } else { |
579 | self::buildObjectInformationCache(); |
579 | self::buildObjectInformationCache(); |
580 | if (isset(self::$object_info_cache[$this->nodeId()])) { |
580 | if (isset(self::$object_info_cache[$this->nodeId()])) { |
581 | $parent = self::$object_info_cache[$this->nodeId()][self::CACHE_PARENT]; |
581 | $parent = self::$object_info_cache[$this->nodeId()][self::CACHE_PARENT]; |
582 | $obj = OIDplusObject::parse($parent); |
582 | $obj = OIDplusObject::parse($parent); |
583 | if ($obj) return $obj; |
583 | if ($obj) return $obj; |
584 | } |
584 | } |
585 | } |
585 | } |
586 | 586 | ||
587 | // 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() |
587 | // 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() |
588 | $cur = $this->one_up(); |
588 | $cur = $this->one_up(); |
589 | if (!$cur) return null; |
589 | if (!$cur) return null; |
590 | do { |
590 | do { |
591 | // findFitting() checks if that OID exists |
591 | // findFitting() checks if that OID exists |
592 | if ($fitting = self::findFitting($cur->nodeId())) return $fitting; |
592 | if ($fitting = self::findFitting($cur->nodeId())) return $fitting; |
593 | 593 | ||
594 | $prev = $cur; |
594 | $prev = $cur; |
595 | $cur = $cur->one_up(); |
595 | $cur = $cur->one_up(); |
596 | if (!$cur) return null; |
596 | if (!$cur) return null; |
597 | } while ($prev->nodeId() !== $cur->nodeId()); |
597 | } while ($prev->nodeId() !== $cur->nodeId()); |
598 | 598 | ||
599 | return null; |
599 | return null; |
600 | } |
600 | } |
601 | 601 | ||
602 | /** |
602 | /** |
603 | * @return string|null |
603 | * @return string|null |
604 | * @throws OIDplusException |
604 | * @throws OIDplusException |
605 | */ |
605 | */ |
606 | public function getRaMail() { |
606 | public function getRaMail() { |
607 | if (!OIDplus::baseConfig()->getValue('OBJECT_CACHING', true)) { |
607 | if (!OIDplus::baseConfig()->getValue('OBJECT_CACHING', true)) { |
608 | $res = OIDplus::db()->query("select ra_email from ###objects where id = ?", array($this->nodeId())); |
608 | $res = OIDplus::db()->query("select ra_email from ###objects where id = ?", array($this->nodeId())); |
609 | if (!$res->any()) return null; |
609 | if (!$res->any()) return null; |
610 | $row = $res->fetch_array(); |
610 | $row = $res->fetch_array(); |
611 | return $row['ra_email']; |
611 | return $row['ra_email']; |
612 | } else { |
612 | } else { |
613 | self::buildObjectInformationCache(); |
613 | self::buildObjectInformationCache(); |
614 | if (isset(self::$object_info_cache[$this->nodeId()])) { |
614 | if (isset(self::$object_info_cache[$this->nodeId()])) { |
615 | return self::$object_info_cache[$this->nodeId()][self::CACHE_RA_EMAIL]; |
615 | return self::$object_info_cache[$this->nodeId()][self::CACHE_RA_EMAIL]; |
616 | } |
616 | } |
617 | return null; |
617 | return null; |
618 | } |
618 | } |
619 | } |
619 | } |
620 | 620 | ||
621 | /** |
621 | /** |
622 | * @return string|null |
622 | * @return string|null |
623 | * @throws OIDplusException |
623 | * @throws OIDplusException |
624 | */ |
624 | */ |
625 | public function getTitle() { |
625 | public function getTitle() { |
626 | if (!OIDplus::baseConfig()->getValue('OBJECT_CACHING', true)) { |
626 | if (!OIDplus::baseConfig()->getValue('OBJECT_CACHING', true)) { |
627 | $res = OIDplus::db()->query("select title from ###objects where id = ?", array($this->nodeId())); |
627 | $res = OIDplus::db()->query("select title from ###objects where id = ?", array($this->nodeId())); |
628 | if (!$res->any()) return null; |
628 | if (!$res->any()) return null; |
629 | $row = $res->fetch_array(); |
629 | $row = $res->fetch_array(); |
630 | return $row['title']; |
630 | return $row['title']; |
631 | } else { |
631 | } else { |
632 | self::buildObjectInformationCache(); |
632 | self::buildObjectInformationCache(); |
633 | if (isset(self::$object_info_cache[$this->nodeId()])) { |
633 | if (isset(self::$object_info_cache[$this->nodeId()])) { |
634 | return self::$object_info_cache[$this->nodeId()][self::CACHE_TITLE]; |
634 | return self::$object_info_cache[$this->nodeId()][self::CACHE_TITLE]; |
635 | } |
635 | } |
636 | return null; |
636 | return null; |
637 | } |
637 | } |
638 | } |
638 | } |
639 | 639 | ||
640 | /** |
640 | /** |
641 | * @return string|null |
641 | * @return string|null |
642 | * @throws OIDplusException |
642 | * @throws OIDplusException |
643 | */ |
643 | */ |
644 | public function getDescription() { |
644 | public function getDescription() { |
645 | if (!OIDplus::baseConfig()->getValue('OBJECT_CACHING', true)) { |
645 | if (!OIDplus::baseConfig()->getValue('OBJECT_CACHING', true)) { |
646 | $res = OIDplus::db()->query("select description from ###objects where id = ?", array($this->nodeId())); |
646 | $res = OIDplus::db()->query("select description from ###objects where id = ?", array($this->nodeId())); |
647 | if (!$res->any()) return null; |
647 | if (!$res->any()) return null; |
648 | $row = $res->fetch_array(); |
648 | $row = $res->fetch_array(); |
649 | return $row['description']; |
649 | return $row['description']; |
650 | } else { |
650 | } else { |
651 | self::buildObjectInformationCache(); |
651 | self::buildObjectInformationCache(); |
652 | if (isset(self::$object_info_cache[$this->nodeId()])) { |
652 | if (isset(self::$object_info_cache[$this->nodeId()])) { |
653 | return self::$object_info_cache[$this->nodeId()][self::CACHE_DESCRIPTION]; |
653 | return self::$object_info_cache[$this->nodeId()][self::CACHE_DESCRIPTION]; |
654 | } |
654 | } |
655 | return null; |
655 | return null; |
656 | } |
656 | } |
657 | } |
657 | } |
658 | 658 | ||
659 | /** |
659 | /** |
660 | * @return string|null |
660 | * @return string|null |
661 | * @throws OIDplusException |
661 | * @throws OIDplusException |
662 | */ |
662 | */ |
663 | public function getComment() { |
663 | public function getComment() { |
664 | if (!OIDplus::baseConfig()->getValue('OBJECT_CACHING', true)) { |
664 | if (!OIDplus::baseConfig()->getValue('OBJECT_CACHING', true)) { |
665 | $res = OIDplus::db()->query("select comment from ###objects where id = ?", array($this->nodeId())); |
665 | $res = OIDplus::db()->query("select comment from ###objects where id = ?", array($this->nodeId())); |
666 | if (!$res->any()) return null; |
666 | if (!$res->any()) return null; |
667 | $row = $res->fetch_array(); |
667 | $row = $res->fetch_array(); |
668 | return $row['comment']; |
668 | return $row['comment']; |
669 | } else { |
669 | } else { |
670 | self::buildObjectInformationCache(); |
670 | self::buildObjectInformationCache(); |
671 | if (isset(self::$object_info_cache[$this->nodeId()])) { |
671 | if (isset(self::$object_info_cache[$this->nodeId()])) { |
672 | return self::$object_info_cache[$this->nodeId()][self::CACHE_COMMENT]; |
672 | return self::$object_info_cache[$this->nodeId()][self::CACHE_COMMENT]; |
673 | } |
673 | } |
674 | return null; |
674 | return null; |
675 | } |
675 | } |
676 | } |
676 | } |
677 | 677 | ||
678 | /** |
678 | /** |
679 | * @return string|null |
679 | * @return string|null |
680 | * @throws OIDplusException |
680 | * @throws OIDplusException |
681 | */ |
681 | */ |
682 | public function getCreatedTime() { |
682 | public function getCreatedTime() { |
683 | if (!OIDplus::baseConfig()->getValue('OBJECT_CACHING', true)) { |
683 | if (!OIDplus::baseConfig()->getValue('OBJECT_CACHING', true)) { |
684 | $res = OIDplus::db()->query("select created from ###objects where id = ?", array($this->nodeId())); |
684 | $res = OIDplus::db()->query("select created from ###objects where id = ?", array($this->nodeId())); |
685 | if (!$res->any()) return null; |
685 | if (!$res->any()) return null; |
686 | $row = $res->fetch_array(); |
686 | $row = $res->fetch_array(); |
687 | return $row['created']; |
687 | return $row['created']; |
688 | } else { |
688 | } else { |
689 | self::buildObjectInformationCache(); |
689 | self::buildObjectInformationCache(); |
690 | if (isset(self::$object_info_cache[$this->nodeId()])) { |
690 | if (isset(self::$object_info_cache[$this->nodeId()])) { |
691 | return self::$object_info_cache[$this->nodeId()][self::CACHE_CREATED]; |
691 | return self::$object_info_cache[$this->nodeId()][self::CACHE_CREATED]; |
692 | } |
692 | } |
693 | return null; |
693 | return null; |
694 | } |
694 | } |
695 | } |
695 | } |
696 | 696 | ||
697 | /** |
697 | /** |
698 | * @return string|null |
698 | * @return string|null |
699 | * @throws OIDplusException |
699 | * @throws OIDplusException |
700 | */ |
700 | */ |
701 | public function getUpdatedTime() { |
701 | public function getUpdatedTime() { |
702 | if (!OIDplus::baseConfig()->getValue('OBJECT_CACHING', true)) { |
702 | if (!OIDplus::baseConfig()->getValue('OBJECT_CACHING', true)) { |
703 | $res = OIDplus::db()->query("select updated from ###objects where id = ?", array($this->nodeId())); |
703 | $res = OIDplus::db()->query("select updated from ###objects where id = ?", array($this->nodeId())); |
704 | if (!$res->any()) return null; |
704 | if (!$res->any()) return null; |
705 | $row = $res->fetch_array(); |
705 | $row = $res->fetch_array(); |
706 | return $row['updated']; |
706 | return $row['updated']; |
707 | } else { |
707 | } else { |
708 | self::buildObjectInformationCache(); |
708 | self::buildObjectInformationCache(); |
709 | if (isset(self::$object_info_cache[$this->nodeId()])) { |
709 | if (isset(self::$object_info_cache[$this->nodeId()])) { |
710 | return self::$object_info_cache[$this->nodeId()][self::CACHE_UPDATED]; |
710 | return self::$object_info_cache[$this->nodeId()][self::CACHE_UPDATED]; |
711 | } |
711 | } |
712 | return null; |
712 | return null; |
713 | } |
713 | } |
714 | } |
714 | } |
715 | 715 | ||
716 | /** |
716 | /** |
717 | * @param OIDplusRA|string|null $ra |
717 | * @param OIDplusRA|string|null $ra |
718 | * @return bool |
718 | * @return bool |
719 | * @throws OIDplusException |
719 | * @throws OIDplusException |
720 | */ |
720 | */ |
721 | public function userHasParentalWriteRights($ra=null): bool { |
721 | public function userHasParentalWriteRights($ra=null): bool { |
722 | if ($ra instanceof OIDplusRA) $ra = $ra->raEmail(); |
722 | if ($ra instanceof OIDplusRA) $ra = $ra->raEmail(); |
723 | 723 | ||
724 | if (!$ra) { |
724 | if (!$ra) { |
725 | if (OIDplus::authUtils()->isAdminLoggedIn()) return true; |
725 | if (OIDplus::authUtils()->isAdminLoggedIn()) return true; |
726 | } |
726 | } |
727 | 727 | ||
728 | $objParent = $this->getParent(); |
728 | $objParent = $this->getParent(); |
729 | if (!$objParent) return false; |
729 | if (!$objParent) return false; |
730 | return $objParent->userHasWriteRights($ra); |
730 | return $objParent->userHasWriteRights($ra); |
731 | } |
731 | } |
732 | 732 | ||
733 | /** |
733 | /** |
734 | * @param OIDplusRA|string|null $ra |
734 | * @param OIDplusRA|string|null $ra |
735 | * @return bool |
735 | * @return bool |
736 | * @throws OIDplusException |
736 | * @throws OIDplusException |
737 | */ |
737 | */ |
738 | public function userHasWriteRights($ra=null): bool { |
738 | public function userHasWriteRights($ra=null): bool { |
739 | if ($ra instanceof OIDplusRA) $ra = $ra->raEmail(); |
739 | if ($ra instanceof OIDplusRA) $ra = $ra->raEmail(); |
740 | 740 | ||
741 | if (!$ra) { |
741 | if (!$ra) { |
742 | if (OIDplus::authUtils()->isAdminLoggedIn()) return true; |
742 | if (OIDplus::authUtils()->isAdminLoggedIn()) return true; |
743 | // TODO: should we allow that the parent RA also may update title/description about this OID (since they delegated it?) |
743 | // TODO: should we allow that the parent RA also may update title/description about this OID (since they delegated it?) |
744 | $ownRa = $this->getRaMail(); |
744 | $ownRa = $this->getRaMail(); |
745 | return $ownRa && OIDplus::authUtils()->isRaLoggedIn($ownRa); |
745 | return $ownRa && OIDplus::authUtils()->isRaLoggedIn($ownRa); |
746 | } else { |
746 | } else { |
747 | return $this->getRaMail() == $ra; |
747 | return $this->getRaMail() == $ra; |
748 | } |
748 | } |
749 | } |
749 | } |
750 | 750 | ||
751 | /** |
751 | /** |
752 | * @param string|OIDplusObject $to |
752 | * @param string|OIDplusObject $to |
753 | * @return int|null |
753 | * @return int|null |
754 | */ |
754 | */ |
755 | public function distance($to)/*: ?int*/ { |
755 | public function distance($to)/*: ?int*/ { |
756 | return null; // not implemented |
756 | return null; // not implemented |
757 | } |
757 | } |
758 | 758 | ||
759 | /** |
759 | /** |
760 | * @param OIDplusObject|string $obj |
760 | * @param OIDplusObject|string $obj |
761 | * @return bool |
761 | * @return bool |
762 | */ |
762 | */ |
763 | public function equals($obj): bool { |
763 | public function equals($obj): bool { |
764 | if (!$obj) return false; |
764 | if (!$obj) return false; |
- | 765 | if (!is_object($obj)) { |
|
- | 766 | if ($this->nodeId(true) === $obj) return true; // simplest case |
|
765 | if (!is_object($obj)) $obj = OIDplusObject::parse($obj); |
767 | $obj = OIDplusObject::parse($obj); |
766 | if (!$obj) return false; |
768 | if (!$obj) return false; |
- | 769 | } else { |
|
- | 770 | if ($this->nodeId(true) === $obj->nodeId(true)) return true; // simplest case |
|
- | 771 | } |
|
767 | if (!($obj instanceof $this)) return false; |
772 | if (!($obj instanceof $this)) return false; |
768 | 773 | ||
769 | $distance = $this->distance($obj); |
774 | $distance = $this->distance($obj); |
770 | if (is_numeric($distance)) return $distance === 0; // if the distance function is implemented, use it |
775 | if (is_numeric($distance)) return $distance === 0; // if the distance function is implemented, use it |
771 | 776 | ||
772 | return $this->nodeId() == $obj->nodeId(); // otherwise compare the node id case-sensitive |
777 | return $this->nodeId() == $obj->nodeId(); // otherwise compare the node id case-sensitive |
773 | } |
778 | } |
774 | 779 | ||
775 | /** |
780 | /** |
776 | * @param string $search_id |
781 | * @param string $search_id |
777 | * @return OIDplusObject|false |
782 | * @return OIDplusObject|false |
778 | * @throws OIDplusException |
783 | * @throws OIDplusException |
779 | */ |
784 | */ |
780 | public static function findFitting(string $search_id) { |
785 | public static function findFitting(string $search_id) { |
781 | $obj = OIDplusObject::parse($search_id); |
786 | $obj = OIDplusObject::parse($search_id); |
782 | if (!$obj) return false; // e.g. if ObjectType plugin is disabled |
787 | if (!$obj) return false; // e.g. if ObjectType plugin is disabled |
783 | 788 | ||
- | 789 | if ($obj->nodeId(false) == '') return false; // speed optimization. "oid:" is not equal to any object in the database |
|
- | 790 | ||
784 | if (!OIDplus::baseConfig()->getValue('OBJECT_CACHING', true)) { |
791 | if (!OIDplus::baseConfig()->getValue('OBJECT_CACHING', true)) { |
785 | $res = OIDplus::db()->query("select id from ###objects where id like ?", array($obj->ns().':%')); |
792 | $res = OIDplus::db()->query("select id from ###objects where id like ?", array($obj->ns().':%')); |
786 | while ($row = $res->fetch_object()) { |
793 | while ($row = $res->fetch_object()) { |
787 | $test = OIDplusObject::parse($row->id); |
794 | $test = OIDplusObject::parse($row->id); |
788 | if ($obj->equals($test)) return $test; |
795 | if ($test && $obj->equals($test)) return $test; |
789 | } |
796 | } |
790 | return false; |
797 | return false; |
791 | } else { |
798 | } else { |
792 | self::buildObjectInformationCache(); |
799 | self::buildObjectInformationCache(); |
793 | foreach (self::$object_info_cache as $id => $cacheitem) { |
800 | foreach (self::$object_info_cache as $id => $cacheitem) { |
794 | if (strpos($id, $obj->ns().':') === 0) { |
801 | if (strpos($id, $obj->ns().':') === 0) { |
795 | $test = OIDplusObject::parse($id); |
802 | $test = OIDplusObject::parse($id); |
796 | if ($obj->equals($test)) return $test; |
803 | if ($test && $obj->equals($test)) return $test; |
797 | } |
804 | } |
798 | } |
805 | } |
799 | return false; |
806 | return false; |
800 | } |
807 | } |
801 | } |
808 | } |
802 | 809 | ||
803 | /** |
810 | /** |
804 | * @return OIDplusObject|null |
811 | * @return OIDplusObject|null |
805 | */ |
812 | */ |
806 | public function one_up()/*: ?OIDplusObject*/ { |
813 | public function one_up()/*: ?OIDplusObject*/ { |
807 | return null; // not implemented |
814 | return null; // not implemented |
808 | } |
815 | } |
809 | 816 | ||
810 | // Caching stuff |
817 | // Caching stuff |
811 | 818 | ||
812 | protected static $object_info_cache = null; |
819 | protected static $object_info_cache = null; |
813 | 820 | ||
814 | /** |
821 | /** |
815 | * @return void |
822 | * @return void |
816 | */ |
823 | */ |
817 | public static function resetObjectInformationCache() { |
824 | public static function resetObjectInformationCache() { |
818 | self::$object_info_cache = null; |
825 | self::$object_info_cache = null; |
819 | } |
826 | } |
820 | 827 | ||
821 | const CACHE_ID = 'id'; |
828 | const CACHE_ID = 'id'; |
822 | const CACHE_PARENT = 'parent'; |
829 | const CACHE_PARENT = 'parent'; |
823 | const CACHE_TITLE = 'title'; |
830 | const CACHE_TITLE = 'title'; |
824 | const CACHE_DESCRIPTION = 'description'; |
831 | const CACHE_DESCRIPTION = 'description'; |
825 | const CACHE_RA_EMAIL = 'ra_email'; |
832 | const CACHE_RA_EMAIL = 'ra_email'; |
826 | const CACHE_CONFIDENTIAL = 'confidential'; |
833 | const CACHE_CONFIDENTIAL = 'confidential'; |
827 | const CACHE_CREATED = 'created'; |
834 | const CACHE_CREATED = 'created'; |
828 | const CACHE_UPDATED = 'updated'; |
835 | const CACHE_UPDATED = 'updated'; |
829 | const CACHE_COMMENT = 'comment'; |
836 | const CACHE_COMMENT = 'comment'; |
830 | 837 | ||
831 | /** |
838 | /** |
832 | * @return void |
839 | * @return void |
833 | * @throws OIDplusException |
840 | * @throws OIDplusException |
834 | */ |
841 | */ |
835 | private static function buildObjectInformationCache() { |
842 | private static function buildObjectInformationCache() { |
836 | if (is_null(self::$object_info_cache)) { |
843 | if (is_null(self::$object_info_cache)) { |
837 | self::$object_info_cache = array(); |
844 | self::$object_info_cache = array(); |
838 | $res = OIDplus::db()->query("select * from ###objects"); |
845 | $res = OIDplus::db()->query("select * from ###objects"); |
839 | while ($row = $res->fetch_array()) { |
846 | while ($row = $res->fetch_array()) { |
840 | self::$object_info_cache[$row['id']] = $row; |
847 | self::$object_info_cache[$row['id']] = $row; |
841 | } |
848 | } |
842 | } |
849 | } |
843 | } |
850 | } |
844 | 851 | ||
845 | /** |
852 | /** |
846 | * override this function if you want your object type to save |
853 | * override this function if you want your object type to save |
847 | * attachments in directories with easy names. |
854 | * attachments in directories with easy names. |
848 | * Take care that your custom directory name will not allow jailbreaks (../) ! |
855 | * Take care that your custom directory name will not allow jailbreaks (../) ! |
849 | * @return string |
856 | * @return string |
850 | * @throws OIDplusException |
857 | * @throws OIDplusException |
851 | */ |
858 | */ |
852 | public function getDirectoryName(): string { |
859 | public function getDirectoryName(): string { |
853 | if ($this->isRoot()) return $this->ns(); |
860 | if ($this->isRoot()) return $this->ns(); |
854 | return $this->getLegacyDirectoryName(); |
861 | return $this->getLegacyDirectoryName(); |
855 | } |
862 | } |
856 | 863 | ||
857 | /** |
864 | /** |
858 | * @return string |
865 | * @return string |
859 | * @throws OIDplusException |
866 | * @throws OIDplusException |
860 | */ |
867 | */ |
861 | public final function getLegacyDirectoryName(): string { |
868 | public final function getLegacyDirectoryName(): string { |
862 | if ($this::ns() == 'oid') { |
869 | if ($this::ns() == 'oid') { |
863 | $oid = $this->nodeId(false); |
870 | $oid = $this->nodeId(false); |
864 | } else { |
871 | } else { |
865 | $oid = null; |
872 | $oid = null; |
866 | $alt_ids = $this->getAltIds(); |
873 | $alt_ids = $this->getAltIds(); |
867 | foreach ($alt_ids as $alt_id) { |
874 | foreach ($alt_ids as $alt_id) { |
868 | if ($alt_id->getNamespace() == 'oid') { |
875 | if ($alt_id->getNamespace() == 'oid') { |
869 | $oid = $alt_id->getId(); |
876 | $oid = $alt_id->getId(); |
870 | break; // we prefer the first OID (for GUIDs, the first OID is the OIDplus-OID, and the second OID is the UUID OID) |
877 | break; // we prefer the first OID (for GUIDs, the first OID is the OIDplus-OID, and the second OID is the UUID OID) |
871 | } |
878 | } |
872 | } |
879 | } |
873 | } |
880 | } |
874 | 881 | ||
875 | if (!is_null($oid) && ($oid != '')) { |
882 | if (!is_null($oid) && ($oid != '')) { |
876 | // For OIDs, it is the OID, for other identifiers |
883 | // For OIDs, it is the OID, for other identifiers |
877 | // it it the OID alt ID (generated using the SystemID) |
884 | // it it the OID alt ID (generated using the SystemID) |
878 | return str_replace('.', '_', $oid); |
885 | return str_replace('.', '_', $oid); |
879 | } else { |
886 | } else { |
880 | // Can happen if you don't have a system ID (due to missing OpenSSL plugin) |
887 | // Can happen if you don't have a system ID (due to missing OpenSSL plugin) |
881 | return md5($this->nodeId(true)); // we don't use $id, because $this->nodeId(true) is possibly more canonical than $id |
888 | return md5($this->nodeId(true)); // we don't use $id, because $this->nodeId(true) is possibly more canonical than $id |
882 | } |
889 | } |
883 | } |
890 | } |
884 | 891 | ||
885 | /** |
892 | /** |
886 | * @param string $mode |
893 | * @param string $mode |
887 | * @return string |
894 | * @return string |
888 | */ |
895 | */ |
889 | public static function treeIconFilename(string $mode): string { |
896 | public static function treeIconFilename(string $mode): string { |
890 | // for backwards-compatibility with older plugins |
897 | // for backwards-compatibility with older plugins |
891 | return 'img/treeicon_'.$mode.'.png'; |
898 | return 'img/treeicon_'.$mode.'.png'; |
892 | } |
899 | } |
893 | 900 | ||
894 | } |
901 | } |
895 | 902 |