Subversion Repositories oidplus

Rev

Rev 20 | Rev 28 | 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
5
 * Copyright 2019 Daniel Marschall, ViaThinkSoft
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
 
20
abstract class OIDplusObject {
21
        public static $registeredObjectTypes = array();
22
 
23
        public static function parse($node_id) { // please overwrite this function!
24
                // TODO: in case we are not calling this class directly, check if function is overwritten and throw exception otherwise
25
                foreach (self::$registeredObjectTypes as $ot) {
26
                        if ($obj = $ot::parse($node_id)) return $obj;
27
                }
28
                return null;
29
        }
30
 
31
        public abstract static function objectTypeTitle();
32
 
33
        public abstract static function objectTypeTitleShort();
34
 
35
        public abstract static function ns();
36
 
37
        public abstract static function root();
38
 
39
        public abstract function isRoot();
40
 
41
        public abstract function nodeId();
42
 
43
        public abstract function addString($str);
44
 
45
        public abstract function crudShowId(OIDplusObject $parent);
46
 
47
        public abstract function crudInsertPrefix();
48
 
49
        public abstract function jsTreeNodeName(OIDplusObject $parent = null);
50
 
51
        public abstract function defaultTitle();
52
 
16 daniel-mar 53
        public abstract function isLeafNode();
54
 
2 daniel-mar 55
        public abstract function getContentPage(&$title, &$content);
56
 
27 daniel-mar 57
        public static function getRaRoots($ra_email=null) {
58
                $out = array();
59
                if (is_null($ra_email)) {
60
                        $res = OIDplus::db()->query("select oChild.id as id, oChild.ra_email as child_mail, oParent.ra_email as parent_mail from ".OIDPLUS_TABLENAME_PREFIX."objects as oChild ".
61
                                                    "left join ".OIDPLUS_TABLENAME_PREFIX."objects as oParent on oChild.parent = oParent.id ".
62
                                                    "order by ".OIDplus::db()->natOrder('oChild.id'));
63
                        while ($row = OIDplus::db()->fetch_array($res)) {
64
                                if (!OIDplus::authUtils()::isRaLoggedIn($row['parent_mail']) && OIDplus::authUtils()::isRaLoggedIn($row['child_mail'])) {
65
                                        $out[] = self::parse($row['id']);
66
                                }
2 daniel-mar 67
                        }
68
                } else {
27 daniel-mar 69
                        $res = OIDplus::db()->query("select oChild.id as id from ".OIDPLUS_TABLENAME_PREFIX."objects as oChild ".
70
                                                    "left join ".OIDPLUS_TABLENAME_PREFIX."objects as oParent on oChild.parent = oParent.id ".
71
                                                    "where ifnull(oParent.ra_email,'') <> '".OIDplus::db()->real_escape_string($ra_email)."' and oChild.ra_email = '".OIDplus::db()->real_escape_string($ra_email)."' ".
72
                                                    "order by ".OIDplus::db()->natOrder('oChild.id'));
73
                        while ($row = OIDplus::db()->fetch_array($res)) {
74
                                $out[] = self::parse($row['id']);
2 daniel-mar 75
                        }
76
                }
77
                return $out;
78
        }
79
 
80
        private static function getAllNonConfidential_rec($parent=null, &$out) {
81
                if (is_null($parent)) {
82
                        $roots = array();
83
                        foreach (self::$registeredObjectTypes as $ot) {
84
                                $roots[] = "parent = '" . OIDplus::db()->real_escape_string($ot::root()) . "'";
85
                        }
86
                        $roots = implode(' or ', $roots);
87
                } else {
88
                        $roots = "parent = '" . OIDplus::db()->real_escape_string($parent) . "'";
89
                }
90
 
91
                $res = OIDplus::db()->query("select id, confidential from ".OIDPLUS_TABLENAME_PREFIX."objects where $roots order by ".OIDplus::db()->natOrder('id'));
92
 
93
                while ($row = OIDplus::db()->fetch_array($res)) {
94
                        if ($row['confidential'] == '1') {
95
                                // do nothing
96
                        } else {
97
                                $out[] = $row['id'];
98
                                self::getAllNonConfidential_rec($row['id'], $out);
99
                        }
100
                }
101
        }
102
 
103
        public static function getAllNonConfidential() {
104
                $out = array();
105
                self::getAllNonConfidential_rec(null, $out);
106
                return $out;
107
        }
108
 
109
        public function isConfidential() {
110
                $curid = $this->nodeId();
111
                // Recursively search for the confidential flag in the parents
112
                while (OIDplus::db()->num_rows($res = OIDplus::db()->query("select parent, confidential from ".OIDPLUS_TABLENAME_PREFIX."objects where id = '".OIDplus::db()->real_escape_string($curid)."'")) > 0) {
113
                        $row = OIDplus::db()->fetch_array($res);
114
                        if ($row['confidential']) return true;
115
                        $curid = $row['parent'];
116
                }
117
 
118
                return false;
119
        }
120
 
121
        public function isChildOf(OIDplusObject $obj) {
122
                $curid = $this->nodeId();
123
                while (OIDplus::db()->num_rows($res = OIDplus::db()->query("select parent from ".OIDPLUS_TABLENAME_PREFIX."objects where id = '".OIDplus::db()->real_escape_string($curid)."'")) > 0) {
124
                        $row = OIDplus::db()->fetch_array($res);
125
                        if ($curid == $obj->nodeId()) return true;
126
                        $curid = $row['parent'];
127
                }
128
 
129
                return false;
130
        }
131
 
132
        public function userHasReadRights($ra_email=null) {
133
                // Admin may do everything
134
                if (OIDplus::authUtils()::isAdminLoggedIn()) return true;
135
 
136
                // If it is not confidential, everybody can read/see it.
137
                if (!$this->isConfidential()) return true;
138
 
139
                // If we own the object, we may see it
140
                if (is_null($ra_email)) {
141
                        if ($this->userHasWriteRights()) return true;
142
                } else {
143
                        $res = OIDplus::db()->query("select ra_email from ".OIDPLUS_TABLENAME_PREFIX."objects where id = '".OIDplus::db()->real_escape_string($this->nodeId())."'");
144
                        $row = OIDplus::db()->fetch_array($res);
145
                        if ($row['ra_email'] == $ra_email) return true;
146
                }
147
 
148
                // If someone has rights to an object below our confidential node,
149
                // we let him see the confidential node,
150
                // Otherwise he could not browse through to his own node.
151
                $roots = $this->getRaRoots($ra_email);
152
                foreach ($roots as $root) {
153
                        if ($root->isChildOf($this)) return true;
154
                }
155
 
156
                return false;
157
        }
158
 
159
        public function getIcon($row=null) {
20 daniel-mar 160
                $namespace = $this->ns(); // must use $this, not self::, otherwise the virtual method will not be called
2 daniel-mar 161
 
162
                if (is_null($row)) {
163
                        $res = OIDplus::db()->query("select ra_email from ".OIDPLUS_TABLENAME_PREFIX."objects where id = '".OIDplus::db()->real_escape_string($this->nodeId())."'");
164
                        $row = OIDplus::db()->fetch_array($res);
165
                }
166
                // TODO: have different icons for Leaf-Nodes
167
                if (OIDplus::authUtils()::isRaLoggedIn($row['ra_email'])) {
168
                        $icon = 'plugins/objectTypes/'.$namespace.'/img/treeicon_own.png';
169
                } else {
170
                        $icon = 'plugins/objectTypes/'.$namespace.'/img/treeicon_general.png';
171
                }
172
                if (!file_exists($icon)) $icon = null; // default icon (folder)
173
                return $icon;
174
        }
175
 
12 daniel-mar 176
        public static function exists($id) {
177
                $res = OIDplus::db()->query("select * from ".OIDPLUS_TABLENAME_PREFIX."objects where id = '".OIDplus::db()->real_escape_string($id)."'");
178
                return OIDplus::db()->num_rows($res) > 0;
179
        }
180
 
2 daniel-mar 181
        public function getParent() {
182
                $res = OIDplus::db()->query("select parent from ".OIDPLUS_TABLENAME_PREFIX."objects where id = '".OIDplus::db()->real_escape_string($this->nodeId())."'");
183
                $row = OIDplus::db()->fetch_array($res);
184
                $parent = $row['parent'];
20 daniel-mar 185
                $obj = OIDplusObject::parse($parent);
186
                if ($obj) return $obj;
187
 
27 daniel-mar 188
                // 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()
20 daniel-mar 189
                $cur = $this->one_up();
190
                if (!$cur) return false;
191
                do {
192
                        if ($fitting = self::findFitting($cur->nodeId())) return $fitting;
193
 
194
                        $prev = $cur;
195
                        $cur = $cur->one_up();
196
                        if (!$cur) return false;
197
                } while ($prev != $cur);
198
 
199
                return false;
2 daniel-mar 200
        }
201
 
202
        public function getRaMail() {
203
                $res = OIDplus::db()->query("select ra_email from ".OIDPLUS_TABLENAME_PREFIX."objects where id = '".OIDplus::db()->real_escape_string($this->nodeId())."'");
204
                $row = OIDplus::db()->fetch_array($res);
205
                return $row['ra_email'];
206
        }
207
 
208
        public function userHasParentalWriteRights($ra_email=null) {
209
                if (is_null($ra_email)) {
210
                        if (OIDplus::authUtils()::isAdminLoggedIn()) return true;
211
                }
212
 
213
                $objParent = $this->getParent();
214
                if (is_null($objParent)) return false;
215
                return $objParent->userHasWriteRights($ra_email);
216
        }
217
 
218
        public function userHasWriteRights($ra_email=null) {
219
                if (is_null($ra_email)) {
220
                        if (OIDplus::authUtils()::isAdminLoggedIn()) return true;
221
                        return OIDplus::authUtils()::isRaLoggedIn($this->getRaMail());
222
                } else {
223
                        return $this->getRaMail() == $ra_email;
224
                }
225
        }
12 daniel-mar 226
 
227
        public function distance($to) {
228
                return null; // not implemented
229
        }
20 daniel-mar 230
 
231
        public function equals($obj) {
232
                if (!is_object($obj)) $obj = OIDplusObject::parse($obj);
233
                $distance = $this->distance($obj);
234
                if (is_numeric($distance)) return $distance === 0; // if the distance function is implemented, use it
235
 
236
                return $this->nodeId() == $obj->nodeId(); // otherwise compare the node id case-sensitive
237
        }
238
 
239
        public static function findFitting($id) {
240
                $obj = OIDplusObject::parse($id);
241
                if (!$obj) throw new Exception("findFitting: Parse failed\n");
242
 
243
                $res = OIDplus::db()->query("select * from ".OIDPLUS_TABLENAME_PREFIX."objects where id like '".OIDplus::db()->real_escape_string($obj->ns()).":%'");
244
                while ($row = OIDplus::db()->fetch_object($res)) {
245
                        $test = OIDplusObject::parse($row->id);
246
                        if ($obj->equals($test)) return $test;
247
                }
248
                return false;
249
        }
250
 
251
        public function one_up() {
252
                return null; // not implemented
253
        }
2 daniel-mar 254
}